はじめに
LDAP(Lightweight Directory Access Protocol)は、1993年に初めて標準化された、広く普及しているディレクトリ情報のソースです。Linuxインスタンスのユーザー/グループ情報の管理や、VPNやレガシーアプリケーションの認証の制御など、幅広い用途で一般的に使用されています。
従来、企業のLDAPサーバーは社内で運用されていました。多くの場合、MicrosoftのActive Directoryの一部、またはオープンソースのOpenLDAPプロジェクトの設定です。現在では、Foxpassを含むSaaSプロバイダーがLDAPサポートを提供しており、Foxpassはマルチテナント型でクラウド中心のLDAP実装をゼロから構築した最初のクラウドLDAPプロバイダーでした。
LDAP には通常、次の基本操作があります: bind、search、compare、および add。Transmission Control Protocol (TCP) 接続を作成した後、アプリケーションはまずユーザー名とパスワードを送信してbindする必要があります。バインドに成功すると、クライアントはLDAPサーバーにコマンドを発行します。通常、これはフィルターと組み合わせて使用する検索コマンドです。クライアントまたはサーバーのいずれかが切断するまで、TCP接続は維持されます。
FoxpassのLDAP
Foxpassでは、当社のLDAPサービスは、Python向けの一般的なイベントベースのサービスフレームワークであるTwisted上に構築されています。このサービスはAWSのECSプラットフォームでホストされ、数十のコンテナ(ノード)上で稼働しています。LDAP接続は持続的であるため、クラスターは数十万の同時TCPセッションを維持できなければなりません。
お客様のデータはRAM内に保持されます。その理由はいくつかあります。まず、大規模な顧客であっても、データセットが比較的小さいためです。次に、LDAPクエリ言語では任意のフィールドを検索できます(Foxpassではカスタムフィールドを使用できるため、これは重要です)。つまり、従来型のRDBMSシステムでは効果的なインデックスを構築できないため、データを別のインメモリ表現に変換する必要があります。第三に、データをRAMに保持することで、可能な限り最速の応答時間を実現できます。レイテンシは通常約100msです(グラフaを参照)。

このアプローチの欠点の1つは、キャッシュの無効化です。顧客のデータが変更された場合(たとえば、ユーザーが追加または削除された場合)、LDAPノードはメインのRDBMSからデータを更新する必要があります。以前のアーキテクチャでは、これは比較的コストの高い処理でした。各ノードが同じ企業のデータを更新すると、LDAPのレイテン シが目立って増加し、バックエンドストアの負荷も高くなる可能性があります。
遅延感度に関する課題
前述のとおり、レイテンシ要件のため、各コンテナは顧客のすべてのデータをメモリ内に保存します(図aを参照)。データは、リクエストがノードに到達した時点でオンデマンドに取得され(まだ存在しない場合)、その後は、その顧客からの接続が少なくとも1つ維持されている限り保持されます。
受信した接続リクエストは(ロードバランサー経由で)どのコンテナにも振り分けられる可能性があるため、クエリを受け付けたコンテナは、その顧客のすべてのデータも読み込み、保存します。その後、コンテナは無効化メッセージを受信するためにredis pubsubサービスに登録します。会社のデータが更新されると、受信ノードに無効化シグナルがブロードキャストされ、各ノードはその会社のデータのキャッシュをクリアし、データベースにアクセスして会社のデータを再取得します。
これにより、継続的に成長し、新しい顧客をシステムに追加していく中で、当社のLDAPサービスを拡張するうえで次のような課題が生じました。
すべてのノード(N)にまたがる顧客(M)のすべてのデータは、無効化時に再読み込みが必要です。実際には、すべてのノードがすべての顧客からの接続をホストしているわけではありませんが、最悪の場合、データを更新するためにデータベースに対して MxN 回の呼び出しが行われます。顧客がさらに追加されると(M)、DBフェッ チの回数はN倍に増加する可能性があります。これは、データベースマシンに過度な負荷をかけないようにするため、リクエストの急増に対応するには追加のDBリーダーインスタンスが必要になることも意味していました。
顧客全体(M)にまたがるすべてのデータは多数のノード(N)のメモリ上に保存されるため、すべてのノードのメモリ使用量は顧客数(M)に比例して増え続けます。これは、メモリ内のすべてのデータを収容できるようにコンテナに必要なメモリも増やす必要があることを意味し、その結果、インフラ全体のコストが増加します。
上記の課題は非常に明確で、すべてのノードで全データを複製するのではなく、顧客データをノード間に分散して配置する方向へと私たちを導きました。これにより、分散キャッシュ管理ソリューションの導入に至りました。

