10年続くサービスのデータを1日未満のメンテナンスウィンドウで安全に移管する
by
masawada
Link
Embed
Share
Beginning
This slide
Copy link URL
Copy link URL
Copy iframe embed code
Copy iframe embed code
Copy javascript embed code
Copy javascript embed code
Share
Tweet
Share
Tweet
Slide 1
Slide 1 text
10年続くサービスのデータを 1日未満のメンテナンスウィンドウで 安全に移管する 2024-10-15 Hatena Engineer Seminar #31 「少年ジャンプ+」 サーバーサイド編 id:masawada / id:momochi29 1
Slide 2
Slide 2 text
2
Slide 3
Slide 3 text
長時間メンテナンスで実施したこと ● 他社システムからGigaViewerへのデータ移行 ● 動作確認 ● GigaViewer for Apps版 少年ジャンプ+の配信 3
Slide 4
Slide 4 text
このセッションのテーマ ● 他社システムからGigaViewerへのデータ移行 ● 動作確認 ● GigaViewer for Apps版 少年ジャンプ+の配信 4
Slide 5
Slide 5 text
このセッションのテーマ ● 素朴に実施すると数週間かかる移行を、どう 1日未満のメンテナンスウィンドウに収めたか ● 巨大なシステムのデータ移行を実施するに あたってのテクニックや心構え 5
Slide 6
Slide 6 text
自己紹介 id:masawada ● データ移行のリード ● 全般的な設計から 渉外までなんでも担当 ● マンガメディア開発の チーム歴は5年程度 ● 「ふつうの軽音部」 が好きすぎる 6
Slide 7
Slide 7 text
二部構成 ● 少年ジャンプ+のデータ移行事情 ○ id:masawada ● 移行の自動検証について ○ id:momochi29 7
Slide 8
Slide 8 text
少年ジャンプ +の データ移行事情 8
Slide 9
Slide 9 text
データ移行は総合格闘技 9
Slide 10
Slide 10 text
データ移行は総合格闘技 ● 旧システムのデータを新システムに横流しする ○ ではない ● モデリングの違いを理解して翻訳する作業 10
Slide 11
Slide 11 text
データ移行は総合格闘技 ● 旧システムのデータを新システムに横流しする ○ ではない ● モデリングの違いを理解して翻訳する作業 ○ だけでもない 11
Slide 12
Slide 12 text
データ移行は総合格闘技 要求の整理 設計 費用見積もり キャパシティプランニン グ 実装 検証 パフォーマンスチューニング スケジュール の検討 リハーサル走行 本番走行 移行後対応 などなど… 30分では話せない! 12
Slide 13
Slide 13 text
今日話すこと ● 少年ジャンプ+のデータ移行に対する要求 ● どのような実装で実現したか ● うまくやるには 13
Slide 14
Slide 14 text
少年ジャンプ +の データ移行に対する要求 14
Slide 15
Slide 15 text
他社システムとGigaViewerの関係 ● 他社システム(旧システム) ○ 旧少年ジャンプ+ アプリ版のバックエンド ○ 2014年9月22日にサービスイン ● GigaViewer(新システム) ○ もともと少年ジャンプ+ Web版を配信 ○ 2017年1月18日にサービスイン 15
Slide 16
Slide 16 text
他社システムとGigaViewerの関係 ● もともと以下データを同期していた ○ 雑誌・話の原稿やメタデータ ○ ユーザアカウント情報 ○ ユーザの定期購読情報 ○ ユーザが購入した雑誌の情報 16
Slide 17
Slide 17 text
他社システムとGigaViewerの関係 ● それぞれのシステムで管理していたデータの例 ○ 話のレンタル履歴 ○ 話をレンタルするためのコイン ○ 閲覧履歴 ○ コメント ○ などなど 17
Slide 18
Slide 18 text
移行するデータの特徴 ● とにかくデータが多い ○ 当初想定では、ほぼ最強のAuroraインスタンスの リソースを使い切って数週間かかる見込み ● メンテナンス直前まで書き込みが発生する ○ 支配的なデータはユーザの閲覧履歴・コインなど ○ マンガを読む機能も課金も止められない 18
Slide 19
Slide 19 text
移行プロジェクトに対する要求 ● メンテナンスウィンドウは1日未満 ○ 日毎に連載があるため ● 移行元の機能ロックは実質不可能 ○ 支配的なデータは止められないため 19
Slide 20
Slide 20 text
どうするか ● ユーザのデータだけをまず移行することに ○ 原稿やメタデータは旧システムに入稿して同期 ○ 別途移行プロジェクトを立ち上げる ● とはいえこれで減らせる量は少ない…… 20
Slide 21
Slide 21 text
どのような実装で 実現したか 21
Slide 22
Slide 22 text
必要なデータを オンラインで少しずつ移行 22
Slide 23
Slide 23 text
分割移行 ● 旧システムのDBスナップショットをいただいて復元 ● 特定の時刻範囲に作成・更新されたデータを移行 ○ を繰り返す 23
Slide 24
Slide 24 text
分割移行 スナップショット 2024/2/1 スナップショット 2024/3/1 2014/1/1 2024/1/1 2014/1/1 2024/1/1 1回目の移行 移行済 2024/2/1 2024/2/1 2回目の移行 2024/3/1 24
Slide 25
Slide 25 text
分割移行 ● Step Functions + AWS Batchを採用 ○ 「魔法のiらんど」のデータ移行でも実績がある ○ 詳しくは: Hatena Engineer Seminar #14* ● Step Functionsで依存関係を管理しつつ実行 * https://speakerdeck.com/tkzwtks/hatena-engineer-seminer-number-14-data-migration 25
Slide 26
Slide 26 text
分割移行 26 { “since”: “2014-01-01T00:00:00+09:00”, “until”: “2024-01-01T00:00:00+09:00” } 引数(時刻範囲) 移行システム 旧システムDB 新システムDB 変換して挿入・更新 時刻範囲のデータを取得
Slide 27
Slide 27 text
分割移行 ● 少しずつ移行する期間を詰めていって、最後は メンテナンス当日に移行 ○ 例: 2014年から5年分, 次の3年分, 1年分... ○ サービス成長に伴って単位時間あたりのデータ量 が増えていく 27
Slide 28
Slide 28 text
分割移行 ● 期間を詰めるほど移行時間が短くなる、ではない ○ Fargateの立ち上げオーバーヘッドだったり ○ 中間状態を管理するためのS3の読み書きだったり ○ どこかで頭打ちになる ● メンテナンス前の最後の分割移行はちょうどよい 塩梅を狙ってタイミングを設定 28
Slide 29
Slide 29 text
うまくいくのか? ● データの依存関係を丁寧になぞれば可能 ○ 2014-01-01〜2015-01-01のユーザアカウント ○ 2014-01-01〜2015-01-01のコイン ○ 2014-01-01〜2015-01-01の読み物購入情報 ■ 購入情報にはどのコインで買ったか記録される ○ 関連がないデータは並行で移行可能 29
Slide 30
Slide 30 text
うまくいくのか? ● 実装をミスると容易に整合性が破壊される ○ 練習用の環境で走行したら実際に壊れた ■ データの更新に失敗したり ■ 更新すべきところで新規に挿入してしまったり ○ 自動検証を仕込むことに ■ この話は後ほど 30
Slide 31
Slide 31 text
分割移行を実現するために必要な条件 ● 移行元に作成日と更新日が仕込まれていること ● 移行元にレコードを物理削除する処理がないこと 31
Slide 32
Slide 32 text
分割移行を実現するために必要な条件 ● 移行元に作成日と更新日が仕込まれていること ● 更新日だけではダメなケース ■ ユーザの最終更新は2024-02-01 ■ コインの最終更新は2023-01-01 ■ 移行範囲は2023-12-31いっぱい ■ →更新日だけでは依存ユーザが作られない! 32
Slide 33
Slide 33 text
分割移行を実現するために必要な条件 ● 移行元にレコードを物理削除する処理がないこと ○ とはいえ、ありますよね ● あった場合は? 33
Slide 34
Slide 34 text
移行元に物理削除があったら ● 移行元で物理削除を記録してもらう ○ triggerなりアプリケーションで仕込むなり ● 移行先に移行ログをとっておく ○ どのテーブルのどのidがどこに移行されたか ● 移行処理の最初に消す ○ 削除ログがある=元のデータは既にない 34
Slide 35
Slide 35 text
移行ログは便利 ● あとから何をどう移行したか調査しやすい ● 依存するデータがあるときはここから引ける ● 処理をべき等にするためにも利用できる ● INSERTするレコード数が単純計算で2倍にはなるが 35
Slide 36
Slide 36 text
ところで…… ● 素朴にオンラインのまま分割移行すると 移行先のDBにユーザのデータが増える ● ユーザにデータが見えるのでは……? 36
Slide 37
Slide 37 text
オンラインのまま移行す るテクニックふたつ 37
Slide 38
Slide 38 text
分ける・隠す 38
Slide 39
Slide 39 text
分ける ● もともとなかった機能に対しての移行ならユーザに 見えない ● 一見同じ機能でも新機能扱いにしてしまう手 39
Slide 40
Slide 40 text
分ける ● ユーザの利便性を損わないとかビジネス上問題が ないとかで判断されるべきではある ● 例: Web用コインとアプリ用コインを分ける ○ (移行都合ではなく、新システムにおける扱いを 検討する際にたまたま分けていた) ○ 今回は移行都合で意図的に分けた例はない 40
Slide 41
Slide 41 text
隠す ● 素直にやるならこっち ○ フラグを立ててリリースまで隠す ● 例: レンタル状態はWebとアプリで統合したい ○ レンタル状態のテーブルにフラグのカラムを追加 ○ リリースまではWebでアプリのものを表示しない 41
Slide 42
Slide 42 text
…という方針を 立てるためには? 42
Slide 43
Slide 43 text
うまくやるには 43
Slide 44
Slide 44 text
うまくやるには ● 最初から理想に至るのは無理 ● どうする? ○ 仕様を読み込む ○ 本番データの傾向を観察する ○ イテレーションを回す 44
Slide 45
Slide 45 text
仕様を読み込む ● 移行の処理自体はモデリングを翻訳する作業 ● 元の処理がどうなっているか分からないと困る ○ 今回は仕様書とデータ一式をいただいた ● 仕様だけじゃなく実際にアプリを触るのも重要 ○ ユーザが触れる面の全てを把握しておく ○ ユーザ=エンドユーザに限らず運用者なども含む 45
Slide 46
Slide 46 text
本番データの傾向を観察する ● どうあがいても例外的なデータは発生する ○ 運用上発生したり ○ 不具合への対応だったり ● 例外的なデータは仕様や開発データを見ていても 気付けない 46
Slide 47
Slide 47 text
本番データの傾向を観察する ● 気付けない例: ○ 仕様にはないけどNullableでNULLが入っている ○ idが指し示す先のデータがない ● どう移行されるのが正しいのか? を考えるためには データを見つつ仕様を読み込む必要がある ○ 考古学 47
Slide 48
Slide 48 text
イテレーションを回す ● 未完成でもとにかくイテレーションを回す ● 1回実行してうまくいくことは絶対にない ○ なんなら時間の見積もりですら実装やデータの 状況によって変わっていく ● エラーを1回で出し切れることも絶対にない ○ エラーを潰すと依存していた処理でエラーが発生 48
Slide 49
Slide 49 text
イテレーションを回す ● イテレーションを回しやすくする ○ 全量の移行を実施すると時間がかかりすぎる ○ 一部ユーザだけ移行して動作確認しやすいような 仕組みを導入 49
Slide 50
Slide 50 text
イテレーションを回す ● イテレーションを回す障害を取り除く ○ Step Functionsは一箇所で異常終了すると ステートマシン全体が止まる ○ 例外的なデータでいちいち止めていたら処理が 一生終わらない 50
Slide 51
Slide 51 text
イテレーションを回す ● イテレーションを回す障害を取り除く ○ 1イテレーションの中ではエラーがあっても途中 で止めずに最後にエラーが起きたかどうか判断 ○ 個別の処理ではエラーを記録するだけにしつつ エラーがなかったように振る舞う 51
Slide 52
Slide 52 text
ということを意識して 移行の仕組みを作ると よいのでは 52
Slide 53
Slide 53 text
ここまでのまとめ ● 分割移行でメンテナンスウィンドウを短くした ○ 19時間のメンテナンスのうちデータ移行は6時間 ● オンラインのまま移行するためのテクニック ○ データを分ける・隠す ● うまくやるためには ○ 結局は泥臭く・丁寧にやる、以上のことはない 53