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

RDB無停止移行への挑戦 #データベース_findy

Ryuya Ikeda
October 13, 2023

RDB無停止移行への挑戦 #データベース_findy

2023年9月26日に行われたファインディ社主催の「データベース移行のウラガワ- 円滑なリリースのために取り組んだLT」の登壇資料です。
https://findy.connpass.com/event/294868/

RDBやアプリケーションの機能を止めずにデータベース移行を実施した事例について紹介しました。
https://techblog.yahoo.co.jp/entry/2022102430369838/ に執筆した内容になります。

Ryuya Ikeda

October 13, 2023
Tweet

Other Decks in Technology

Transcript

  1. Copyright (C) 2020 Yahoo Japan Corporation. All Rights Reserved. 公開

    © Yahoo Japan RDB無停⽌移⾏への挑戦 ヤフー株式会社 マーケティングプラットフォーム統括本部 広告開発本部 池⽥ 流弥 2023/09/26
  2. 公開 © Yahoo Japan 公開 ⾃⼰紹介 2 池⽥ 流弥(Ryuya Ikeda)

    2020年 ~ ヤフー株式会社 Yahoo!広告 ディスプレイ広告 バックエンドエンジニア GitHub, Twitter などは @rikeda71
  3. 公開 © Yahoo Japan 公開 Yahoo!広告 ディスプレイ広告とは 1.移⾏対象のDBの概要 5 •Yahoo!

    JAPANのトップページや広告の掲載枠があるWEB サイトに、画像や動画付きで表⽰できる広告 •多彩なターゲティングや予算に応じた料⾦設定に対応 •ヤフー社内で⼊稿・配信システムを開発 IUUQTBETQSPNPZBIPPDPKQTFSWJDFEJTQMBZBET ΑΓ
  4. 公開 © Yahoo Japan 公開 移⾏対象のDB 1.移⾏対象のDBの概要 6 •OracleDB を採⽤

    •Amazon RDS のように DB チームが OracleDB を利⽤できるプラットフォームを提供 •広告配信における予算・課⾦情報を保存 • 広告の予算と課⾦額 • 課⾦・返⾦ログ(数⽇分) •格納した情報は広告の配信⾦額の課⾦に利⽤
  5. 公開 © Yahoo Japan 公開 移⾏の背景 1.移⾏対象のDBの概要 7 ソフトウェア・ハードウェアの EOL

    にともない移⾏が必要に •約5年間運⽤し続けた DB •Oracle12c (12.2.0.1) の EOL • Oracle19c への移⾏が必要に
  6. 公開 © Yahoo Japan 公開 DB を停⽌した場合の影響 2.DBを停⽌できない理由 9 前提︓DBチームで提供されている移⾏⽅法による

    DB 停⽌は最低で2時間程度 (Oracle Data Pump または Oracle GoldenGate を利⽤する⽅法が提供されている) •DB 停⽌に伴いサービスの機能を停⽌させることによる影響 • 広告配信に伴う課⾦ができない • 課⾦ができないことによる機会損失によって、かなりの売り上げが毀損してしまう • 課⾦ = 更新処理であるため、DB を読み取り専⽤にすることもできない => 停⽌を許容いただくための広告主さま・関係者へのコミュニケーションが難しい
  7. 公開 © Yahoo Japan 公開 移⾏の要件 2.DBを停⽌できない理由 11 •サービス無停⽌ •

    DB だけでなく、DB を利⽤するアプリケーションの機能を⽌めない •サービスに影響のあるデータの差分を発⽣させない • ⾦額を扱う DB であるため、移⾏前 / 後で差分を出すことはできない •利⽤者から⾒た影響が軽微
  8. 公開 © Yahoo Japan 公開 アプリケーション側に以下の機能を実装することで無停⽌移⾏を実現 •並⾏書き込み機能 •新旧差分確認 API •新旧差分マイグレ

    API 移⾏⽅法: 移⾏に利⽤した機能 3.無停⽌移⾏の⼿順 14 old new ①課⾦リクエスト app ②旧DBの更新 ③新DBの更新 ④レスポンス ※ レスポンスは旧DB内のデータを使って処理できた値を使って⽣成 ※ ビジネスロジックは各DBに⼊っているデータを利⽤して実⾏ => DB に保存 新規差分を発⽣させないための機能 性能要件を満たすため、2相コミットは採⽤せず、旧新別々にトランザクション制御
  9. 公開 © Yahoo Japan 公開 ◼ 永続化層(Repository) •並⾏書き込み機能で実装は特に変わらず •新旧DB⽤のクライアントを別途実装 Dependency

    Injec,on (DI) で新旧DBのクライアントを注⼊ した 新旧DB⽤の Repository をそれぞれ定義 ◼ トランザクション制御を担う Applica;on Service •並⾏書き込み機能で実装は特に変わらず •DI で新旧DB⽤の Repository を注⼊した新旧 DB ⽤の Applica;on Service の実装を定義 •この実装の中でトランザクション制御が閉じる 並⾏書き込み機能の実装イメージ 3.無停⽌移⾏の⼿順 15 ※ 疑似コードは Java + SpringBoot の例
  10. 公開 © Yahoo Japan 公開 ◼ Applica;on Service •DI で「新旧DB

    ⽤のトランザクション制御を担う Applica;on Service」を注⼊ •旧 -> 新の順で処理 •旧の結果を返却 ◼ 実装の差分 •新 DB ⽤のクライアントと設定 •Applica;on Service で 旧 -> 新 の順で処理 •DI 並⾏書き込み機能の実装イメージ 3.無停⽌移⾏の⼿順 16 ※ 疑似コードは Java + SpringBoot の例
  11. 公開 © Yahoo Japan 公開 アプリケーション側に以下の機能を実装することで無停⽌移⾏を実現 •並⾏書き込み機能 •新旧差分確認 API •新旧差分マイグレ

    API 差分を確認するための機能 1件ずつレコードの差分を調べられるような仕様 移⾏⽅法: 移⾏に利⽤した機能 3.無停⽌移⾏の⼿順 17 old new ①リクエスト app ②旧DBのデータ取得 ④差分 ③新DBのデータ取得 ※ 確認している間に新旧の値が書きかわらないよう、 データ取得時に SELECT FOR UPDATE で⾏ロックをとるオプションを⽤意
  12. 公開 © Yahoo Japan 公開 アプリケーション側に以下の機能を実装することで無停⽌移⾏を実現 •並⾏書き込み機能 •新旧差分確認 API •新旧差分マイグレ

    API 差分をなくすための機能 1件ずつ旧の値を新に反映する仕様 移⾏⽅法: 移⾏に利⽤した機能 3.無停⽌移⾏の⼿順 18 old new ①リクエスト app ②旧DBのデータ取得 ④更新できたか ③新DBのデータ更新 ※ マイグレしている間に旧の値が書きかわらないよう、 旧DBのデータ取得時に SELECT FOR UPDATE で⾏ロックをとっている ※ APIのクライアント側に RPS 制限を実装している。 サービス影響のない程度の RPS で利⽤
  13. 公開 © Yahoo Japan 公開 移⾏⼿順 3.無停⽌移⾏の⼿順 19 1. 新DBへのデータコピー

    2. 並⾏書き込み機能リリース 3. 差分⽐較・マイグレーション 4. 全件突合 5. 新DB完全移⾏
  14. 公開 © Yahoo Japan 公開 移⾏⼿順 3.無停⽌移⾏の⼿順 20 1. 新DBへのデータコピー

    2. 並⾏書き込み機能リリース 3. 差分⽐較・マイグレーション 4. 全件突合 5. 新DB完全移⾏ old new app データコピー • Oracle Data Pump を利⽤ • コピーを開始し始めた時点のデータが新DBに挿⼊される(ダンプをとってコピーする) • 旧DB は更新し続けられているので、新旧間の差分は出続けている • この作業は DB チームに依頼
  15. 公開 © Yahoo Japan 公開 移⾏⼿順 3.無停⽌移⾏の⼿順 21 1. 新DBへのデータコピー

    2. 並⾏書き込み機能リリース 3. 差分⽐較・マイグレーション 4. 全件突合 5. 新DB完全移⾏ old new app 新規接続 • 並⾏書き込み機能をリリースし、新規に差分を出さない状態に • 他案件の機能開発のブロックにならないよう、事前に並⾏書き込み機能の修正はリリースし、 Feature Toggle によって機能を有効化するだけ
  16. 公開 © Yahoo Japan 公開 移⾏⼿順 3.無停⽌移⾏の⼿順 22 1. 新DBへのデータコピー

    2. 並⾏書き込み機能リリース 3. 差分⽐較・マイグレーション 4. 全件突合 5. 新DB完全移⾏ • 1の開始時点 ~ 2の終了時点にあった全リクエストから、差分が発⽣している可能性のレコードを特定 • 「新旧差分確認API」を使って、実際に新旧で差分のあったレコードを特定 • 「新旧差分マイグレAPI」を使って、新旧で差分のあったレコードを1件ずつマイグレ • このステップを何度か繰り返す old new app 差分⽐較・マイグレ
  17. 公開 © Yahoo Japan 公開 移⾏⼿順 3.無停⽌移⾏の⼿順 23 1. 新DBへのデータコピー

    2. 並⾏書き込み機能リリース 3. 差分⽐較・マイグレーション 4. 全件突合 5. 新DB完全移⾏ • 夜間に全ての広告の予算・課⾦額で差分が出ていないか確認するジョブを実⾏ • ↑で確認した差分は営業時間にマイグレ • 「課⾦・返⾦ログ」はレコード数が数千万件であり、全件の差分を⽐較することが⾮現実的 =>集計結果の差分を⽐較することで差分がないことを確認 old new app batch 差分⽐較 batch storage ログについては集計結果 の差分を⽐較
  18. 公開 © Yahoo Japan 公開 移⾏⼿順 3.無停⽌移⾏の⼿順 24 1. 新DBへのデータコピー

    2. 並⾏書き込み機能リリース 3. 差分⽐較・マイグレーション 4. 全件突合 5. 新DB完全移⾏ old new app • 旧DBを切り離すリリースを実施 • 「新DBのみ更新するアプリケーション」 (A)と「新旧DBを更新するアプリケーション」(B)が混在 • カナリアリリースのため • 「Aで更新」 -> 「Bで取得」した場合に値の整合性が取れてないケースが存在 • 事前に想定していたため、クライアントに更新リクエストを流し直してもらってリカバリー
  19. 公開 © Yahoo Japan 公開 ⼯夫した点 3.無停⽌移⾏の⼿順 26 •本番を想定したリハーサル •

    本番以上の QPS で取得・更新リクエストを流しつつ、マイグレ • マイグレ⽤の DML でインデックスがうまく使われない事象を発⾒ • 新DBへのデータコピーも本番DBに対してリハーサル(DBチーム) •事前の念密なコミュニケーション • マイグレ中に更新処理のレイテンシが倍になることが問題がないか • 完全移⾏時に更新処理に差分が出る可能性があること • 差分が出た後、リカバリーを依頼できるか
  20. 公開 © Yahoo Japan 公開 終わりに 4.終わりに 28 •課⾦を担うアプリケーション・ビジネス事情などの観点から無停⽌で移⾏を決断 •並⾏書き込み・新旧差分書き込み・新旧差分マイグレ

    機能を実装 API を利⽤するマイグレ⽤ツールも実装 •事前のリハーサル・コミュニケーションで事故なく無停⽌移⾏を実現 • 無停⽌・停⽌に関わらず、移⾏タスクでは他チームに協⼒いただくことが重要