先頃のブログ投稿で、Uberのエンジニアは、自社開発のレプリケーションプラットフォームを使用して、マルチリージョンのKafka展開で大規模な災害復旧を実装する方法を強調している。
UberにはApache Kafkaの大規模な展開があり、1日に数兆のメッセージと数ペタバイトのデータを処理する。Kafkaを使用するには、エンジニアは自然災害や人為的災害に直面した時にビジネスの回復力と継続性を提供する必要があった。彼らは、Kafkaのデータを複製するためのUberのオープンソースソリューションであるuReplicatorを構築した。KafkaのMirrorMakerをベースにしたUberベースのuReplicatorで、高信頼性、データ損失ゼロの保証、運用のしやすさが改善されている。
UberのエンジニアであるYupeng Fu氏とMingmin Chen氏は、彼らの洞察を要約している:
プラクティスからの重要な洞察は、Kafkaのような信頼性が高くマルチリージョンで利用可能なインフラストラクチャサービスを提供することで、アプリケーションの事業継続計画の開発を大幅に簡素化できることです。アプリケーションはその状態をインフラストラクチャ層に格納できるため、ステートレスになり、リージョン間の同期やレプリケーションなどの状態管理の複雑さをインフラストラクチャサービスに任せることができます。
uReplicatorを使用して、Uberのエンジニアは災害復旧のために次のKafkaトポロジを構築した:
出典: https://eng.uber.com/kafka/
各プロデューサは、リージョンのKafkaクラスタでローカルにデータを生成する。この戦略は最もパフォーマンスの高いオプションだ。ローカルのKafkaクラスタに障害が発生した場合、プロデューサは別のリージョンのKafkaクラスタにフェイルオーバーする。次に、uReplicatorはリージョンクラスタを複製して、すべてのリージョンで利用可能なKafkaクラスタを集約する。各クラスタには、他のすべてのリージョンからの集約データが含まれている。
メッセージの消費は、アクティブ-アクティブまたはアクティブ-パッシブの2つのReaderトポロジを使用して、各リージョンの集約Kafkaクラスタから常に行われる。アクティブ-アクティブは、パフォーマンスと回復までの時間の短縮がより重要な場合に推奨される。一方、アクティブ-パッシブは、一貫性がより重要な場合に好まれる。
アクティブ-アクティブモードでは、すべてのリージョンのReaderが集約されたクラスタからデータを読み取る。ただし、選択したプライマリサービスのみが処理済みデータを更新し、すべてのリージョンでアクティブ-アクティブデータベースを使用できるようになる。次の図は、Uberの急上昇価格データを計算するFlinkジョブでこの概念を示している。
出典: https://eng.uber.com/kafka/
アクティブ-パッシブモードでは、一度に1つのリージョンの集約クラスタから消費できるのは1つのコンシューマのみだ。Kafkaは、消費オフセットを他のリージョンに複製する。プライマリリージョンに障害が発生すると、コンシューマは別のリージョンにフェイルオーバーし、消費を再開する。Uberは、このアプローチで「集約クラスタからのメッセージは、リージョンクラスタから集約した後、順序が狂う可能性がある」場合の警告を処理する必要があった。Uberは、次の図に示すように、これらの不一致を解決し、リージョンのフェイルオーバに直面した時にデータ損失をゼロにすることを使命とするオフセットマネージャを導入した。