/note/tech

150万レコードを持つ画像テーブルの移行

レコード移行する方法として以下の二つを検討しました。

  • Rakeタスクで旧テーブルから新テーブルにレコードをコピーする。
  • AWS BatchでS3の画像ファイルをコピーし、MySQLで直接レコードをコピーする。

その結果、以下の理由からRakeタスクを採用することを決めました。

  • CarrierWaveを使用することで、レコードコピーと同時に新たなサムネイル画像を準備できる。
  • Railsの機能を活用してレコードを作成するため、モデルバリデーションを適用できる。
  • レコードのコピー速度が遅い場合でも、並行処理によってそれをカバーすることが可能。
  • 検証環境での動作確認が容易。

大まかな流れと解説です。

  • (1) Rakeタスクで引数によりIDを指定し、その範囲の旧テーブルのレコードを取得します。
    • 引数でコピー対象の範囲を指定することで、タスクを並列稼働させることが可能になります。
    • 範囲を指定することでRakeタスクの稼働時間を短縮し、万が一AWSなどで障害が発生した場合でも影響範囲を特定しやすくなります。
  • (2) 旧テーブルのレコード情報をコピーし、その情報を使用して新テーブルのレコードを作成します。
    • CarrierWaveにより画像ファイルがS3にアップロードされます
    • この時点で新しいサムネイル用の画像も同時に生成されます。
  • (3) コピーが完了した旧テーブルのレコードに新テーブルのレコードIDを保存します。
    • 事前に旧テーブルに新しいIDを保存するカラムを追加しておきます。
    • 旧テーブルのレコードを取得する際にコピー済みのレコードを除外することができます。
    • コピー前後のレコードが紐づくため、正しくコピーされたかを検証できます。