Airbnbは最近、スケーラブルな集中認証システムであるHimejiをどのように構築したかについて説明した。Himejiは、信頼できる唯一の情報源として、パーミッションデータを保存し、パーミッションチェックを実行する。シャーディングおよびレプリケートされたインメモリキャッシュを使って、パフォーマンスを向上させ、レイテンシを短縮し、本番環境で約1年間チェックを行ってきた。そのスループットは、99.999%の可用性と、99%に対して12ミリ秒の遅延を維持しながら、2020年3月の0から2021年3月の85万エンティティ/秒にスケールアップした。
下の画像はHimejiの3層アーキテクチャを表している。
まず、オーケストレーションレイヤーはクライアントからの要求を受信し、キャッシュからデータをフェッチする役割を持つ。シャーディングおよびレプリケートされるキャッシングレイヤーは、インメモリでのフィルタリングと、キャッシュミス時のデータベースからのロードを担当する。Airbnbは、キャッシュで最大98%のヒット率を目標としている。最後に、データレイヤーは永続的なデータベースストレージとしてAmazon Auroraを使用する。AirbnbのSpinalTapはデータの変異を検出し、Apache Kafkaを介して通知を送信してキャッシュを無効にする。
AirbnbのエンジニアであるAlan Yao氏が、このアーキテクチャに至った理由を説明している。
過去数年間で、AirbnbエンジニアリングはモノリシックなRuby on Railsアーキテクチャからサービス指向アーキテクチャに移行しました。Railsアーキテクチャでは、基盤となるデータにアクセスするためにリソースごとにAPIがありました。これらのAPIには、機密データを保護するための承認チェックがありました。リソースのデータにアクセスする方法は1つしかなかったため、これらのチェックの管理は簡単でした。 SOAへの移行では階層化アーキテクチャに移行し、データサービスがデータベースとプレゼンテーションサービスをラップし、複数のデータサービスにより機能するようになりました。
Yao氏によると、下の画像が示すように、Airbnbは最初にパーミッションチェックをプレゼンテーションサービスに移した。
この選択はいくつかの問題を引き起こした。まず、承認チェックが重複し、管理が困難になった。次に、各認証チェックは、必要なロジックを実行するために複数のサービスに広がる必要があり、パフォーマンスと信頼性が大幅に低下した。解決策は、承認チェックをプレゼンテーションサービスではなくデータサービスに移動することであった。そのためHimejiを開発し、それによってアクセスパーミッションデータを一元化されたスケーラブルな方法で保存できるようになった。下の図は、HimejiとそれがAirbnbシステムでどのように使用されているかを示している。
HimejiのチェックAPIを使用すると、データサービスで権限チェックを実行できる。データサービスは、特定のプリンシパル(ユーザなど)が特定のエンティティで関係(特権やアクションなど)を持っているかどうかをHimejiに尋ねることができる。たとえば、データサービスは、「ユーザ123はリスト10の説明に書き込むことができるか」と尋ねることができる。この構造はタプルと呼ばれる。これは、Googleのグローバル認証システムであるGoogle Zanzibar氏にインスパイアされている。
Himejiのパーミッションルールは、DBに保存することも、構成から派生させることもできる。たとえば、次の構成済みルールでは、プリンシパルがリストの所有者である場合(所有者は、DBに格納されているリストのパーミッションである)、プリンシパルがリストの場所を読み取ることができる。または、リストに関連する限定されたゲストが場所を読み取ることもできる。
LISTING:
LOCATION:
'#READ':
union:
- #OWNER
- LISTING : $id # RESERVATION @
Reference(RESERVATION : $reservationId # GUEST)
その結果、ゲストがリストの場所を読み取ろうとすると、データサービスは、そのユーザのプリンシパルに読み取り権限があるかどうかを確認する。上記のルールに基づき、Himejiは本人がリスティングの限定されたゲストであるかどうかを自動的に照会し、適切な結果を返す。
統合時間を短縮し、開発者の採用を促進するために、Airbnbはいくつかのツールを開発した。これらには、Apache AirflowとApache Sparkを使用して既存の権限データを移植するためのツールと、JavaおよびScalaコードを自動生成するためのスクリプトが含まれている。