分散キャッシュ管理
当社のLDAPサービスにはインテリジェントなルーティングレイヤーを導入しており、接続先のコンテナに顧客データが存在しない場合、そのリクエストを顧客データをホストしているノードへ転送していました。これを実現するために、ルーティングレイヤーに求められる設計要件を次のように絞り込みました。
ノードが追加されるたびに、顧客を各ノードへ動的に分散する必要があります。
ノードの縮小・拡張やノード障害が発生した際に、顧客データを動的に分散する必要があります。
特定の顧客向けにパーティション数を増減できるため、トラフィ ックの偏りによって単一ノードに過負荷がかかるのを防げます。
インスタンス間でリソースを分散するApache Helixを導入しました。helixエコシステムの頭脳であるHelix controllerは、ノードや顧客が追加または削除された際に、ノード間でのリソース割り当てを決定します。Apache HelixのcontrollerとRest serverをコンテナ化し、ECSにデプロイしました。Helix controller は、クラスターの変更を監視するために Zookeeper に依存しています。ECS に Zookeeper を確実に設定する方法を実装したことで、Helix と Zookeeper のインフラ全体が ECS 上で稼働するようになりました。
すべてのLDAPノードは、クラスターへの参加を登録するために、Zookeeper とやり取りします。各LDAPインスタンスはHelixコントローラーによって管理される顧客からノードへの割り当てクラスターに参加する、Helixの参加者として起動します。LDAPノードによってその場で新しい顧客が作成されると、その顧客のパーティション数(各パーティションはデータをホストするノードを表します)が、ユーザー数に基づいて決定されます。
この統合により、当社のLDAPノードは、クラスター内で発生するイベント(つまり、新しい顧客が追加されたときや、利用可能なノードのセットが変更された とき)を認識できます。
このクラスター認識により、当社のLDAPサービスのルーティングレイヤーは、ノードと顧客の間のマッピングを提供します。すべての受信接続は今後、接続のルーティング先となるノードを判断するために、ルーティングレイヤーを経由するようになります。これにより、顧客のデータは特定のノードに割り当てられます(図bを参照)。

ルーティングレイヤーは、顧客とノードのルート情報を保持するキャッシュをホストしています。ルーティングレイヤーは、顧客とノードの割り当て変更を特定し、変更が検出されると即座に更新します。このようにして、各LDAPノードは、顧客とノード間の変更を発生した時点ですぐに把握できます。
上記のキャッシュ管理ソリューションにより、レイテンシ感度の課題のセクションで述べたスケーラビリティの課題に対応しました。
現在、顧客は各ノードに分散しています。各ノードは顧客の一部のみをホストし、pubsub invalidates を受信した際には、その一部の顧客データのみを取得する役割を担います。これによりDBへの読み取り回数が大幅に減り、大量のDB読み取りを処理するためにDBリーダーノードを追加する必要がなくなります。LDAPクラスターは現在、以前と比べてDBの読み取り回数が75%少なくなっています。
また、すべてのノード(N)で顧客(M)のデータをメモリ上に保存していないため、メモリ効率も向上しました。このアーキテクチャにより、インスタンスサイズを増やすことなく水平方向にスケールできます。各LDAPノードが消費するメモリは、以前 より40%少なくなりました。


現在の課題
上記の実装では、ノードが受け取るTCP接続数に偏りが生じることが課題の1つです。この分散の不均衡により、他のノードと比べて一部のノード(ホットノード)でCPU使用率が高くなります。ただし、ノード全体の平均CPU使用率は、以前と比べても変わらず同じままです。
謝辞
チームの皆さんに感謝します。Helix と Zookeeper クラスターのコンテナ化と構築を支援し、これらのクラスターのメトリクスを Datadog で可視化してくれた Bryan Bojorque に特別な感謝を表します。
セキュリティを強化
ネットワークは不正なユーザーから保護されていますか?Foxpassがコストのかかるセキュリティミスの回避にどのように役立つかについては、こちらをクリックしてください。




