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

[JPN] Creating Spanner Index over 57 hours

783718ebd2faaa896d4cb347835c07fb?s=47 tarotaro0
February 05, 2021

[JPN] Creating Spanner Index over 57 hours

(Japanese slide)
Write about:
- The story of creating Spanner Index over 57 hours in production
- The knowledge from the operation

783718ebd2faaa896d4cb347835c07fb?s=128

tarotaro0

February 05, 2021
Tweet

Transcript

  1. mercari.go #15 @tarotaro0 57時間かけてCloud Spannerに インデックスを追加して得た知見

  2. ⭕ 今回の発表のターゲット • Goで作られたマイクロサービスの周辺知識 • Cloud Spannerの実用例 ❌ 今回ターゲットにしない話 •

    Go言語 はじめに
  3. Cloud Spannerとインデックス Agenda 57時間かけてインデックスを追加した話 得られた知見とその後 02 03 01

  4. Cloud Spannerとインデックス

  5. Cloud Spanner • GCP上のフルマネージドRDB • Cloud SQLとの比較 ◦ マルチリージョン ◦

    高可用性 ◦ 水平スケーリング ◦ etc… • メルカリ・メルペイで多くのマイクロサービ スがメインDBとして用いている 参考:https://cloud.google.com/spanner
  6. Secondary Index (以下 インデックス) • 特定のカラムに対する検索効率の向上が目的 ◦ 主キーは自動的にインデックスが作成されるため不要 • インデックス用のテーブルとして新たに格納される

    ◦ 主キー + インデックスのキー ◦ 通常テーブルと同様の注意が必要(ホットスポットなど) • 多くのケースではテーブル作成と同時にインデックスを作ることが効率的 で、推奨されている ◦ データが少ない方が負荷も少なく作成時間も短い ◦ ホットスポット回避のために初期を避けるケースもある 参考: https://medium.com/google-cloud-jp/cloud-spanner-aruaru-quiz-6430fcf80a1
  7. 今回の話 • 既に本番稼働中のSpannerにインデックスを追加した話 ◦ サービスのダウンタイム無し ◦ 約57時間のオペレーション ◦ SpannerのCPUが100%に張り付き続ける ◦

    得られた知見 • ↑の知見を活かして同様のオペレーションを問題なく実行した話
  8. 57時間かけてインデックスを追加した話

  9. • 既存のNotificationsテーブルは右図 ◦ 設計当初の要件に合わせた 複合Primary Keyを設定 • 当初想定していなかったUUIDのみによ る検索が必要になる ◦

    SpannerではPKの1つ目のカラムに 対して分散される ◦ (UUID)に対するインデックスが必要 インデックス追加の背景 Notifications Table Schema CREATE TABLE Notifications ( UserId INT64 NOT NULL, UUID STRING(64) NOT NULL, … … …, ) PRIMARY KEY (UserId, UUID, …);
  10. インデックス追加開始 インデックス追加開始後のSpanner CPUモニタリング → System Low Priorityの使用率が急上昇 ▪ User High

    Priority ▪ System High Priority ▪ System Low Priority
  11. なぜ長時間・高負荷になってしまったか • 数十億規模のレコード数 ◦ テスト・開発環境の数百倍 • 普段の処理性能(ノード数)を上回るほどタスクが重い ◦ 普段の余剰分で十分だと思っていた •

    公式ドキュメントの推奨アラートには当たらず様子を見ていた
  12. 作成開始から数十時間経過後 数時間Total CPU使用率が100%を継続している... → このままでは24時間で平滑化したCPU使用率が推奨値(90%)を超える ▪ User High Priority ▪

    System High Priority ▪ System Low Priority
  13. 実行時間の見積もり 2通りの方法で見積もりを行っていた • レコード数から試算 ◦ テスト・開発環境にインデックスを追加したデータから、レコード数に対して線形 時間かかると仮定して約60時間 • 途中まで作成されたストレージ容量から試算 ◦

    実行中に計測した単位時間当たりに作成されるストレージ容量と、最終的に増 加する見込みの容量から判断して約58時間 → 試算された結果より、問題だと判断
  14. 追加のオペレーション • ノードの追加 ◦ ダウンタイム無しに水平スケール出来 るSpannerの良い点 ◦ ノード追加のために余計にCPUを使っ てしまい、更にCPUを逼迫させる懸念 は残っていた

    • その他の選択肢 ◦ インデックス作成の中止 引用 :https://www.slideshare.net/HammoudiSamir/cl oud-spanner-78081604
  15. 作成開始から30数時間経過後 ノード数を7→13に変更 → 平均80%前後で余裕が生まれ、最終的に57時間で完了した ▪ User High Priority ▪ System

    High Priority ▪ System Low Priority
  16. 得られた知見とその後

  17. • 高負荷時のノード追加対応 ◦ ノード追加による負荷はほぼ感じられない ◦ 特別なダウンタイムを設けずスケール出来るのはSpannerの良い点 • インデックス作成時間の見積もり ◦ レコード数に対して線形時間であると近似して計算

    ◦ 実行中に増加したストレージ容量から計算 • Spanner CPUの負荷 ◦ 100%の時にUser High Priorityタスクに僅かに影響した ◦ 優先度付きとはいえ、余裕が必要 得られた知見
  18. 良かった点 • 事前の実行時間試算 • 事前のノード追加 • CPU使用率がMax 60% その後の同様のオペレーション Notifications

    Table A Table B レコード数 数十億 10億 15億 普段のCPU使用率 20~30% 20~30% 20~30% ノード数 7 → 13 (15→) 24 (15→) 21 実行時間 57時間 1時間 2時間 Table A実行時のCPU使用率
  19. • レコード数やノード数から適切な時間を試算する ◦ 必要に応じて事前にノード追加しておく • 高負荷にならなければダウンタイム無しに問題なく追加可能 ◦ 途中で高負荷になっても、ノードを後から追加することで解決出来る • そもそも途中でインデックスを追加しない選択肢も考える

    ◦ 要件の見直し・修正 ◦ 最初から注意深く設計しておく ◦ etc... まとめ Tech Blogにも書いているので良かったらどうぞ: https://engineering.mercari.com/blog/entry/20201203-3f9780edf7/