Cells: データ移行

Cells アーキテクチャには、大きな Cell から小さな Cell にデータを移行する手段を提供することが不可欠です。このドキュメントでは、このような分割を行うためのさまざまなアプローチについて説明します。

また、データが Cells の期待する分離制約に既に違反している場合(例えば、参照が複数の Organization をまたぐことができない場合)の処理も必要です。リンクされた Issue のような既存の機能では、ユーザーがプロジェクト階層に関係なく任意のプロジェクト間で Issue をリンクできました。同様の機能が多数あります。これらのデータはすべて、異なる Cell 間で分割または移行できるようになる前に、何らかの方法で移行する必要があります。これは、一部のデータを削除する必要があること、または Organization を Cell 間で適切に分割または移行できるようになる前に、機能を変更して若干異なるモデルにする必要があることを意味する場合があります。

異なる Cell 間でスキーマが異なること(これは異なるデータベースの必然的な結果です)は、Cell 間でデータを移行する能力にも影響します。スキーマが異なると、Cell 間でデータを確実にレプリケートする能力に影響し、特にデータが正しくレプリケートされているかを検証する能力に影響します。すべてのスキーマが同期している場合にのみ Cell 間でデータを移動できるという制約が生じる可能性があり(デプロイメントとリバランスプロセスが遅くなる)、またはより複雑になる可能性のある新しいスキーマから古いスキーマへの移行のみが可能になる場合があります。

1. 定義

2. データフロー

3. 提案

3.1. 大きな Cell を分割する

単一の Cell は多くの Cell にのみ分割できます。これは、既存の Cell の正確なクローンを多数のレプリカとして作成し、移行後にそのうちの一部が権威を持つようにする方が簡単であるという原則に基づいています。これらのレプリカを Cell 0 と最新の状態に保つことも、システム全体をレプリケートできる既存のレプリケーションソリューション(Geo、PostgreSQL 物理レプリケーションなど)によってはるかに容易です。

  1. Organization のすべてのデータは多くの Cell に分割しないことが必要です。
  2. 分割はオンラインで行える必要があります。
  3. 新しい Cell には既存のデータを含めることができません。
  4. N 個の Cell は Cell 0 の正確なレプリカを含みます。
  5. Cell 0 のデータは、分割する必要がある数の Cell にライブレプリケートされます。
  6. Cell 0 と N-Cell 間でコンセンサスが達成されると、移行する Organization はクラスター全体でリードオンリーとしてマークされます。
  7. 分割するすべての Organization の routes が更新され、最新データを保持する権威ある Cell(cell-100gitlab-org など)が示されます。
  8. Cell 0 および非権威的な N-Cell 上の gitlab-org のデータは休止状態になり、将来的に削除されます。
  9. 特定の Cell 上の gitlab-org へのすべてのアクセスは、その Cell がデータを処理する権限を持つことを確認するために routescell_id に対して検証されます。

この提案のさらなる課題

  1. Elasticsearch にはストリーミングレプリケーション機能がありませんが、Elasticsearch インデックス全体のスナップショットを取得して再作成できます。ただし、これには数時間かかります。インデックスのダウンタイムは大きな問題ではないため、移行中に初期 Cell での Elasticsearch インデックスを一時停止することで処理できますが、これも移行プロセスと調整する必要があります。
  2. オンラインシステムで Redis、Gitaly、CI Postgres、メイン Postgres、レジストリ Postgres、その他の新しいデータストアのスナップショットを同期すると、長いダウンタイムなしにギャップが生じる可能性があります。同期ポイントを選択する必要があり、同期ポイントで移行を実行するために書き込みを停止する必要があります。同時に移行するデータストアが多いほど、フェイルオーバーの書き込みダウンタイムが長くなります。また、非同期ワークロードやその他の予期しないコードパスにより、どの Rails プロセスもいつでもこれらのシステムのいずれかに直接書き込む可能性があるため、すべての Rails サービスをシャットダウンすることでのみ自信を持てていたことから、アプリケーション内でこれらすべてのシステムへの更新をブロックする信頼性の高い場所を見つける必要があります。
  3. 孤立したすべてのデータを効率的に削除する方法。半分の Organization に関連するすべての ci_builds を見つけるには、結合を行う必要があり、非常にコストがかかります。すべてのテーブルに organization_id カラムを保存するかどうかはまだ決定していませんが、これはその役に立つ種類のことです。

3.2. 既存の Cell から Organization を移行する

これは分割とは異なり、単一の Organization に属するデータを論理的かつ選択的にレプリケートすることを意図しています。現在、このタイプの選択的レプリケーションは Gitaly のみで実装されており、最小限のダウンタイムで単一の Gitaly ノードから別のノードに Git リポジトリを移行できます。

このモデルでは、データベース行、オブジェクトストレージファイル、Git リポジトリなど、特定の Organization に属するすべてのリソースを特定し、別の(おそらく)既存の Cell にそれらを選択的にコピーしてデータをインポートする必要があります。すべての変更されたデータのライブ論理レプリケーションを実行できるようにし、分割と同様にどの Cell がその Organization の権威を持つかを変更することが理想的です。

  1. Organization に属するすべてのリソースを特定することは困難です。
  2. Organization のダウンタイムまたは行われたライブ変更を特定する堅牢なシステムが必要です。
  3. 選択的な PostgreSQL 論理レプリケーションを実行するために(プロジェクトのインポート/エクスポートよりも堅牢な)完全なデータベース構造分析が必要な可能性があります。

この提案のさらなる課題

  1. 論理レプリケーションは、まだ私たちのスケールに追いつくほどのパフォーマンスを発揮していません。論理レプリケーションを使用できたとしても、organizations テーブルまで結合しなければ単一の Organization に関連するデータをフィルタリングする効率的な方法がなく、論理レプリケーションを大幅に遅延させます。

4. 評価

4.1. メリット

4.2. デメリット