このサイトのコンテンツは、人工知能(AI)または機械翻訳技術を使用して翻訳されており、誤りが含まれている場合があります。

Skip to content

RobloxがKafkaプラットフォームを拡張し、1日あたり18兆件以上のメッセージ処理を実現した方法

効率的なシステムのためのエンドツーエンド最適化

過去2年間で、社内メッセージキュープラットフォームを毎年2.5倍以上スケールアップさせ、1日あたり18兆件以上のメッセージを処理できるようになりました。 現在、99.995%の可用性を維持しつつ、1秒あたり3億件以上のメッセージを処理しています。Apache Kafkaを基盤として構築されたこのメッセージキュープラットフォームは、社内でデータをやり取りする上で不可欠な要素となっています。このプラットフォームは、分析イベント、モデレーションパイプライン、マッチメイキングシステムなど、さまざまなワークロードをサポートしています。これらの数字は確かに素晴らしいものですが、それ以上に重要なのは、私たちがどのようにしてこの成果を達成したかという点です。 

エンドツーエンドの最適化がもたらす影響 

大規模システムに関する一般的な誤解として、容量の問題は主にハードウェアの問題であるという考えがあります。しかし、私たちの経験上、スケーラビリティをエンドツーエンドのエンジニアリング課題として扱うことで、最も大きな改善効果が得られます。

Roblox全社の各チームは、メッセージングキューを基盤として、AIトレーニングパイプライン、ストリーム処理の抽象化、テレメトリシステムなど、さまざまなプラットフォームを構築してきました。これらのプラットフォームの責任者と連携することで、バッチ処理や圧縮の有効化といったベストプラクティスの順守を確実に支援できます。その結果、エンドユーザーが詳細な設定作業を行うことなく、効率的なシステムを実現できています。

当社のキューアーキテクチャおよび関連プラットフォームにより、他のチームは「車輪の再発明」をすることなく、また設定について心配することなく開発を行うことができます

ビジネス上の優先事項、測定基準、成功基準について、プラットフォームを利用する各チームと足並みを揃えることは極めて重要であり、チーム間の連携を促進する助けとなります。主要な指標はシステムの各レイヤーによって異なります。例えば、Kafkaサーバーを最適化して少ないマシン数で大量のデータを効率的に処理できるようにする一方で、エンドユーザーはエンドツーエンドのレイテンシをミリ秒単位まで短縮することや、バッチジョブがデータの書き込みを完了するまでの総時間を短縮することを重視する場合があります。 

すべてのトラフィックが同等というわけではない

私たちが学んだ重要な教訓の一つは、大規模なプラットフォームは、すべてのトラフィックを平等に扱わない方が信頼性が高まるということです。一部のワークロードは、非常に低いレイテンシとトラフィック急増時の強力な保護を必要とします。例えば、エンドツーエンドのレイテンシを10ミリ秒未満で動作させる当社のマッチメイキングシステムがそうです。 一方、トラフィック量は極めて多いものの、遅延に対する許容度が高いものもあります。例えば、当社の分析用イベント取り込みパイプラインは、エンドツーエンドのレイテンシが数秒あってもスムーズに実行できます。これらを同じように扱ってしまうと、特にピーク負荷時には、トラフィック量が最も多いものが、ビジネス上より重要なトラフィックを圧迫してしまう可能性があります。

この問題を解決するため、当社はユースケースの要件ごとにトラフィックをグループ化し、それぞれが適切にサポートされるようにしています。Kafkaにおけるエンドツーエンドのレイテンシとスループットのトレードオフは、新しいユースケースを設定する際の主要な考慮事項の一つです。これは、プロデューサーからサーバー、そしてコンシューマーに至るデータパス全体に当てはまります。それぞれの要素には、スループットまたはレイテンシのいずれかを最適化するために調整可能な設定があります。 クライアント側の設定は個々のユースケースに合わせて調整できますが、サーバー側の設定は柔軟性に欠けます。なぜなら、個別のユースケースごとに専用のクラスターを維持することは現実的ではないからです。 

スタックを下って、各クラスタが担当するユースケースに合わせて最適化するというこのアプローチを、ハードウェア層にも適用します。 

ハードウェアは依然として重要

当初、私たちはRAID10構成のHDDマシン上でKafkaを稼働させていました。トラフィック量が増加するにつれ、マシンのディスクI/O容量が、サーバーごとのKafkaスループットを制限する主要なボトルネックとなりました。この問題に対処するため、2つの最適化を行いました。まず、ブローカーを可能な限りSSDを使用するように変換し、ボトルネックをディスクI/O容量からネットワークスループットまたはディスク容量(導入したSSDのディスク容量は少なかったため)へと移行させました。 これにより、ディスクI/Oスループットは10倍に向上しました。また、残りのHDDについてもRAID10からRAID0への移行を開始しました。RAID0では書き込みごとに2つのディスクへの書き込みが必要だったのが1つで済むため、ディスクI/O容量はおよそ2倍になりました。 

その代償として、各メッセージのレプリカがブローカー1台につき2つのディスクではなく1つのディスクに書き込まれるため、RAID10からRAID0への移行には信頼性のリスクが伴う可能性があります。信頼性を維持するため、重要なユースケースを対象に、ACKの頻度やデータレプリケーションの強化(複数のリージョンへのレプリケーションを含む)に取り組みました。

