Meta、ZippyDB向けプロキシ「ZGateway」実装、10億Ops超を処理

MetaがZippyDB向けに開発したプロキシ層ZGatewayが、毎秒10億オペレーションを処理し、スケーラビリティ問題を解決。

投稿者 central
Meta、ZippyDB
ハイライト
  • ZGatewayは毎秒10億オペレーシヨン超ええる処理を達成した。

Meta(旧Facebook)の中核となるキーバリューストア「ZippyDB」を支える新たなプロキシ層「ZGateway」が、同社の検証環境において1秒間に10億オペレーション(Ops)を超える処理を達成した。このプロキシは、クライアントアプリケーションとデータベース群の間に介在し、接続管理、バッチ処理、アドミッションコントロール、キャッシング、フェイルオーバーといった機能を統合。これにより、従来の直接接続方式が抱えていた深刻なスケーラビリティ問題を劇的に改善した。本稿では、Meta Engineeringブログで公開された詳細をもとに、ZGatewayのアーキテクチャとその技術的価値を深掘りする。

なぜZippyDBにプロキシが必要だったのか

ZippyDBはMeta全体で最も広く利用されるキーバリューストアであり、商品メタデータ、カウンター、設定情報などを保持し、1秒間に数百万から数十億のオペレーションを処理している。このデータベースへのアクセスは、従来、各クライアントアプリケーションが直接データベースホストに接続する方式が取られていた。この「直接接続」モデルが、大規模な運用において深刻なボトルネックを生み出していたのである。

問題の核心は接続の爆発的増加にあった。単一のクライアントがアクセスする必要のあるシャード数は数万にものぼり、それを支えるデータベースホストの数は数十万台に達する。その結果、クライアントとデータベースホストの両方で、それぞれ数万ものTLS接続が同時に維持されることになる。各アイドル接続はメモリ、CPU、ファイルディスクリプタを消費し、新たなクライアントが追加されるたびにインバウンド接続数は増加し続ける。最悪の場合、ルーティングバグにより全てのクライアントが全シャードに対して接続を張り直す「再接続ストーム」が発生し、ファイルディスクリプタの枯渇やメモリ不足(OOM)によるサーバーの再起動ループに陥るインシデントも報告されている。クライアントサイドの修正は、数百ものチームが管理するクライアント群全体に影響を及ぼすため、事実上不可能だった。

ZGatewayの全体像

ZGatewayは、ZippyDBクライアントとZServerデータベース群の間に位置するステートレスなプロキシ層である。その設計思想は「クライアントライブラリをマネージドサービスとして運用する」というものだ。エンジンとしてMetaのC++で書かれたZippyDBクライアントをそのまま内蔵しており、実質的にはプロキシを介したZippyDBアクセスのすべてがこの内部クライアントによって処理される。

ZGatewayは、Metaのサービスメッシュ「ServiceRouter」を通じてリージョナルな階層としてデプロイされる。提供される機能は、純粋なリクエスト転送を行う「プロキシ」と、読み取り応答をキャッシュする「リードスルーキャッシュ」の2種類だ。

クライアントは、スティッキーな接続を介してリージョン内のZGatewayホストにリクエストを送信する。ZGatewayは、TLSの終端、ACL(アクセス制御リスト)による認可、テナント単位のトラフィックシェーピング、シャードの解決(ルーティング)、ローカルキャッシュの確認、同一シャード宛のリクエストのバッチ処理、そして適切なレプリカへの転送を一貫して実行する。レスポンスはデマルチプレクスされ、テナントごとのメトリクスやトレース情報とともにクライアントに返される。

接続数の劇的な削減

ZGateway導入による最大の成果の一つは、接続数の大幅な削減である。Metaはこの効果を「N個のボールをM個の箱にランダムに投げ入れる」という確率モデルを用いて説明している。具体的なシミュレーションとして、20リージョン、50万台のデータベースホスト、3万台のプロキシホスト、100万台のクライアント、クライアントあたり5万シャードという構成を仮定した場合、ホストあたりの接続数は約97~98%削減され、システム全体の持続的接続数は約19分の1に減少する。

