BT

最新技術を追い求めるデベロッパのための情報コミュニティ

寄稿

Topics

地域を選ぶ

InfoQ ホームページ ニュース Uberが基礎のフルフィルメントサービスを再構築

Uberが基礎のフルフィルメントサービスを再構築

原文(投稿日:2021/08/10)へのリンク

Uberは先頃、Uberの基本的なプラットフォームサービスの1つ、フルフィルメントサービスの再構築の方法を共有した。30以上のチームと数百人の開発者が関わった2年間の取り組みに続いて、Uberのエンジニアは「新しいプラットフォームでさまざまなタイプの物理的フルフィルメントカテゴリをモデル化するための強力な基盤を構築し、既存のすべての輸送ユースケースを移行した」と述べている。このプラットフォームは、1万を超える都市で、年間100万人を超える同時ユーザと数十億回の旅行を処理する。

フルフィルメントとは「顧客に製品やサービスをデリバリーする行為またはプロセス」だ。Uberのエンジニアは、フルフィルメントサービスを再構築する理由を次のように説明する:

フルフィルメントプラットフォームの最後の主要な書き直しは2014年でした、Uberの規模ははるかに小さく、フルフィルメントシナリオは単純でした。それ以来、Uberのビジネスは発展し、モビリティとデリバリー全体に多くの新しい業種が含まれるようになり、さまざまなフルフィルメントエクスペリエンスを処理しています。例としては、ドライバが事前に確認する予約フロー、同時に提供される複数の旅行のバッチフロー、空港の仮想キューメカニズム、Uber Eatsの三面市場、Uber Directを介したパッケージの配送などがあります。

チームは移動の準備に6か月を費やし、「スタック内のすべての製品を注意深く監査し、ステークホルダーチームから200ページ以上の要件を収集し、数十の評価基準を使用してアーキテクチャオプションについて広範囲に議論し、データベースの選択をベンチマークし、アプリケーションフレームワークオプションのプロトタイプを作成した。」 新しいアーキテクチャの重要な要件は、SLAに少なくとも99.99%準拠している高可用性、リージョン間のトランザクションに対しても強力な一貫性、およびUber開発者が使用するための堅固な拡張性モデルだった。

Uberは、トランザクションの一貫性と水平方向のスケーラビリティの要件を満たすために NewSQL を活用することを決定した。NewSQLは、従来のデータベースシステムのACID保証を維持してオンライントランザクション処理 (OLTP) ワークロードにNoSQLシステムのスケーラビリティを提供しようとするリレーショナルデータベース管理システムのクラスだ。このクラスのデータベースには CockroachDBFoundationDB などのデータベースが含まれる。Uberは、広範なベンチマークの取り組みに続いて、主要なストレージエンジンとして Google Spanner を使用することを選択した。


出典: https://eng.uber.com/fulfillment-platform-rearchitecture/

変更データキャプチャ (change data capture) テクニックを使用したコミット後操作をサポートするため、Uberは潜在的な非同期タスク実行 (Latent Asynchronous Task Execution - LATE) と呼ばれる社内コンポーネントを実装した。LATEは、コミット後のすべての操作とタイマを、読み取り/書き込みトランザクションとともに、別のLATEアクションテーブルにコミットする。専用のLATEワーカは、このテーブルから行をスキャンして取得し、少なくとも1回 (at-least-once) の実行を保証する。

内部エンジニアによる拡張性は、新しいアーキテクチャの重要な側面だ。それをサポートするために、Uberのエンジニアは3部構成のプログラミングモデルを作成した。まず、Statecharts を使用して、一貫性のあるモジュールの動作モデリングを確保しながら、フルフィルメントエンティティをモデル化した。Uberのエンジニアによると「Protobufsを使用した一貫したデータモデリングアプローチを活用し、Statechartsを実装するための汎用Javaフレームワークを構築することで、フルフィルメントエンティティのモデリングの原則を形式化して文書化した。」


出典: https://eng.uber.com/fulfillment-platform-rearchitecture/

次に、Business Transaction Coordinators は、複数のエンティティにわたる書き込みを処理して、モジュール化し、さまざまな製品フローで活用する。Business Transaction Coordinators は、入力としてエンティティトリガの有向非巡回グラフを受け取り、ノードを介して、単一エンティティトリガを表すことで、単一の読み取り/書き込みトランザクションのスコープ内のグラフを調整する。最後に、ORMレイヤは、データベースの抽象化、単純さ、および正確さを提供する。

チームは、下位互換性と上位互換性を維持しながら、既存のサービスユーザを新しいサービスに移行する設計に多大な努力を払った。これらの努力のいくつかは、新しいサービスのための厳しいテストフレームワークをもたらした。Uberのエンジニアは説明する:

200以上の製品フローに対して新しいエンドツーエンドの統合テストを構築し、既存のスタックでバックテストして、古いスタックに対する新しいスタックの正確さを検証しました。新旧スタックの間でリクエストとレスポンスを比較するために、洗練されたセッションベースのシャドウフレームワークを構築しました。開発中のスモークテストに生産都市の構成を一致させるテスト都市を作成しました。これらの戦略はすべて、可能な限り多くの問題を捉え、未知の未知 (unknown unknowns) のものを最小限に抑えることを保証しました。

Uberには、再構築ジャーニーに出る動機がいくつかあった。何よりもまず、Uberは、一貫性と可用性およびレイテンシーのトレードオフを前提として、以前のアーキテクチャを構築した。したがって、ベストエフォートメカニズムを介してのみ一貫性を実現していた。実際には、さまざまなスプリットブレインの状況 (デプロイ中に発生、リージョンのフェイルオーバー) が原因でシステムの不整合が予想以上に発生した。また、複数のエンティティの状態変更はトランザクションではなかったため、どの時点でも一貫性のない状態になった。この動作により、システムのデバッグと推定がはるかに困難になった。

システム再構築の他の理由には、スケーラビリティの懸念と技術スタックを変更したいという願望が含まれていた。古いサービスはNode.jsとHTTP/JSONで記述されていたが、新しいUberサービスは通信にJavaで Protocol Buffers (Protobuf) を使用している。

この記事に星をつける

おすすめ度
スタイル

BT