Delhivery は、インドのデジタル コマースの主要なフルフィルメント プラットフォームとして、1 日あたり 100 万個の荷物を 1 年 365 日フルフィルメントしています。 24 の自動仕分けセンター、101 のハブ、3,100 を超える直接配送センター、1,000 を超えるパートナー センター、11,000 を超えるフリート、60,000 を超えるチーム メンバーは、IoT デバイスの広大なネットワークのおかげでスムーズに稼働しています。毎秒何千ものデータ イベントとメッセージがパイプラインに出入りしています。これはテラバイト単位の膨大な毎日のデータ量に相当し、当社と当社の関係者にとって運用の可視性が非常に重要になります。 要件を認識した私たちは、データ マートを構築することにしました。これは、ユーザーが事前に集約されたビジネス データに迅速にアクセスできるようにする、一元化された結果整合性のあるデータベースです。これにより、関係者はデータ ウェアハウス全体を検索することなく、ビジネスの洞察に迅速にアクセスできるようになります。 ただし、この気が遠くなるような規模では、分析ワークロードの容量を提供しながら、データの整合性と低遅延を維持することが大きな課題の 1 つでした。 このブログでは、データ マートを Amazon Aurora からハイブリッド トランザクション/分析処理 (HTAP) の分散 SQL データベースである TiDB に移行する際に学んだことをすべて解き明かしていきます。この投稿が、TiDB またはその他の HTAP データベースへの同様の移行を検討しているデータ エンジニアリング リーダー、データベース管理者、またはデータ アーキテクトに洞察を提供できれば幸いです。 OLTP、OLAP、HTAP Delhivery でのリアルタイム データ マートの事例をより深く理解するために、まず、ユース ケースの中核となる 3 つの概念 (OLTP、OLAP、HTAP) について理解しましょう。 オンライン トランザクション処理 (OLTP) システムは、トランザクション指向のアプリケーション向けに設計されており、ACID (原子性、一貫性、分離性、耐久性) プロパティを通じてデータの整合性を保証します。 OLTP: オンライン分析処理 (OLAP) システムは、大量のデータの高速多次元分析を可能にし、データ主導の意思決定を支援します。 OLAP: ハイブリッド トランザクション/分析処理 (HTAP) は、OLTP 機能と OLAP 機能を組み合わせて、トランザクション データのリアルタイム分析を可能にします。 HTAP: Delhivery でのリアルタイム データ マートの使用例 リアルタイム データ マートは、特定の間隔ではなくリアルタイムでデータを取り込むという点で従来のデータ マートとは異なります。これらのイベントの同期に遅延は許されないため、これらのデータ マートはデリーベリーでの地上運用の意思決定にとって非常に重要です。 私たちのリアルタイム データ マートへの取り組みは、一元化されたダッシュボード、特に EYE ダッシュボードの必要性を認識した 2020 年に始まりました。このダッシュボードの目的は、地上運用にリアルタイムの運用可視性を提供し、最新のデータに基づいた意思決定を可能にすることでした。使用例には次のようなものがあります。 デリーベリー ハブの着信および発信接続スケジュールをリアルタイムで監視します。 車両の計画と可視性: Delhivery の施設の継続的なパフォーマンス追跡。 パフォーマンス追跡: 中央チームに地上ブロッカーに関する正確な情報を提供し、適切な行動をとります。これらは、センターのパフォーマンスの低下、出荷の老朽化、受信接続と送信接続の混雑など、さまざまな要因が原因である可能性があります。 集中制御の可視化: プットおよびピックのコンプライアンス指標の追跡 コンプライアンス: 初期実装と課題 Redshift や Snowflake などのデータ ウェアハウス ツールを使用してユースケースを解決することを考えましたが、設計パターンとマージを伴うリアルタイム データ インジェストの要件を考慮すると、これらのソリューションはいずれも機能しませんでした。 したがって、最初はデータ マートのユースケースに対応するために Aurora (PostgreSQL) を選択しました。 Aurora に関するデータ取り込みプロセス 私たちは、Spark Streaming と Aurora を使用してリアルタイム データ マートを構築しました。私たちのスチーム パイプラインは非常にシンプルで、Kafka からデータを読み取り、Spark マイクロ バッチでデータを処理し、Aurora で upsert 操作を実行しました。 私たちのデータベースは、生のレイヤー、パーティション化されたレイヤー、データ マート レイヤーで構成される多層アーキテクチャを使用してモデル化されました。ユーザーには、生のレイヤーのデータを表示または変更するアクセス権がありませんでした。パーティション化されたレイヤーは、すべてのパーティション化されたテーブル (一般にディメンション テーブル) を維持するために保持されます。以下はデータベースの簡単なスキーマ設計です。 Aurora で直面した課題 システムは当初、1 秒あたり 3,000 メッセージを超えるスループットを処理する必要があるまで、良好なパフォーマンスを発揮しました。これにより、次のようないくつかの課題が始まりました。 1 秒あたり 3K メッセージのスループットを超えたため、Aurora の 1 秒あたりの入出力操作数 (IOPS) の制限がボトルネックになりました。スケーラビリティの制約が当社の業務に影響を及ぼし始めていました。 スケーラビリティの制限: レコードが更新されるたびに、新しいレコードと無効なタプル (レコードの以前のバージョン) が作成されます。これらの無効なタプルの生成速度がクリーンアップ プロセスを上回ると、肥大化が発生しました。 VACUUM FULL がストレージを要求できなかったため、ディスク使用量は増加し続けました。約 5 TB のデータに対して、Aurora は 30 TB 以上のストレージを使用していました。 肥大化の問題: 肥大化の問題は、メンテナンスの課題に直接関係しています。 70 を超えるパイプラインと合計書き込み QPS が 5,000 メッセージ/秒を超えているため、PostgreSQL の自動クリーンアップ プロセスである Auto Vacuum がデッド タプルの生成速度に追いついていないことがわかりました。したがって、データベースを回復するには、VACUUM または VACUUM FULL を手動で実行する必要があります。 pg_repack や pgcompacttable などの PostgreSQL ツールを使用した試みも失敗に終わりました。 メンテナンスの負担: その結果、メンテナンスはますます複雑になり、時間がかかるようになりました。 読み取りおよび書き込みのワークロードに対応するには、利用可能な最大のノード (24XLarge) まで拡張する必要がありました。これにより、3 ノードの Aurora クラスターに毎月約 100,000 ドルの支出が発生しました。この規模では、IOPS の自動スケーリングにより、Aurora は高価であることが判明しました。 コスト: 代替品を探す Aurora の制限を解決するために、私たちは次の要件を満たすより良い代替手段を見つけることに着手しました。 データベースは少なくとも 10,000 以上の書き込み QPS をサポートし、水平方向にスケーラブルである必要があります。 高い書き込み QPS でスケーラブル: データベースは高速またはリアルタイムの OLAP 機能を提供できる必要があります。 リアルタイム分析: 高可用性とフォールト トレランスを提供するには、データベースを複数のサイトに分散する必要があります。 完全に分散: データベースは強力な一貫性を維持し、すべてのユーザーが同じデータを参照できるようにする必要があります。 強力な一貫性: 上記のすべての要件を考慮し、変更管理を最小限に抑えたいと考え、当初は Spanner や Yugabyte を含む多くの PostgreSQL の代替案を検討しました。 スパナ Spanner は、Google が提供する分散 SQL データベース管理およびストレージ サービスです。 Google Cloud Platform (GCP) 上でフルマネージドされます。ただし、次の理由により、Spanner は私たちのアーキテクチャにとって適切なユースケースではない可能性があることがわかりました。 Spanner はスキーマをサポートしていません。 履歴データをロードするための適切なツールが見つかりませんでした。 Spanner の評価と移行のためのオープンソース ツールである Harbourbridge について調査しました。ただし、約 100 GB のデータ読み込みに制限がありました。 ユガバイト YugabyteDB は、Yugabyte によって開発された、クラウドネイティブ アプリケーション用の高性能トランザクション分散 SQL データベースです。このデータベースは PostgreSQL に完全に準拠し、水平方向にスケーラブルで、完全に分散されているため、私たちのユースケースに非常に近いものです。残念ながら、スケーラビリティに制限があるため、それほどうまく機能しませんでした。私たちの成功基準では 1 秒あたり 7,000 以上のトランザクションが必要でしたが、Yugabyte は 5,000 までしかスケールアップできませんでした。 BigQuery などの他の候補も検討しましたが、どれも私たちの要件を十分に満たすものではありませんでした。 TiDB で着陸 上記の PostgreSQL の代替案の後、HTAP を要件に追加することに決め、それが TiDB につながりました。すぐに使えるスケーラビリティ、一貫性、可用性、マルチサイト展開トポロジ、その他多くの機能をサポートします。分散データベースである TiDB には、相互に通信して完全な TiDB システムを形成する複数のコンポーネントがあります。 これは、クライアント側のエンドポイントをユーザーに提供するステートレス SQL 処理コンポーネントです。データを取得するために PD から接続する正しい TiKV ノードを見つけます。 TiDB: データを左 - クローズ - 右 - オープンの範囲に保持する、分散トランザクションのキーと値のデータ ストアです。データは複数のレプリカを持つシャードに保存されます。 TiKV は、レプリケーションに Raft プロトコルを使用します。 TiKV: 配置ドライバー (PD) は、シャード レプリカの場所などのクラスターのメタデータを保持し、TiKV ノード全体でシャードをスケジュールする役割も担います。 PD リーダーはそのようなタスクを処理し、他のノードは高可用性を維持します。 PD: Multi-Raft Learner プロトコルを使用して TiKV からリアルタイムでデータをレプリケートし、TiKV 行ベースのストレージ エンジン間でデータの一貫性を確保するカラムナ型ストレージ拡張機能。 TiFlash: TiDB の次の機能は私たちの主要な課題に対処し、運用要件を満たしました。 簡単なスケーリング TiDB アーキテクチャ設計はコンピューティングをストレージから分離しており、必要に応じてコンピューティングやストレージの容量をオンラインでスケールアウトまたはスケールインできます。スケーリング プロセスは、アプリケーションの運用スタッフやメンテナンス スタッフにとって透過的です。 ACID準拠 TiDB は MySQL に準拠しており、すぐに使用できるトランザクションをサポートします。楽観的なトランザクションと悲観的なトランザクションの両方のタイプをサポートします。これにより、他のデータベースとは異なります。 可用性が高い TiKV はデータを複数のレプリカに保存し、Multi-Raft プロトコルを使用してトランザクション ログを取得します。トランザクションは、大部分のレプリカにデータが正常に書き込まれた場合にのみコミットできます。これにより、少数のレプリカがダウンした場合でも、強力な一貫性と高可用性が保証されます。 リアルタイムHTAP TiDB は、行ストレージ (TiKV) と列指向ストレージ (TiFlash) の両方を同じアーキテクチャ内で組み合わせて、運用データのリアルタイム分析を容易に作成できる合理化された技術スタックを形成します。 当社の TiDB インフラストラクチャ 当社の TiDB インフラストラクチャは、主要なクラウド サービス プロバイダーの VM 上にデプロイされます。 TiDB のパッケージ マネージャーである TiUP を使用して、クラスターとすべての管理操作を管理します。私たちのクラスターは 3 つの利用可能なゾーン (AZ) 上にデプロイされています。 クラスター構成は次のとおりです。 PD レイヤーには、マルチ AZ に分割された 3 つのノードがあります。 PD リーダーはそのようなタスクを処理し、他のノードは高可用性を維持します。 PD: TiDB レイヤーには、n2-highmem-8 ファミリの 9 つのノードがあります。これらのノードはメモリ要件に基づいて選択され、各 TiDB ノードに 64 GB RAM と 8 コア CPU が割り当てられました。 TiDB: TiKV レイヤーには、128 GB RAM と 16 個の vCORE CPU を備えた n2-highmem-16 ファミリの 15 ノードがあります。 TiKV: TiDB クラスターを複数の AZ にデプロイし、処理とメモリのニーズを満たすノード タイプを慎重に選択することで、高いデータ スループット要件に対応できる堅牢で可用性の高いインフラストラクチャを作成しました。 私たちのケースに合わせて TiDB をチューニングする 私たちのユースケースで機能するように、PingCAP チームと緊密に連携してデータベースを調整しました。私たちが行った重要な調整の一部を以下に示します。 インデックスの最適化 インデックスを開始する前に、次のパラメータを設定します。 SET @@global.tidb_ddl_reorg_worker_cnt = 16; SET @@global.tidb_ddl_reorg_batch_size = 4096; インデックス作成後にデフォルト値にリセットします。 SET @@global.tidb_ddl_reorg_worker_cnt = 4; SET @@global.tidb_ddl_reorg_batch_size = 256; パーティションのプルーニング これは主にパーティション化されたテーブルにとって重要です。クエリ ステートメントのフィルター条件を分析し、必要なデータが含まれていないパーティションを削除 (プルーニング) します。 SET @@session.tidb_partition_prune_mode = 'dynamic'; チューニング分析 大量のデータが取り込まれると、TiDB の自動アナライザーが失敗することがあります。その場合、すべてのクエリで間違った実行プランが使用され、テーブル全体がスキャンされてしまう可能性があります。このような状況を回避するために、TiDB 構成に次の変更を加えました。 set global tidb_max_auto_analyze_time = 86400; set global tidb_enable_pseudo_for_outdated_stats = off; set global tidb_sysproc_scan_concurrency = 15; パーティション化されたテーブルを使用している場合は、分析の失敗を避けるために、一度に 1 つのパーティションに対してテーブルの分析操作を手動で実行することをお勧めします。 このような調整により、TiDB の使用を効果的に合理化し、リアルタイム データ マートの最適なパフォーマンスを達成することができました。 TiDB に関する私たちの経験 クエリのパフォーマンスの向上 400 を超えるクエリのベンチマークを実施したところ、すべてのクエリが SLA 内で実行されていることがわかりました。 P95 クエリのパフォーマンスが 15 ~ 20% 向上したこともあります。 簡単な移行 TiDB Lighting ツールを使用して、テーブルのすべての履歴データを Postgres から TiDB に移行しました。このツールは非常に使いやすく、非常に高速です。約 2 ~ 3 時間以内にテラバイト規模のデータをロードすることができました。ただし、このような巨大なデータをロードする前に多くの調整が必要であることに注意してください。 強力なサポート 実稼働インフラストラクチャのセットアップ中にいくつかの問題が発生しましたが、PingCAP サポート チームが非常に重要な役割を果たし、ワークロードの性質に合わせてクラスターを調整するのに役立ちました。 結論 この投稿では、リアルタイム データ マートのユースケースと TiDB への移行過程で Aurora を使用する際の課題を検討しました。また、Delhivery が TiDB をどのように大規模に使用しているかについても説明しました。 TiDB での成功にもかかわらず、完璧なソリューションはなく、有効性はユースケースによって異なる可能性があることを認識しています。 TiDB では、マテリアライズド ビューやネイティブ クォータ管理に対するすぐに使用できるサポートの欠如など、改善の余地があるいくつかの領域に注目しました。ただし、適切な回避策と調整を行うことで、これらの制限に効果的に対処することができました。 これまでのところ、実稼働環境に TiDB をデプロイしてきました。私たちのベンチマークに基づくと、TiDB を使用すると、1 秒あたり数千を超えるリクエストを 100 ミリ秒未満のレイテンシーで処理できます。今後も、堅牢で一貫した分散型データベースを必要とするさらなるユースケースの探索を続けていきます。 参考文献 https://docs.pingcap.com/tidb/stable/tidb-lightning-overview https://reorg.github.io/pg_repack/ https://github.com/dataegret/pgcompacttable https://cloud.google.com/spanner https://www.yugabyte.com/yugabytedb/ https://cloud.google.com/bigquery/ https://docs.pingcap.com/tidb/dev/transaction-overview https://proxysql.com/ 著者: (デリーベリーのシニアエンジニアリングマネージャー) Hari Kishan (デリーベリーのテクノロジー ディレクター) Akash Deep Verma