各マシンのストレージとスループット能力を最大限に活用するには、追加の作業が必要でした。Kafkaがメッセージをバッファリングし、読み取りや直近のデータをメモリから提供できるように、メモリ割り当てとページキャッシュ管理の設定を最適化しました。これにより、履歴データの読み取りなど、必要な場合にのみディスクにアクセスし、貴重なIOPSを消費するようになっています。 

また、パフォーマンスベンチマークを実施してハードウェアの限界を把握し、ソフトウェアレベルでどのような制限を設定すべきかを判断しました。実際には、これはKafkaブローカーの読み取りおよび書き込みスロットルの設定を意味しますが、これらはクラスタが稼働しているハードウェアによって異なります。SSD搭載マシンはブローカーあたりのスループットが高く、一方、HDD搭載マシンは履歴データの長期保存を必要とするユースケースに適しています。 

信頼性の確保

キュープラットフォームはRobloxのインフラストラクチャにおける重要な構成要素であり、信頼性の維持は不可欠です。ローンチ前のテストや継続的な障害シナリオテスト(「ゲームデイ演習」とも呼ばれる)は、単一ホストの障害、ラックの障害、ネットワークの問題など、さまざまな障害モードに対して当社のインフラストラクチャが耐性を持っていることを検証する上で極めて重要な役割を果たしてきました。 当社の信頼性チームが開発した内部カオステストプラットフォームにより、さまざまな障害シナリオをシミュレートするプロセスが可能になり、効率化されました。これらのテストは、システムの改善点や退行を特定するのに役立ち、アラートを定期的に検証し、オペレーターがさまざまな問題(まれなケースであっても)に対処するための手順を確実に理解できるようにすることで、運用面の卓越性を構築しています。

また、依存するユースケースにおいてキュー機能を迅速に復旧できるフェイルオーバープロセスも設計・実装しました。個々のクラスターが完全に障害を起こした場合でも、十分な容量を持つ正常なクラスターへクライアントを切り替えることが可能です。十分な未使用容量を確保するため、スタンバイのKafkaクラスターを維持しています。これにより、稼働中のクラスター間でトラフィックを切り替える際の「ノイジー・ネイバー」問題のリスクを排除できます。

以下の図は、フェイルオーバーを実行するための大まかな手順を示しています。まず、オペレーターがフェイルオーバーの範囲を特定します。次に、自動化された一括操作により、スタンバイクラスター上にトピックとアクセス制御リスト(ACL)が作成されます。最後に、オペレーターがコントロールプレーンサービスの設定を更新します。クライアントはこの設定をポーリングして、再接続が必要かどうかを判断します。以下の図は、一般的なリアルタイムユースケースを想定したものです。 その他のユースケースやシナリオに対応するため、Mirror Maker 2 を使用したトピックミラーリングやデータバックフィルツールなど、追加の戦略やツールも用意されています。

Robloxでは、信頼性の重要な要素であるセキュリティに関して厳格な要件を設けています。通信中の暗号化(mTLS)、保存時の暗号化(暗号化ディスク)、データ保持期間の要件、KafkaプリンシパルおよびACLによる認証・認可といった標準的なセキュリティ機能を実装しています。また、セキュリティをさらに強化するため、ユーザーの認証情報を自動的にローテーションしています。

これに加え、OSのパッチ適用やラックの排水作業を迅速に行えるよう、コントロールプレーンにカスタム処理機能を構築しました。OSのパッチ適用中は、ディスク上のデータを保持することで、パッチが適用されたマシンがKafkaクラスターに再参加した後、迅速に正常な状態を取り戻せるようにしています。これにより、インフラが拡大し続けていても、30日以内に全インフラへのパッチ適用を完了させることができます。 Cruise Control などのツールを活用し、ラック単位でデータをレプリケートしています。これにより、データの可用性を損なうことなく、メンテナンスやネットワークパッチ適用のためにラック全体をオフラインにすることができます。

今後の展望

当社のキュープラットフォームの次の段階は、弾力性と分離性を継続的に向上させつつ、開発者にとってプラットフォームをさらにシンプルにすることです。プロデューサーおよびコンシューマープロキシ、ならびにフルマネージドコネクタを含む新しい抽象化機能に投資しています。これらのシステムにより、アプリケーションチームとインフラの複雑さがさらに切り離され、プラットフォームの大規模な導入と管理が容易になります。 例えば、コンシューマープロキシにより「競合コンシューマー」パターンが実現され、プラットフォームはより幅広いユースケースをサポートできるようになり、プロセッサのスケーリングとKafkaパーティションのスケーリングを分離できるようになります。これは、順序付けを必要とせず、エンドツーエンドの配信目標に縛られることなくプロセッサ数を一時的に増やすことでメリットが得られる、通知の大量バースト処理のようなユースケースにおいて有用です。

Kafkaのスケーリングとは、単にクラスタの数や規模を拡大することだけではありません。それは、Robloxが毎日10億人の人々を、前向きな姿勢と礼儀正しさをもってつなぐという旅を継続できるようにするための、エンジニアリングの規律、抽象化、運用モデルを構築することなのです。 

謝辞:Roblox キュー・プラットフォームに多大な貢献をしてくださった Danny Yuan 氏および George Li 氏に感謝いたします。