データ移行プロジェクトで得た学び

ここ1ヶ月半ほどとあるデータ移行プロジェクトに携わっていた。

データ移行プロジェクトは初めてで難しかったがなんとか一段落することができたので、今回のデータ移行のむずかしポイントと乗り越えるためにやったことを記録しておく。

何をやったか

とある別サービス  S _ {origin} で定期課金中のユーザー数万人を自社のサービス  S _ {dest} に移行してきて課金状態を引き継ぐというのがプロジェクトのゴールだった。

つまり、 S _ {origin} を利用しているユーザーは何も操作しなくても移行日以降に  S _ {dest} でログインすると定期課金状態になっていることを目指している。

むずかしポイント

  • 課金状態を引き継ぐために移行時に課金をする必要があり、失敗するとユーザーに不利益が生じる
  • 初めて触るところ & 移行プロジェクトが初めて

むずかしポイントを乗り越えるために

課金状態を引き継ぐために移行時に課金をする必要があり、失敗するとユーザーに不利益が生じる

課金という性質上、同じユーザーに対する移行の二重実行を避ける必要がある。 さらに、移行後にユーザーからのお問い合わせで調査が必要になるかもしれない。

そこで、移行用の一時テーブルを用意することにした。 移行の処理をステップごとに分けて、ステップごとに成功 or 失敗を記録していき、ステップごとに埋めたいデータをテーブルに持つようにした。

そして、二重実行を避けるために状態遷移図に従うような処理しかできないように制御した。

状態遷移図

今回はお問い合わせを見越して各ステップごとのログが重要となると考えたので更新していくのではなくて追記していく方式にした。

また、エラーによってはリトライすれば治るもの(通信時エラーなど)もあればリトライしても治らないもの(クレジットカードの有効期限切れなど)がある。 そこで、エラーコードを細かく分けて記録することで調査をしやすくしたり、治る見込みのあるものだけをリトライできるようにした。

移行テーブルを作っておくことで並列処理がしやすくなるというメリットもあった。 あるユーザーが複数の定期課金をしていた場合に同時に移行されると想定しない問題が発生する可能性があった。 移行自体はユーザーと定期課金の商品の組み合わせごとに行うので、移行テーブルでユーザー単位でロックを取ることで1ユーザーの複数の定期課金が同時に移行されることを防ぎながら並列処理が可能になった。

エラーに倒れるようにするほうがいい。 本来エラーになるべきデータが正常に移行されるのは困る。 バリデーションを頑張る & 意図した条件でなければエラー とすることでエラーに倒すことはできる。 移行当日にエラーに対処することにはなるが異常なデータが移行されるよりはまし、ということで頑張る。

テストはやっぱり重要。 データ移行に限った話ではないけど1回きりのスクリプトだからといってテストなしだったらきっと破滅していた。 今回は特に課金ということもあって検証できる機会が少なかったので、その分テストでエッジケースをしっかり確認できたのは良かったと思う。

関係者の少ない検証環境もあるとよい。 関係者が少ないとデプロイしないでとか操作しないでとお願いすることができる。 今回はこの環境を使ってさらに安全目には倒しながら一時的に検証環境から課金サービスの本番につなげることで検証を行った。

初めて触るところ & 移行プロジェクトが初めて

今回のプロジェクトに携わるまで課金周りを触ったことがなかったのと移行プロジェクト自体が初めてだった。

当初のアサインではこの移行プロジェクトと別のプロジェクトを並行して進めるということになっていたが、明らかに厳しくてこういう状況で困っていますとか慣れていないので不安ですというエントリを社内に書いていたら移行プロジェクトの専任にさせてもらえて、ヘルプの体制を組んでもらえた。 このとき声を上げていなかったらプロジェクト後半で破滅していたかもしれない。

プロジェクトを進めるにあたってはとにかく記録を残していった。 やろうとしていること、やったこと、困っていることを記録していると相談もしやすいので便利。

タスク管理はちゃんとしたほうがいい。 ちゃんとするというのは、タスクの期日を入れて見積もりポイントを振って依存関係をつけるということ。 見積もりポイントが入っていたらバーンアップチャートが見れるので今のベロシティでは間に合わないので助けてください! と説得材料になる。 依存関係をつけているとこのタスクは依存がないので別の人にお願いできるなとか判断しやすくなる。

手順書は作ったほうがいい。 特に深夜作業なら頭が働かない前提で手順書は書いたほうがいい。 つまり、何をやるのか・期待される結果は何なのか・このエラーの場合にはどう対処するか を手順に盛り込む。 やることと期待される結果はペアで書いたほうが手順書としては見やすくなるのでオススメ。

事前に移行作業のタイムラインを考えて問題ないかを脳内シミュレーションするといい。 理想的には何時に終わるのか、エラー対処などを含めて落ち着けるようになるのは何時かなどを考える。 移行プロジェクトは関係者が多いはずなので、各関係者に必要な確認が漏れていないかを確認するのが重要。

dry run は実装したほうがいい。 コマンドを実行する前に何件実行されるのかを出すぐらいでも事故は防ぎやすくなると思う。

振り返り

移行プロジェクトは3人以上は必要

移行プロジェクトは別サービスを運用している会社などとの連携が必要になり関係者は自社に閉じている場合と比較して多くなる。 なので関係者とのコミュニケーションや仕様のすり合わせなどを行う人が1人は必要になる。

となると実装するエンジニアの人数は? となるけど2人以上じゃないと難しいんじゃないかと思う。 別サービスで運用されていたデータを自社のサービスに持ってくるのは特殊な対応が必要になることが多く、エッジケースが多い。 1人でエッジケースを全部カバーするのは自社のサービスを完全理解していないと難しい。 また特殊な対応をするために工数はどんどん増えていくので1人じゃ捌ききれなくなってくると実感した。