DMM.comの、一番深くておもしろいトコロ。

DMMにおけるユーザーレビュー基盤の変革(AWS DMSを使ったクラウドへのデータ移行/レプリケーション編)

DMMにおけるユーザーレビュー基盤の変革(AWS DMSを使ったクラウドへのデータ移行/レプリケーション編)

  • このエントリーをはてなブックマークに追加

はじめに

はじめましてプラットフォーム事業本部の富田です。 普段はサイト内の回遊率の向上施策や、ユーザの購買意思決定のサポートになるサービスの開発、運用を担当しています。

さて、ユーザーレビュー基盤では現在リプレイスを進めております。システムをオンプレからクラウドへ移行させる際、大きな障害になりがちなのがDBなどのデータ移行だと思います。 そこで今回は、弊チームがオンプレからクラウドにデータを移行させるまでのプロセスを実作業をもとにご紹介できればと思います。 ※ 今回の事例では、オンプレのMySQLからRDS for MySQLへの移行をもとに記述します。

なお、過去のユーザーレビュー基盤の変革シリーズは以下のリンクよりご覧いただけます! inside.dmm.com

この記事におけるデータ移行って何?

データ移行とは、サービスや機能をオンプレからパブリッククラウドへ移行するにあたり、DBのデータもクラウドで用意するDBに移す作業です。 DBがオンプレにあっても問題はないですが、疎通や相性など諸々含めると一緒にパブリッククラウドに移してしまったほうが将来的に楽できると思います。 何も考慮せずデータを移行させるだけなら簡単なのですが、ユーザ影響を考えるとざっくりと下記項目くらいは考慮、検討する必要があります。

  • ユーザ影響
    • ダウンタイムの発生
    • データの整合性の担保
    • データ損失のリスク
  • システム影響
    • サーバへの負荷
    • 失敗した場合の切り戻し

AWSにおけるデータ移行の選択肢

データ移行では、起きうる障害を最小にするためにプロダクトにあった移行手段を選択することが非常に重要です。 AWSでは、大きく分けると下記の2通りの方法が存在します。

それぞれの概要とメリット・デメリットを挙げて行きましょう。

DBエンジンの公式移行手段を使用する

mysqldumpなどでスキーマ情報とデータをdumpし、移行先のDBに流し込みコマンドでレプリケーションを取る方法です。

AWSが一般的になる前からよく使われている手法で、資料が多く実績も多い。 同じDBエンジン間(MySQLからMySQL)の場合、基本的にはこちらを推奨しています。

  • メリット
    • レプリケーションインスタンスを作らないので障害発生点が減る
    • 同じデータベースプラットフォームの場合、こちらの方がスタンダード
    • 実績多数
  • デメリット
    • dumpしてデータを移行する性質上、どうしてもDBを止めるか書き込みを制限するタイミングが発生してしまう
    • 何かあったときロールバックやデータの差異の修正が大変
    • 異なったデータベースプラットフォームへの移行は難しい
    • dumpするために権限をもらうか、権限がある人にファイルをもらう調整が必要
    • 分割実行した場合の制御が大変

データ移行イメージ

f:id:tommy_39:20190805131146j:plain

DMSを使用する

AWSにあるデータベースのデータ移行とレプリケーションサービス。

正式名称は、AWS Database Migration Service。

移行中も移行元DBを止める必要がなく、異なったデータベースプラットフォーム間での移行もサポートされてます。 サポートされてるプラットフォームや細かい機能は挙げ出すとキリがないので公式リファレンスを参照ください。

データ移行元と移行先の間にレプリケーションインスタンスを設置することで双方への影響をなるべく排除しデータを移行できます。 レプリケーションインスタンスを立てることで異種間でのデータ移行やデータの加工を可能としています。

DMSでできること

あげればキリがないので、大きな特徴の部分を列挙します。

  • スキーマの移行
    • オンプレのスキーマ情報をAWSのDBにコピーできる
    • 完全にコピーされる保証はないのでmysqldumpなどを推奨
  • データの移行
    • オンプレのDBに格納されているデータをAWSのDBにコピーできる
    • 一部のテーブルデータは移さないなどの設定も可能
  • データ移行後の変更の追跡
    • データの移行が終わった後に変更を追うことができるので、そのままレプリケーションを貼ることができる
    • 1つの機能でデータ移行とレプリケーションの両方を実現できる
    • 移行後も変更に追従してくれるので、切替も切戻しもローリスク
  • 最小のダウンタイムでのデータ移行
    • レプリケーションインスタンスを挟んでのデータ移行なので、オンプレの機能を制限する必要がない
  • 異種間(OracleからMySQLなど)のDB移行のサポート
    • レプリケーションインスタンスを挟んでのデータ移行なので、中間インスタンスでいい感じにできる

メリット・デメリット

  • メリット
    • 移行元DBへの制限を最小にできる
    • データ移行とレプリケーションが1つの機能でできる
    • 異なったデータベースプラットフォーム間での移行もサポートされてる
  • デメリット
    • サポートされてないDB固有のデータ型があり必ずできるとは言えない
    • レプリケーションインスタンスを立てる性質上、障害点が増えてしまう

データ移行イメージ

f:id:tommy_39:20190805131116j:plain

弊チームが選択した移行方法

弊チームのプロダクトでは、下記理由によりスキーマコピーとレプリケーションはMySQLの機能で行い、データ移行はDMSで行いました。

