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

2.8K Views

September 27, 23

スライド概要

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

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

profile-image

2023年10月からSpeaker Deckに移行しました。最新情報はこちらをご覧ください。 https://speakerdeck.com/lycorptech_jp

シェア

またはPlayer版

埋め込む »CMSなどでJSが使えない場合

関連スライド

各ページのテキスト
1.

公開 RDB無停⽌移⾏への挑戦 ヤフー株式会社 マーケティングプラットフォーム統括本部 広告開発本部 池⽥ 流弥 2023/09/26 Copyright (C) 2020 Yahoo © Yahoo Japan Japan Corporation. All Rights Reserved.

2.

公開 ⾃⼰紹介 池⽥ 流弥(Ryuya Ikeda) 2020年 ~ ヤフー株式会社 Yahoo!広告 ディスプレイ広告 バックエンドエンジニア GitHub, Twitter などは @rikeda71 © Yahoo Japan 2

3.

公開 アジェンダ 1. 移⾏対象のDBの概要 2. DBを停⽌できない理由 3. 無停⽌移⾏の⼿順 4. 終わりに © Yahoo Japan 3

4.

公開 1. 移⾏対象のDBの概要 © Yahoo Japan 4

5.

公開 1.移⾏対象のDBの概要 Yahoo!広告 ディスプレイ広告とは • Yahoo! JAPANのトップページや広告の掲載枠があるWEB サイトに、画像や動画付きで表⽰できる広告 • 多彩なターゲティングや予算に応じた料⾦設定に対応 • ヤフー社内で⼊稿・配信システムを開発 https://ads-promo.yahoo.co.jp/service/displayads/ より © Yahoo Japan 5

6.

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

7.

公開 1.移⾏対象のDBの概要 移⾏の背景 ソフトウェア・ハードウェアの EOL にともない移⾏が必要に •約5年間運⽤し続けた DB •Oracle12c (12.2.0.1) の EOL • Oracle19c への移⾏が必要に © Yahoo Japan 7

8.

公開 2. DBを停⽌できない理由 © Yahoo Japan 8

9.

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

10.

公開 DB停⽌に伴う影響が⼤きいため、無停⽌で移⾏することに © Yahoo Japan 10

11.

公開 2.DBを停⽌できない理由 移⾏の要件 •サービス無停⽌ • DB だけでなく、DB を利⽤するアプリケーションの機能を⽌めない •サービスに影響のあるデータの差分を発⽣させない • ⾦額を扱う DB であるため、移⾏前 / 後で差分を出すことはできない •利⽤者から⾒た影響が軽微 © Yahoo Japan 11

12.

公開 3. 無停⽌移⾏の⼿順 © Yahoo Japan 12

13.

公開 3.無停⽌移⾏の⼿順 移⾏⽅法: 移⾏に利⽤した機能 アプリケーション側に以下の機能を実装することで無停⽌移⾏を実現 •並⾏書き込み機能 •新旧差分確認 API •新旧差分マイグレ API © Yahoo Japan 13

14.

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

15.

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

16.

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

17.

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

18.

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

19.

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

20.

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

21.

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

22.

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

23.

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

24.

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

25.

公開 これらの⼿順で事故なく無停⽌で移⾏することに成功 © Yahoo Japan 🎉 25

26.

公開 3.無停⽌移⾏の⼿順 ⼯夫した点 •本番を想定したリハーサル 本番以上の QPS で取得・更新リクエストを流しつつ、マイグレ • • マイグレ⽤の DML でインデックスがうまく使われない事象を発⾒ 新DBへのデータコピーも本番DBに対してリハーサル(DBチーム) • •事前の念密なコミュニケーション • マイグレ中に更新処理のレイテンシが倍になることが問題がないか • 完全移⾏時に更新処理に差分が出る可能性があること • 差分が出た後、リカバリーを依頼できるか © Yahoo Japan 26

27.

公開 4. 終わりに © Yahoo Japan 27

28.

公開 4.終わりに 終わりに •課⾦を担うアプリケーション・ビジネス事情などの観点から無停⽌で移⾏を決断 •並⾏書き込み・新旧差分書き込み・新旧差分マイグレ 機能を実装 API を利⽤するマイグレ⽤ツールも実装 •事前のリハーサル・コミュニケーションで事故なく無停⽌移⾏を実現 • 無停⽌・停⽌に関わらず、移⾏タスクでは他チームに協⼒いただくことが重要 © Yahoo Japan 28

29.

公開 © Yahoo Japan