データベース101: 実世界でのデータベース間の移行ってどうやってるの?

最近、ScyllaDBでの新しい仕事として、データベース間でデータを移行する方法について勉強しています。以前約束した通り、最新の学びについて皆さんに情報をお伝えしていきます。

もしデータベース一般について、あるいはデータベース移行についてこれから学び始めるとしたら、私の最初の投稿であるデータベース101: 初心者のためのデータ整合性から読み始めるのが良いでしょう。その記事では、SQLとMySQLだけの経験を超えて、どれだけ多くのデータベースパラダイムが存在するかについて私が探求した内容がまとまっています。このデータベース101シリーズで私の学びを追跡していきます。

目次

1. 序章

「データベース環境」での冒険を始めてから、数年かけて答えを出そうとしている疑問がたくさんあります。そのうちの一つは、どのように適切にデータベース移行を行うか、というものですが、まだ答えは出ていません。

実際に私がHe4rt Developers(私がリードするコミュニティ)のボットを移行したときには、バックエンドとデータベースモデルをできるだけ完璧にしようと努力しました。しかし、実際に移行する段になると、本当に大変でした。「ビッグバン」(変更ファイルが532個のプルリクエスト)という移行アプローチを選びましたが、オープンソースのメンテナーとしては悪い決断の一つでした。

その当時は、このトピック(データベース移行)について全く知識がありませんでした。しかし、この記事で皆さんに教えることになる、私が学んだ教訓があります。

2. データベース移行: どう始めるか

データベースから別のデータベースへ適切にデータを移行することを調査するようなタスクを受けたら、コードに関連することを何もする前にいくつかのことを知っておくべきです。それは何を意味するのでしょうか?つまり、ただデータベース間でクエリを投げることから調査を始めるわけではありません。

まず、以下のような質問を自分自身にしてみましょう:

  • 移行の動機は何ですか?
  • 移行アプローチは、プロジェクト上でどのように使用すべきでしょうか?
  • 私たちは一つのパラダイムから別のパラダイムへ移行しますか?
  • 新しいデータベースは、現在使用しているものすべてをサポートしていますか?

これら4つの質問を頭に入れておけば、全てに答えるために調査を続けてから、クエリやコードに手をつけることができます。

3. なぜこの移行をするのか

プロジェクトのスタックの一部を交換するとき、その理由は計画を立てている全チームにとって明確でなければなりません。

では、交換で何を求めていますか?いくつかの可能性があります:

  • I/O操作の遅延を低下させるため;
  • 維持費の安いデータベース;
  • 製品に追いつくためのスケーラブルなデータベース。

データベースを置き換える理由の巨大なリストの中で、これらはほんのいくつかの項目に過ぎないことを覚えておいてくださいね。チームやリーダーから必要なすべての詳細を聞いて、その動機を理解し、それがあなたが探しているものであることを確認してください!

4. 概念実証: どこから始めるか

良いですね!私たちはこれをする理由が明確です。それではこの作業を成功させるために重要なことを見極めましょう。データベースパラダイムの違いを知っていますか?もし二つの異なるデータベース間でデータを移行するなら、これは常に懸念事項でなくてはなりません。どのタイプの概念実証(PoC)を行うか理解しましょう。

4.1 同じパラダイムでの概念実証

以下のシナリオを想像してみましょう。あなたが移行したいと考えているのは:

  • CassandraDBからScyllaDBへ(Wide Column);
  • MySQLからPostgreSQLへ(リレーショナル);
  • MemcacheからRedisへ(キーバリュー);
  • MongoDBからDynamoDBやFirebaseへ(ドキュメント)。

これらのシナリオは、データベースパラダイムが同じであるため、移行が比較的簡単です。つまり、同じアーキテクチャに準拠しています。

ですから、ほとんどの場合、彼らは同じ機能、インデックス、データ型を持っています。多少の違いはあるかもしれませんが、テストをして一つの機能やデータ型から別のものに移行することで対応できることです。

例えばDiscordがCassandraDBからScyllaDBに移行したときでさえ、幾つか修正する必要があったものの、結局のところ異なるパラダイム間で移行するよりも簡単でした。正直言って、PoC中に問題が発生した場合は、それが仕事の一部であることを覚えておいてください。¯\(ツ)

4.2 異なるパラダイムでの概念実証

さて、問題がドキュメントベースのデータベースからWide Columnに移行することだったら、どうでしょう?MongoDBからScyllaDBへのような状況です。

難しい仕事のように思えるかもしれませんし、実際そうかもしれませんが、このパートは特に慎重に設計する必要があります。