スキーマとレプリケーションをMySQLの機能にした理由

  • エンジンがMyISAMのスキーマがあって定義の変更が、不可能だったがDMSでスキーマを移行するとInnoDBに再構築されてしまった -> AWSではMyISAM未対応なので仕方ないね
  • DMSのレプリケーションには対応してない型があった -> 各環境に依存するのでテーブル設計が対応してるか確認が必要

DMSでデータ移行を行った理由

  • 本番DBの権限の問題で自由にデータをdumpできない
    • 弊社では、サーバを管理するインフラ部の方が本番環境の権限を持っており各チームにはプロダクト運用のために必要な権限しか付与されていない
  • 移行作業の際になるべく他事業部に影響を与えたくない
    • インフラ部の方に日程調整や作業をお願いするのは、申し訳ない
    • 万が一失敗したとき、速やかに対応したい
  • 本番サーバへの負荷を考えてデータ全部dumpするのは避けたい

データ移行イメージ

f:id:tommy_39:20190805131232j:plain

意識するポイントがあります

DMSは、とても便利ですが、ハマりポイントというか意識するポイントがいろいろとあります。 弊チームでは、検証中に下記問題にハマりました。

  • AuroraやRDS for MySQLでは、MyISAMはサポートしてない

    • サポートしてないのでMyISAMで作られたテーブルがある場合、DMSでスキーマ情報をコピーすると全てInnoDBで構築される
    • InnoDBで構築されてもいいなら、DMSで行うと勝手にエンジンがInnoDBになって構築されるので手間が省けるかもしれません
  • DMSでは、サポートされてない型がある

    • スキーマやカラムの型次第では、DMSでサポートされておらず使えない可能性がある
    • サポートされている型一覧はこちら
  • AWSのRDSには、replicate-ignore-db設定がない

    • ignore設定がないので全てのDBをレプリケーションしない場合、binlogに吐き出すDBを指定するなどの設定が必要
  • データ移行ではサポートされてるけどレプリケーションではサポートされてない型などがある

    • データ移行では問題なかったけどレプリケーションを貼るとうまくいかない場合があるので、どこまでできてどこを他の機能に任せるかの判断が必要
  • セカンダリインデックス、非プライマリーキー制約、デフォルト値などはサポートしてないので、移行先に自分で作る必要がある

実作業手順とコマンド

  1. 事前準備
    • mysqldumpでスキーマ情報を取得
    • 移行元にレプリケーション用のユーザを作成
      • SELECT, REPLICATION SLAVE, REPLICATION CLIENT, LOCK TABLES権限を付与
  2. dumpしたスキーマ情報をもとに移行先DBにテーブルを作成

    $ mysql -h 移行先DBHost -u ユーザ -p 移行先DB名 < dumpしたsqlファイル

  3. 書き込み導線をメンテナンス画面に & reviewDBの書き込みを制限(読み込みは可能) 書き込みを制限したいテーブルにREADロックを掛け、書き込みを制限する

    mysql > LOCK TABLE ロックしたいテーブル名 READ, ... ;

  4. 移行元のマイグレーション開始位置の確認とメモ。 データ移行後、MySQLコマンドでレプリケーションを貼るので開始位置を確認

    mysql > show master status;

  5. DMSでデータ移行

    1. レプリケーションインスタンスを置くサブネット作成 f:id:tommy_39:20190726125546p:plain

    2. レプリケーションインスタンス作成 f:id:tommy_39:20190726171307p:plain

    3. エンドポイント作成

      • ソースデータベース = オンプレDB <- レプリケーションインスタンス の疎通

      f:id:tommy_39:20190726180535p:plain

      • ターゲットデータベース = レプリケーションインスタンス -> AWSのDB の疎通

      f:id:tommy_39:20190726180547p:plain

    4. タスク作成 & データ移行開始

      • タスクの設定 f:id:tommy_39:20190726182941p:plain

      • データ移行時の設定 f:id:tommy_39:20190726182951p:plain

  6. データ移行が完了したらレプリケーション設定 & 確認

    レプリケーションはストアドプロシージャを使う

   $ mysql -h 移行先DBHost -u ユーザ -p 

   # レプリケーション設定
   mysql > CALL mysql.rds_set_external_master ('オンプレHost',3306,'レプリケーションユーザ名','パスワード','確認したbinlogファイル名',確認したbinlogのポジション,0);
  
   # レプリケーションスタート
   mysql > CALL mysql.rds_start_replication;

   # レプリケーションにエラーがないことを確認
   mysql >  SHOW SLAVE STATUS\G

まとめ

DMSはとても便利で、すごい機能ですが自分たちのプロダクト次第でできる範囲が変わってきます。
どこまでできるかは実際に試さないとわからない部分があるので、まずはそこを試してみるといいと思います。
MyISAMを使ってる場合、AWSと相性が悪いので、後々でもいいのでスキーマ情報の再定義を行いましょう。
AWSへの移行は、どこまでをどの機能で行うかが難しいが、自分のプロダクトにあった運用を。

最後に

私の所属するプラットフォーム事業本部 Customer Decision Support Teamでは、一緒に働いてくれる仲間を探しています。 それぞれの得意分野を活かしながら、みんなでフロントエンドからインフラまでフルスタックを目指しているチームです。 少しでもご興味のある方はぜひご応募ください!

https://dmm-corp.com/recruit/347