より重要な点は、この効果がクライアント数の増加に対して線形ではないことだ。直接接続方式では、データベースホストへのファンイン(輻輳)はクライアント数に比例して増加する。しかしZGatewayを経由する場合、ファンインは「リージョン数 × ホストあたりのシャード密度」にほぼ依存し、クライアントフリート全体の規模から独立する。これにより、Metaのようなハイパースケール環境でも接続管理が現実的な範囲に収まるようになった。

ZGatewayがもたらした新たな機能

接続問題の解決に加え、ZGatewayはプロキシ層に組み込まれたことで、ZippyDBの運用や信頼性を大幅に向上させる複数の機能を実現している。

安全なマイグレーションと段階的ロールアウト

設定フラグにより、サービス単位、シャードプレフィックス単位でトラフィックの割合を調整可能。パーセンテージランプ、リージョンフィルター、グローバルキルスイッチを備え、段階的なロールアウトと緊急停止を容易にしている。

差別化負荷制限(Discriminant Load Shedding)

リクエストをテナントごと、かつプライオリティごとのバケットにマッピングし、ラウンドロビンでドレインする仕組み。これにより、特定のテナントが過剰なトラフィックを送信しても、そのテナントのバケットだけが溢れてリクエストが棄却される。他のテナントには影響が及ばない。Metaのテストでは、CPU使用率が90%を超える高負荷状態で、約1,350のテナントバケットのうち6つだけが負荷を棄却し、残りのテナントは99.9%のリクエストをエラーなく処理。全体のグッドプットは97~98%を維持し、この機構にかかるCPUオーバーヘッドは約8%に抑えられた。

読み取りキャッシュ

キャッシュ層は、ホットな読み取りリクエストをプロセス内で処理する。キャッシュミス時にはキー単位でロックを取得してフェッチし、データの更新はCDC(Change Data Capture)イベントを利用して有限の古さ(bounded staleness)を保証する。

負荷分散

プロキシ層は26コアから126コアまで異なるスペックのホストが混在する。制御プレーン上のバランサーが、各ホストの最近のCPU負荷に応じてServiceRouterの重みを動的に調整し、処理能力に応じた負荷分散を実現する。

クロスリージョン耐障害性

グローバルルーティング、メガリージョン、リング構造により、あるリージョンのプロキシ層が飽和状態になった場合、近隣の健全なキャパシティにトラフィックをフェイルオーバーさせる。

トランザクション処理の統合

従来はクライアントサイドで行われていたトランザクションのブックキーピングを、ZGateway内に移行。9つのフェーズを経て、信頼性の低下なしに全トランザクショントラフィックをプロキシ経由で処理することに成功した。

ZGatewayから得られる教訓

ZGatewayは、Metaの極めて特殊なスケール要件に最適化されたシステムであり、そのまま外部環境にデプロイ可能な汎用ソフトウェアパッケージではない。しかし、その設計パターンは、大規模分散システムを運用するあらゆる組織にとって示唆に富む。特に、直接接続によるスケーラビリティの限界、ステートレスなプロキシ層による接続管理の集中化、そしてテナントを明示的に隔離したリソース管理の重要性は、クラウドネイティブなアーキテクチャ設計において普遍的な価値を持つ。

ZGatewayは、1秒間に10億を超えるオペレーションを約6%の計算オーバーヘッドで処理し、ZippyDBトラフィックの約40%を担い、将来的には60%を超えると予想されている。この数字は、単なる性能を示すだけでなく、Metaがいかにしてシステム全体の複雑性とリスクを管理しているかを物語っている。今後もMetaは、このプロキシ層を基盤に、さらなる機能拡張と性能最適化を進めていくことになるだろう。

この記事をシェア