Discordが2017年にドキュメントベースのデータベースからWide Columnデータベースに移行を始めた時、彼らも同じ問題を抱えていました。

無限のJSONオブジェクトをどのように分割するか想像できますか?下のJSONの例をチェックしてみてください:

{
  "servers": [
    {
      "218378123781": {
        "id": "218378123781",
        "server_name": "He4rt Developers",
        "channels": [
          {
            "78931278921723": {
              "name": "Test Channel 1",
              "messages": [
                {
                  "312783712867": {
                    "message_id": "312783712867",
                    "chatter_id": "danielhe4rt",
                    "content": "oh hi lol",
                    "created_at": "1691972222",
                    "updated_at": "1691972222"
                  }
                },
                {
                  "312783712867": {
                    "message_id": "312783712867",
                    "chatter_id": "danielhe4rt",
                    "content": "oh hi lol",
                    "created_at": "1691972222",
                    "updated_at": "1691972222"
                  }
                }
              ]
            }
          }
        ]
      }
    }
  ],
  "users": [
    {
      "danielhe4rt": {
        "chatter_id": "danielhe4rt",
        "joined_at": "1691972222"
      }
    },
    {
      "dont_forget_to_follow_me_on_socials": {
        "chatter_id": "dont_forget_to_follow_me_on_socials",
        "joined_at": "1691972222"
      }
    }
  ]
}

これは、DiscordのようなSNSのモデリングを手短に想像しました。ええ、現実とはほど遠いですが、ここでは問題に焦点を当ててくださいね。そして実際に、優秀なDBAとアーキテクトがそばにいれば、問題にはならないでしょう。

まず、チーム全体がパラダイムについてもっと知り、どのように使うかを学ぶ必要があります。ドキュメント指向では、データの整合性があまり厳しくないため、何でも投入できます。しかし、ScyllaDBに移行する場合は、テーブルをモデル化し、実行したいクエリに焦点をあて、「整合性レベル」や「レプリケーションファクター」のようなものの仕組みを理解する必要があります。

最終的にはこんな感じになるでしょう:

CREATE TABLE servers (
    server_id bigint
    owner_id text
    server_name text,
    created_at timestamp,
    PRIMARY KEY (server_id, created_at)
);

CREATE TABLE channels (
    server_id bigint
    channel_id bigint
    channel_name text,
    created_at timestamp
    PRIMARY KEY ((server_id), created_at)
) WITH CLUSTERING ORDER BY (created_at DESC);

CREATE TABLE channel_messages (
    message_id bigint
    channel_id bigint,
    chatter_id text,
    content text,
    created_at timestamp,
    PRIMARY KEY ((message_id, channel_id), created_at)
) WITH CLUSTERING ORDER BY (created_at DESC);

CREATE TABLE users (
    user_id text,
    user_name text,
    created_at timestamp,
    PRIMARY KEY (user_id, created_at)
);

はい、CQL(Cassandra Query Language)はSQL(Structured Query Language)にとても似ています。このScyllaDB: NoSQL 101 Essentialsコースを受けてみることをお勧めします。Wide Columnパラダイムについて多くの興味深いことを学べるでしょう :D

5. テスト: 後悔する前に!(本当に)

OK、PoCを実施し、どのデータベースとパラダイムが私たちの新しい環境に最適かを知りました。今やチームはデータモデリングをできるだけ早く終了させることに集中していますね。それが終わったら、成功する移行に向けて全てのスクリプトを準備することになるでしょう。

できる最善の事は、ステージング環境でデータベースの1%および5%でテストを分割することです。なぜか? "新しいシステム" または "システムの新しいバージョン" が1%のデータベースでクラッシュした場合、それはデータモデリングに何かが欠けているか、バックエンドで問題があることを反映します。したがって、移行スクリプトを停止して、アプリケーションのテストを書きましょう。

1%の移行バグが解決したら、同じプロセスをデータベースの5%で繰り返しましょう。このステップでは、最終テストステップになるため、すべてのものを慎重にテストする必要があります。

6. 移行戦略

もちろん、データベース間の移行は「新しい」ことではないので、より簡単にするための計画があります。また、一緒にあなたのデータベース移行をプロのように見せるルールもあります。

この点に関して、「ホット移行」と「コールド移行」という二つの非常に人気のある戦略があります。これらの戦略の名前自体が、この調査の

こちらの記事はdev.toの良い記事を日本人向けに翻訳しています。
https://dev.to/danielhe4rt/database-101-how-does-migration-between-databases-work-in-the-real-world-24dn