Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
10年続くサービスのデータを1日未満のメンテナンスウィンドウで安全に移管する
Search
masawada
October 15, 2024
5
2.1k
10年続くサービスのデータを1日未満のメンテナンスウィンドウで安全に移管する
Hatena Engineer Seminar #31 「少年ジャンプ+」 サーバーサイド編 - connpass
masawada
October 15, 2024
Tweet
Share
More Decks by masawada
See All by masawada
よりよいレビュー環境を求めて / A code review odyssey
masawada
0
2.9k
フロントエンドの秩序は保たれているか?
masawada
1
4.1k
Getting Started with ScratchX
masawada
0
670
GyaPC::Asia Tokyo 2015 LT
masawada
0
1.4k
Privileged Apps with Vue.js
masawada
0
160
Chikubeam
masawada
1
1.5k
Git講習 2014.04.15
masawada
1
310
Hack U at UEC 2014.03.27
masawada
0
1.5k
Firefox OS勉強会 4th Untitled
masawada
0
1.3k
Featured
See All Featured
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
47
5.1k
The Cult of Friendly URLs
andyhume
78
6.1k
Art, The Web, and Tiny UX
lynnandtonic
298
20k
A better future with KSS
kneath
238
17k
Designing Experiences People Love
moore
138
23k
What's in a price? How to price your products and services
michaelherold
243
12k
[RailsConf 2023 Opening Keynote] The Magic of Rails
eileencodes
28
9.1k
Designing for Performance
lara
604
68k
RailsConf 2023
tenderlove
29
940
Bootstrapping a Software Product
garrettdimon
PRO
305
110k
Product Roadmaps are Hard
iamctodd
PRO
49
11k
KATA
mclloyd
29
14k
Transcript
10年続くサービスのデータを 1日未満のメンテナンスウィンドウで 安全に移管する 2024-10-15 Hatena Engineer Seminar #31 「少年ジャンプ+」 サーバーサイド編
id:masawada / id:momochi29 1
2
長時間メンテナンスで実施したこと • 他社システムからGigaViewerへのデータ移行 • 動作確認 • GigaViewer for Apps版 少年ジャンプ+の配信
3
このセッションのテーマ • 他社システムからGigaViewerへのデータ移行 • 動作確認 • GigaViewer for Apps版 少年ジャンプ+の配信
4
このセッションのテーマ • 素朴に実施すると数週間かかる移行を、どう 1日未満のメンテナンスウィンドウに収めたか • 巨大なシステムのデータ移行を実施するに あたってのテクニックや心構え 5
自己紹介 id:masawada • データ移行のリード • 全般的な設計から 渉外までなんでも担当 • マンガメディア開発の チーム歴は5年程度
• 「ふつうの軽音部」 が好きすぎる 6
二部構成 • 少年ジャンプ+のデータ移行事情 ◦ id:masawada • 移行の自動検証について ◦ id:momochi29 7
少年ジャンプ +の データ移行事情 8
データ移行は総合格闘技 9
データ移行は総合格闘技 • 旧システムのデータを新システムに横流しする ◦ ではない • モデリングの違いを理解して翻訳する作業 10
データ移行は総合格闘技 • 旧システムのデータを新システムに横流しする ◦ ではない • モデリングの違いを理解して翻訳する作業 ◦ だけでもない 11
データ移行は総合格闘技 要求の整理 設計 費用見積もり キャパシティプランニン グ 実装 検証 パフォーマンスチューニング スケジュール
の検討 リハーサル走行 本番走行 移行後対応 などなど… 30分では話せない! 12
今日話すこと • 少年ジャンプ+のデータ移行に対する要求 • どのような実装で実現したか • うまくやるには 13
少年ジャンプ +の データ移行に対する要求 14
他社システムとGigaViewerの関係 • 他社システム(旧システム) ◦ 旧少年ジャンプ+ アプリ版のバックエンド ◦ 2014年9月22日にサービスイン • GigaViewer(新システム)
◦ もともと少年ジャンプ+ Web版を配信 ◦ 2017年1月18日にサービスイン 15
他社システムとGigaViewerの関係 • もともと以下データを同期していた ◦ 雑誌・話の原稿やメタデータ ◦ ユーザアカウント情報 ◦ ユーザの定期購読情報 ◦
ユーザが購入した雑誌の情報 16
他社システムとGigaViewerの関係 • それぞれのシステムで管理していたデータの例 ◦ 話のレンタル履歴 ◦ 話をレンタルするためのコイン ◦ 閲覧履歴 ◦
コメント ◦ などなど 17
移行するデータの特徴 • とにかくデータが多い ◦ 当初想定では、ほぼ最強のAuroraインスタンスの リソースを使い切って数週間かかる見込み • メンテナンス直前まで書き込みが発生する ◦ 支配的なデータはユーザの閲覧履歴・コインなど
◦ マンガを読む機能も課金も止められない 18
移行プロジェクトに対する要求 • メンテナンスウィンドウは1日未満 ◦ 日毎に連載があるため • 移行元の機能ロックは実質不可能 ◦ 支配的なデータは止められないため 19
どうするか • ユーザのデータだけをまず移行することに ◦ 原稿やメタデータは旧システムに入稿して同期 ◦ 別途移行プロジェクトを立ち上げる • とはいえこれで減らせる量は少ない…… 20
どのような実装で 実現したか 21
必要なデータを オンラインで少しずつ移行 22
分割移行 • 旧システムのDBスナップショットをいただいて復元 • 特定の時刻範囲に作成・更新されたデータを移行 ◦ を繰り返す 23
分割移行 スナップショット 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
分割移行 • Step Functions + AWS Batchを採用 ◦ 「魔法のiらんど」のデータ移行でも実績がある ◦
詳しくは: Hatena Engineer Seminar #14* • Step Functionsで依存関係を管理しつつ実行 * https://speakerdeck.com/tkzwtks/hatena-engineer-seminer-number-14-data-migration 25
分割移行 26 { “since”: “2014-01-01T00:00:00+09:00”, “until”: “2024-01-01T00:00:00+09:00” } 引数(時刻範囲) 移行システム
旧システムDB 新システムDB 変換して挿入・更新 時刻範囲のデータを取得
分割移行 • 少しずつ移行する期間を詰めていって、最後は メンテナンス当日に移行 ◦ 例: 2014年から5年分, 次の3年分, 1年分... ◦
サービス成長に伴って単位時間あたりのデータ量 が増えていく 27
分割移行 • 期間を詰めるほど移行時間が短くなる、ではない ◦ Fargateの立ち上げオーバーヘッドだったり ◦ 中間状態を管理するためのS3の読み書きだったり ◦ どこかで頭打ちになる •
メンテナンス前の最後の分割移行はちょうどよい 塩梅を狙ってタイミングを設定 28
うまくいくのか? • データの依存関係を丁寧になぞれば可能 ◦ 2014-01-01〜2015-01-01のユーザアカウント ◦ 2014-01-01〜2015-01-01のコイン ◦ 2014-01-01〜2015-01-01の読み物購入情報 ▪
購入情報にはどのコインで買ったか記録される ◦ 関連がないデータは並行で移行可能 29
うまくいくのか? • 実装をミスると容易に整合性が破壊される ◦ 練習用の環境で走行したら実際に壊れた ▪ データの更新に失敗したり ▪ 更新すべきところで新規に挿入してしまったり ◦
自動検証を仕込むことに ▪ この話は後ほど 30
分割移行を実現するために必要な条件 • 移行元に作成日と更新日が仕込まれていること • 移行元にレコードを物理削除する処理がないこと 31
分割移行を実現するために必要な条件 • 移行元に作成日と更新日が仕込まれていること • 更新日だけではダメなケース ▪ ユーザの最終更新は2024-02-01 ▪ コインの最終更新は2023-01-01 ▪
移行範囲は2023-12-31いっぱい ▪ →更新日だけでは依存ユーザが作られない! 32
分割移行を実現するために必要な条件 • 移行元にレコードを物理削除する処理がないこと ◦ とはいえ、ありますよね • あった場合は? 33
移行元に物理削除があったら • 移行元で物理削除を記録してもらう ◦ triggerなりアプリケーションで仕込むなり • 移行先に移行ログをとっておく ◦ どのテーブルのどのidがどこに移行されたか •
移行処理の最初に消す ◦ 削除ログがある=元のデータは既にない 34
移行ログは便利 • あとから何をどう移行したか調査しやすい • 依存するデータがあるときはここから引ける • 処理をべき等にするためにも利用できる • INSERTするレコード数が単純計算で2倍にはなるが 35
ところで…… • 素朴にオンラインのまま分割移行すると 移行先のDBにユーザのデータが増える • ユーザにデータが見えるのでは……? 36
オンラインのまま移行す るテクニックふたつ 37
分ける・隠す 38
分ける • もともとなかった機能に対しての移行ならユーザに 見えない • 一見同じ機能でも新機能扱いにしてしまう手 39
分ける • ユーザの利便性を損わないとかビジネス上問題が ないとかで判断されるべきではある • 例: Web用コインとアプリ用コインを分ける ◦ (移行都合ではなく、新システムにおける扱いを 検討する際にたまたま分けていた)
◦ 今回は移行都合で意図的に分けた例はない 40
隠す • 素直にやるならこっち ◦ フラグを立ててリリースまで隠す • 例: レンタル状態はWebとアプリで統合したい ◦ レンタル状態のテーブルにフラグのカラムを追加
◦ リリースまではWebでアプリのものを表示しない 41
…という方針を 立てるためには? 42
うまくやるには 43
うまくやるには • 最初から理想に至るのは無理 • どうする? ◦ 仕様を読み込む ◦ 本番データの傾向を観察する ◦
イテレーションを回す 44
仕様を読み込む • 移行の処理自体はモデリングを翻訳する作業 • 元の処理がどうなっているか分からないと困る ◦ 今回は仕様書とデータ一式をいただいた • 仕様だけじゃなく実際にアプリを触るのも重要 ◦
ユーザが触れる面の全てを把握しておく ◦ ユーザ=エンドユーザに限らず運用者なども含む 45
本番データの傾向を観察する • どうあがいても例外的なデータは発生する ◦ 運用上発生したり ◦ 不具合への対応だったり • 例外的なデータは仕様や開発データを見ていても 気付けない
46
本番データの傾向を観察する • 気付けない例: ◦ 仕様にはないけどNullableでNULLが入っている ◦ idが指し示す先のデータがない • どう移行されるのが正しいのか? を考えるためには
データを見つつ仕様を読み込む必要がある ◦ 考古学 47
イテレーションを回す • 未完成でもとにかくイテレーションを回す • 1回実行してうまくいくことは絶対にない ◦ なんなら時間の見積もりですら実装やデータの 状況によって変わっていく • エラーを1回で出し切れることも絶対にない
◦ エラーを潰すと依存していた処理でエラーが発生 48
イテレーションを回す • イテレーションを回しやすくする ◦ 全量の移行を実施すると時間がかかりすぎる ◦ 一部ユーザだけ移行して動作確認しやすいような 仕組みを導入 49
イテレーションを回す • イテレーションを回す障害を取り除く ◦ Step Functionsは一箇所で異常終了すると ステートマシン全体が止まる ◦ 例外的なデータでいちいち止めていたら処理が 一生終わらない
50
イテレーションを回す • イテレーションを回す障害を取り除く ◦ 1イテレーションの中ではエラーがあっても途中 で止めずに最後にエラーが起きたかどうか判断 ◦ 個別の処理ではエラーを記録するだけにしつつ エラーがなかったように振る舞う 51
ということを意識して 移行の仕組みを作ると よいのでは 52
ここまでのまとめ • 分割移行でメンテナンスウィンドウを短くした ◦ 19時間のメンテナンスのうちデータ移行は6時間 • オンラインのまま移行するためのテクニック ◦ データを分ける・隠す •
うまくやるためには ◦ 結局は泥臭く・丁寧にやる、以上のことはない 53