Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Azure Cosmos DB での時系列ログの運用と改善

Azure Cosmos DB での時系列ログの運用と改善

■ イベント
Azure PaaSを使った大規模BtoBプロダクト開発と運用の舞台裏 -データベースサービス編-
https://sansan.connpass.com/event/325049/

■ 発表者
技術本部 Sansan Engineering Unit Data Hubグループ 高橋 光太郎

■ Sansan Data Hubエンジニア 採用情報
https://media.sansan-engineering.com/datahub-engineer

■ Sansan Tech Blog
https://buildersbox.corp-sansan.com/

SansanTech

August 29, 2024
Tweet

More Decks by SansanTech

Other Decks in Technology

Transcript

  1. 2 ©Sansan, Inc. 自己紹介 前職はSIerにて大型公共案件を中心に .NET + Azure のイン フラ開発、アプリケーション開発などに従事。

    2018年、Sansan Data Hub のローンチとほぼ同時期に開発 メンバーとしてSansanにジョインし、プロダクトの成長と 共に5年間を過ごす。プロダクト初期の全てがカオスだっ た時期から現在まで、レイヤーにこだわらずプロダクト価 値の向上と安定運用に向き合っている。 高橋 光太郎 (Kotaro Takahashi)
  2. 4 ©Sansan, Inc. ※詳細は省略しています (各マイクロサービスのデータストア等) Sansan Data Hubの全体像 管理用画面 組織データなど

    データ書き出し先 データ取り込み元 データ連携用API 組織情報作成処理群 書き出し処理群 取り込み処理群 コアデータ群
  3. 5 ©Sansan, Inc. ※詳細は省略しています (各マイクロサービスのデータストア等) Sansan Data Hubの全体像 管理用画面 組織データなど

    データ書き出し先 データ取り込み元 データ連携用API 組織情報作成処理群 書き出し処理群 取り込み処理群 コアデータ群 Azure Cosmos DB での 時系列ログの運用と改善 Azure SQL Database Hyperscale HA レプリカ の監視
  4. 6 ©Sansan, Inc. やんわり Azure Cosmos DB の特徴を紹介 - フルマネージドと

    分散 NoSQL データベース - コンピューティングとストレージに対する弾力的なスケールを提供 - 選択可能な整合性レベル - read/write のレイテンシに対して SLA Azure Cosmos DB って?
  5. 7 ©Sansan, Inc. Sansan Data Hub では 月間 8 億件

    のレコードを外部サービスに書き出している - 外部サービスへの書き出し結果を「書き出しログ」として Cosmos DB に格納 - 1レコードの書き出しに対して、1件の書き出しログを Azure Cosmos DB に記録 - 2024/08/26 時点でログの総量は約 9 TiB - Cosmos DB の Change Feed を通して Data Lake Storage にアーカイブ - 書き出しログは TTL を付けて自動的に削除 Sansan Data Hub での Azure Cosmos DB の利用 データ書き出し先 書き出し処理群 書き出しログ
  6. 8 ©Sansan, Inc. 書き出しログのシステム構成 データ書き出し先 Function Apps Cosmos DB Function

    Apps Function Apps Service Bus Service Bus Data Lake Storage Gen2 Synapse Analytics Function Apps 開発・運用 メンバー 【Change Feed API】 書き出しログ TTL が過ぎたログは バックグラウンドで自動削除
  7. 9 ©Sansan, Inc. Why Cosmos DB ? Sansa Data Hub

    での書き出しログの特徴 - 書き出し量は予測不可能で突然のスパイクがある - アプリケーションだけでなく DB も瞬時にスケールしてほしい - マネージドサービスでメンテナンス不要 - 他の箇所で Azure VMSS 上に Elasticsearch Cluster を構築して運用している - 時系列ログの格納先として Elasticsearch も考えたが、マネージドの利点が勝った - 時系列データなので、古いログはアーカイブする - TTLがあるとアーカイブが楽 - Hot Storage 上でのリテンション期間が過ぎれば自動で消えてくれる => Comos DB ぴったりじゃん!
  8. 10 ©Sansan, Inc. 書き出しログの設計 { "partitionKey": "sansan_88e6610cc3064bbeba8d225c8c7210a4_20240826", "id": "244c14e16c71427c9d6e3e61bafb871f", "jobMetadata":

    { ... }, "contentMetadata": { ... }, "data": { ... }, "success": true, "errors": [ ... ], "createdAt": "2024-08-26T12:52:03.369263+00:00", "_ts": 1716900723 } (サンプルログ) - partitionKey - 論理パーティションキー - id - ドキュメントID - jobMetadata - 書き出しジョブの情報 - contentMetadata - 書き出し先のメタデータ - data - 書き出した内容 - success - 書き出し成功・失敗 - errors - 書き出し失敗時のエラー情報 今日はこの部分を 重点的にお話しします
  9. 11 ©Sansan, Inc. 書き出しログの設計 パーティション設計 { "partitionKey": "sansan_88e6610cc3064bbeba8d225c8c7210a4_20240826", "id": "244c14e16c71427c9d6e3e61bafb871f",

    "jobMetadata": { ... }, "contentMetadata": { ... }, "data": { ... }, "success": true, "errors": [ ... ], "createdAt": "2024-08-26T12:52:03.369263+00:00", "_ts": 1716900723 } "sansan_88e6610cc3064bbeba8d225c8c7210a4_20240826" テナントID 書き出し先ID 書き出しを実行した週の 先頭(月曜)の日付 論理パーティションを週毎にまとめることで、 TimeRenge での検索を効率化 t1_o1_20240728 t1_o1_20240805 t1_o1_20240812 t1_o1_20240819 t1_o1_20240826 SELECT * FROM c WHERE (c.partitionKey BETWEEN 't1_01_202040805' AND 't1_01_202040819') AND ... (サンプルログ)
  10. 13 ©Sansan, Inc. 書き出しログの設計 Pertition1 Pertition2 Pertition3 write write write

    理想 t1_o1_20240805 t1_o1_20240812 t1_o1_20240819 write write write 現実 書き込み時はパーティションが均等に分割する read 読み込み時はパーティションを特定する (クロスパーティションのリクエストを避ける) 書き込み時のパーティションに負荷が偏る 特定テナント・特定期間のログ検索において効率が良い read パーティション設計 => Hot Partition が発生
  11. 14 ©Sansan, Inc. 書き出しログの設計 Hot Partition が出来ると何が悪いのか? - Cosmos DB

    のリソース(RU) を効率的に使えない - 論理パーティションは自動で物理パーティションにマップされる - 購入した RU (プロビジョニングスループット) は物理パーティションに按分される t1_o1_20240728 t1_o1_20240805 t1_o1_20240812 t1_o1_20240819 t1_o1_20240826 論理パーティション 物理パーティション t2_o1_20240728 t2_o1_20240805 t2_o1_20240812 t2_o1_20240819 t2_o1_20240826 プロビジョニングスループット: 3,000 RU/s 1,000 RU/s 1,000 RU/s 1,000 RU/s RUを使い切って TooMenyRequest が多発
  12. 15 ©Sansan, Inc. Hot Partition と闘う Hot Partition をどうにかしたい -

    そのための工夫を2点ご紹介 1. 物理パーティションへの書き込みを直列化する 2. Hot Partition を検知してパーティションキーふり直す (ReRouteする)
  13. 16 ©Sansan, Inc. Hot Partition と闘う ① 物理パーティションへの書き込みを直列化する 1. PartitionKey

    から 物理パーティションID を取得 ※ レスポンスの x-ms-documentdb-partitionkeyrangeid Header を利用 2. Service Bub の Session キューを利用して、物理パーティション毎に書き込み処理を直列化する - RU が余っている物理パーティションの処理を優先させる - 物理パーティションの RU 消費を限定する tenant_A tenant_A tenant_B tenant_B tenant_A tenant_A tenant_A tenant_A tenant_A Service Bus Session キュー tenant_B 直列化なし tenant_A tenant_A tenant_A tenant_A tenant_A tenant_A tenant_B tenant_B tenant_A tenant_B 直列化あり 特定テナントで短期間に 大量のログが出ると、 物理パーティションが Hot になる : : 特定の物理パーティション が Hot でも、他の物理パ ーティションの書き込みを 邪魔しない
  14. 17 ©Sansan, Inc. Hot Partition と闘う ② Hot Partition を検知してパーティションキーふり直す

    (ReRoute する) - 書き出しログのメッセージ処理が10分以上遅延している場合に、 論理パーティションキーにサフィックスを付与することで別の物理パーティションへ分散させる - サフィックスの index は書き出しログのハッシュによって4つに分散 ("tenant_A_1", "tenant_A_2", "tenant_A_3", "tenant_A_4") - ReRoute 処理は再帰的に行う ("tenant_A_1", "tenant_A_1_1" … 。再分散先が遅延した場合、さらに分散させる。再帰処理は5回まで) - 遅延が許容範囲内に収まったら元の論理パーティションに戻ってくる tenant_A (enqueue time: 2024-08-26T00:00:00) tenant_A ① [Function 実行日時 - enqueue time] が、10分以上の場合に遅延と判定 tenant_A_1 tenant_A_1 (enqueue time: 2024-08-26T00:20:00) ② 論理パーティションキーにサフィックスを 付与して Service Bus Session キューに再投入 Service Bus Session キュー
  15. 18 ©Sansan, Inc. まとめ: Azure Cosmos DB で時系列ログを運用してみて よかった -

    Query 性能は期待通り - 特に、応答性が SLA で保証されている = テスト環境と本番環境で性能が変わらないことが (お金をかけ れば) 保証されている - データ量等で性能が上下しないのはまじでうれしい - ストレージとコンピューティングのスケール性はすばらしい - ストレージ上限を考えずに運用をはじめても、 9TiB のログがきちんと運用できている - 必要な時に RU を瞬時にスケールアウトできてよかった場面はいくつかあった - 緊急の調査依頼とかで大規模なクエリを流したいときとか - TTL は楽 - 特に時系列ログ(一定期間で Cold Storage に落としてよい or 削除して良い)では、考えることが減るのが ダイレクトに「楽」につながる - 特に Cosmos DB ではユーザ要求によって消費されていない残りの RU で削除してくれる
  16. 19 ©Sansan, Inc. まとめ: Azure Cosmos DB で時系列ログを運用してみて 悪かった (難しかった)

    - 設計むずい - フルマネージドの NoSQL、数ミリ秒 (1 桁台) の応答、自動および即時のスケーラビリティ - だけど、それらを活かすためには物理パーティションまで意識しなければいけない - 特に今回はパーティションキーを失敗して、結構力業で頑張っている