Geo (開発)

GeoはGitLabインスタンス同士を接続します。1つのGitLabインスタンスがプライマリサイトとして指定され、複数のセカンダリサイトで実行することができます。Geoは以下の図にあるような多くのコンポーネントをオーケストレーションします。

Geo Architecture Diagram

レプリケーションレイヤー

Geo はさまざまなコンポーネントのレプリケーションを処理します:

  • データベース:キャッシュとジョブを除くアプリケーション全体を含みます。
  • Git リポジトリ: プロジェクトと Wiki の両方を含みます。
  • Blobs:イシューに添付された画像から、CIの生のログやアセットまで含まれます。

セカンダリサイトでは、データベースのレプリケーションを除いて、すべてがGeo Log Cursor によって調整されます。

レプリケーションの状態

以下の図は、レプリケーションがどのように機能するかを示しています。わかりやすくするため、一部の遷移は省略しています。

stateDiagram-v2 Pending --> Started Started --> Synced Started --> Failed Synced --> Pending: Mark for resync Failed --> Pending: Mark for resync Failed --> Started: Retry

Geo Log Cursor デーモン

Geo Log Cursor デーモンは各セカンダリーサイトで実行される個別のプロセスです。Geo イベントログの新しいイベントを監視し、特定のイベントタイプごとにバックグラウンドジョブを作成します。

例えば、リポジトリが更新されると、Geoプライマリサイトはリポジトリ更新イベントに関連する Geo イベントを作成します。Geo Log Cursor デーモンはそのイベントをピックアップし、Geo::RepositorySyncService を使ってリポジトリを更新するGeo::ProjectSyncWorker ジョブをスケジュールします。

Geo Log Cursor デーモンは自動的に高可用性モードでオペレーションできます。デーモンは時々ロックの取得を試み、一度取得するとアクティブデーモンとして動作します。

アクティブデーモンがそのロックをリリースした場合、同じサイト上で実行中の追加デーモンはスタンバイモードで、作業を再開する準備ができています。

プーリング・サイクルごとに更新される小さな TTL を持つExclusiveLease ロック・タイプを使用します。これにより、タイムアウト付きのグローバル・ロックを実装することができます。

プーリング・サイクルの終わりに、デーモンがロックを更新または再取得できない場合、スタンバイ・モードに切り替わります。

データベースのレプリケーション

Geo では、プライマリサイトから セカンダリサイトへのデータベースのレプリケーションにストリーミングレプリケーションを使用しています。このレプリケーションにより、セカンダリサイトはデータベースに保存されたすべてのデータにアクセスできるため、ユーザーはセカンダリサイトにサインインして、たとえばすべてのイシューやマージリクエストを読むことができます。

リポジトリのレプリケーション

Geo はリポジトリも複製します。各セカンダリサイトは追跡データベース内のすべてのリポジトリの状態を追跡します。

リポジトリが複製される方法はいくつかあります:

プロジェクトレジストリ

Geo::ProjectRegistry クラスは、リポジトリの複製状態を追跡するためのモデルを定義します。メインデータベースの各プロジェクトに対して、追跡データベースのレコードが1つ保持されます。

リポジトリについて、以下のことを記録します:

  • 最後に同期された時間。
  • 最後に同期に成功した時間。
  • 再同期が必要な場合。
  • 再試行が必要な場合。
  • 再試行回数。
  • いつ検証されたか。

プロジェクトWikiのこれらの属性も専用のカラムに保存されます。

リポジトリ同期ワーカー

Geo::RepositorySyncWorker クラスはバックグラウンドで定期的に実行され、更新が必要なプロジェクトをGeo::ProjectRegistry モデルから探します。これらのプロジェクトは次のようなものです:

  • 同期されていないプロジェクト:セカンダリ・サイトで同期されたことがなく、まだ存在していないプロジェクト。
  • 最近更新されたもの:Geo::ProjectRegistry モデルのlast_repository_successful_sync_at タイムスタンプよりも新しいlast_repository_updated_at タイムスタンプを持つプロジェクト。
  • 手動:管理者はGeo 管理エリアで手動でリポジトリに再同期のフラグを立てることができます。

セカンダリRETRIES_BEFORE_REDOWNLOAD でリポジトリの取得に失敗した場合、Geo はいわゆる_再ダウンロードを_行います。ストレージのルートにある@geo-temporary ディレクトリにクリーンなクローンを行います。これが成功すると、メインのリポジトリを新しくクローンされたリポジトリに置き換えます。

ブロブレプリケーション

アップロード、LFSオブジェクト、CIジョブのアーティファクトなどのブロブは、セルフサービスフレームワークでセカンダリサイトにレプリケートされます。同期の状態を追跡するために、各モデルには対応するレジストリテーブルがあります。例えば、UploadPostgreSQL Geo Tracking DatabaseGeo::UploadRegistry があります。

サービス間のブロブレプリケーションハッピーパス・ワークフロー

ジョブ・アーティファクトは、ブロブの一例として以下の図で使用されています。

新しいジョブアーティファクトの複製

プライマリサイト

sequenceDiagram participant R as Runner participant P as Puma participant DB as PostgreSQL participant SsP as Secondary site PostgreSQL R->>P: Upload artifact P->>DB: Insert `ci_job_artifacts` row P->>DB: Insert `geo_events` row P->>DB: Insert `geo_event_log` row DB->>SsP: Replicate rows
  • アーティファクトをアップロードするRunner
  • Pumaが ci_job_artifacts 行を挿入します。
  • Pumaはgeo_events 、”ID 123のアーティファクトが更新されました “というようなデータを含む行を挿入します。
  • Pumaはgeo_events 行を指すgeo_event_log 行を挿入します(レガシーロジックの上にSSFを構築したため)。
  • PostgreSQLのストリーミングレプリケーションは読み込みレプリカに行を挿入します。

セカンダリサイトに行を挿入します:

sequenceDiagram participant DB as PostgreSQL participant GLC as Geo Log Cursor participant R as Redis participant S as Sidekiq participant TDB as PostgreSQL Tracking DB participant PP as Primary site Puma GLC->>DB: Query `geo_event_log` GLC->>DB: Query `geo_events` GLC->>R: Enqueue `Geo::EventWorker` S->>R: Pick up `Geo::EventWorker` S->>TDB: Insert to `job_artifact_registry`, "starting sync" S->>PP: GET <primary site internal URL>/geo/retrieve/job_artifact/123 S->>TDB: Update `job_artifact_registry`, "synced"
  • Geo Log Cursorループが新しいgeo_event_log 行を検出。
  • Geo Log Cursor がgeo_events の行を処理。
    • Geo Log Cursor はgeo_events 行のデータを通過するGeo::EventWorker ジョブをエンキュー。
  • Sidekiqが Geo::EventWorker ジョブをピックアップ。
    • SidekiqはPostgreSQL Geo Tracking Databaseに job_artifact_registry 、行が存在しないため挿入し、”同期開始 “とマーク。
    • SidekiqはプライマリGeoサイトのAPIエンドポイントでGETリクエストを行い、ファイルをダウンロードします。
    • Sidekiq はjob_artifact_registry の行を “同期中” および “検証待ち” としてマークします。
既存のジョブのアーティファクトの埋め戻し
  • シスアドはGeoのない既存のGitLabサイトを持っています。
  • 既存の CI ジョブとジョブのアーティファクトがあること
  • シスアドが新しい GitLab サイトをセットアップし、セカンダリ Geo サイトに設定

セカンダリサイト

Geo::Secondary::RegistryConsistencyWorkerGeo::RegistrySyncWorker 。以下のワークフローはこの2つに分かれています。

sequenceDiagram participant SC as Sidekiq-cron participant R as Redis participant S as Sidekiq participant DB as PostgreSQL participant TDB as PostgreSQL Tracking DB SC->>R: Enqueue `Geo::Secondary::RegistryConsistencyWorker` S->>R: Pick up `Geo::Secondary::RegistryConsistencyWorker` S->>DB: Query `ci_job_artifacts` S->>TDB: Query `job_artifact_registry` S->>TDB: Insert to `job_artifact_registry`
  • Sidekiq-cronは毎分Geo::Secondary::RegistryConsistencyWorker のジョブをエンキューします。このジョブがアクティブに作業(行の作成と削除)を行っている限り、このジョブは即座に自分自身を再エンキューします。このジョブは、複数のインスタンスが同時に実行されないように排他リースを使用します。
  • Sidekiqは Geo::Secondary::RegistryConsistencyWorker ジョブをピックアップします。
    • Sidekiqがci_job_artifacts テーブルに最大10000行までクエリ。
    • Sidekiqがjob_artifact_registry テーブルに最大10000行までクエリ。
    • Sidekiqは既存のジョブアーティファクトに対応するjob_artifact_registry 行をPostgreSQL Geo Tracking Databaseに挿入します。
sequenceDiagram participant SC as Sidekiq-cron participant R as Redis participant S as Sidekiq participant DB as PostgreSQL participant TDB as PostgreSQL Tracking DB participant PP as Primary site Puma SC->>R: Enqueue `Geo::RegistrySyncWorker` S->>R: Pick up `Geo::RegistrySyncWorker` S->>TDB: Query `*_registry` tables S->>R: Enqueue `Geo::EventWorker`s S->>R: Pick up `Geo::EventWorker` S->>TDB: Insert to `job_artifact_registry`, "starting sync" S->>PP: GET <primary site internal URL>/geo/retrieve/job_artifact/123 S->>TDB: Update `job_artifact_registry`, "synced"
  • Sidekiq-cronは1分ごとにGeo::RegistrySyncWorker ジョブをエンキューします。このジョブがアクティビティを行っている限り、同期ジョブのスケジューリングは最大1時間ループします。このジョブは、複数のインスタンスが同時に実行されないように排他リースを使用します。
  • Sidekiqは Geo::RegistrySyncWorker ジョブをピックアップします。
    • Sidekiqは、PostgreSQL Geo Tracking Databaseのすべてのテーブル(registry )に、「同期を試みたことがない」行をクエリします。各テーブルの行をインターリーブし、メモリ内のキューに追加します。
    • 前のステップで1000行未満だった場合、Sidekiqはすべてのregistry テーブルに「同期に失敗し、再試行する準備ができた」行をクエリし、それらをインターリーブしてメモリ内キューに追加します。
    • Sidekiqは、キュー内の各項目について「ID 123のジョブ・アーティファクトが更新されました」のような引数を持つGeo::EventWorker ジョブをエンキューし、エンキューされたSidekiqジョブIDを追跡します。
    • Sidekiqは、「最大同時実行数制限」設定に達すると、Geo::EventWorker ジョブのキューイングを停止します。
    • Sidekiqはこのような作業を、やることがなくなるまでループします。
  • SidekiqはGeo::EventWorker のジョブをピックアップします。
    • Sidekiqはjob_artifact_registry の行を “同期開始 “としてマークします。
    • SidekiqはプライマリGeoサイトのAPIエンドポイントでGETリクエストを行い、ファイルをダウンロードします。
    • Sidekiq はjob_artifact_registry の行を “同期中” および “検証待ち” としてマークします。
新しいジョブのアーティファクトの検証

プライマリサイト

sequenceDiagram participant Ru as Runner participant P as Puma participant DB as PostgreSQL participant SC as Sidekiq-cron participant Rd as Redis participant S as Sidekiq participant F as Filesystem Ru->>P: Upload artifact P->>DB: Insert `ci_job_artifacts` P->>DB: Insert `ci_job_artifact_states` SC->>Rd: Enqueue `Geo::VerificationCronWorker` S->>Rd: Pick up `Geo::VerificationCronWorker` S->>DB: Query `ci_job_artifact_states` S->>Rd: Enqueue `Geo::VerificationBatchWorker` S->>Rd: Pick up `Geo::VerificationBatchWorker` S->>DB: Query `ci_job_artifact_states` S->>DB: Update `ci_job_artifact_states` row, "started" S->>F: Checksum file S->>DB: Update `ci_job_artifact_states` row, "succeeded"
  • アーティファクトをアップロードするRunner
  • Pumaが ci_job_artifacts
  • Puma は検証状態を保存するためにci_job_artifact_states 行を作成します。
    • この行は “pending verification” とマークされます。
  • Sidekiq-cronは毎分Geo::VerificationCronWorker のジョブをエンキューします。
  • Sidekiqは Geo::VerificationCronWorker のジョブをピックアップします。
    • Sidekiqは “pending verification “または “failed verification and ready to retry “と表示された行数をci_job_artifact_states
    • Sidekiqは、”最大検証同時実行数 “設定によって制限された1つ以上のGeo::VerificationBatchWorker ジョブをエンキューします。
  • SidekiqはGeo::VerificationBatchWorker ジョブをピックアップします。
    • Sidekiqは “pending verification “と表示された行についてci_job_artifact_states
    • 前のステップで10行未満しか得られなかった場合、Sidekiqは “検証に失敗し、再試行可能 “とマークされた行についてci_job_artifact_states
    • 各行に対して
      • Sidekiqは “検証開始 “をマークします。
      • SidekiqはファイルのSHA256チェックサムを取得します。
      • Sidekiqはチェックサムを行に保存し、”検証に成功しました “とマークします。
      • セカンダリGeoサイトはこのチェックサムと比較することができます。

セカンダリサイト

sequenceDiagram participant SC as Sidekiq-cron participant R as Redis participant S as Sidekiq participant TDB as PostgreSQL Tracking DB participant F as Filesystem participant DB as PostgreSQL SC->>R: Enqueue `Geo::VerificationCronWorker` S->>R: Pick up `Geo::VerificationCronWorker` S->>TDB: Query `job_artifact_registry` S->>R: Enqueue `Geo::VerificationBatchWorker` S->>R: Pick up `Geo::VerificationBatchWorker` S->>TDB: Query `job_artifact_registry` S->>TDB: Update `job_artifact_registry` row, "started" S->>F: Checksum file S->>DB: Query `ci_job_artifact_states` S->>TDB: Update `job_artifact_registry` row, "succeeded"
  • アーティファクトが正常に同期されると、”検証待ち “になります。
  • Sidekiq-cronは毎分Geo::VerificationCronWorker のジョブをエンキューします。
  • Sidekiqは Geo::VerificationCronWorker のジョブをピックアップします。
    • SidekiqがPostgreSQL Geo Tracking Databaseの job_artifact_registry 、”pending verification “または “failed verification and ready to retry “と表示された行数をクエリ。
    • Sidekiqは、”最大検証同時実行数 “設定によって制限された1つ以上のGeo::VerificationBatchWorker ジョブをエンキューします。
  • SidekiqはGeo::VerificationBatchWorker ジョブをピックアップします。
    • SidekiqがPostgreSQL Geo Tracking Databaseのjob_artifact_registry 、”pending verification “とマークされた行をクエリ。
    • 前のステップの結果が10行未満の場合、Sidekiqは “検証に失敗し、再試行する準備ができている “とマークされた行についてjob_artifact_registry
    • 各行に対して
      • Sidekiqは “検証開始 “をマークします。
      • SidekiqはファイルのSHA256チェックサムを取得します。
      • Sidekiqはチェックサムを行に保存します。
      • SidekiqはチェックサムをPostgreSQLによってレプリケートされたci_job_artifact_states 行のチェックサムと比較します。
      • チェックサムが一致した場合、Sidekiqはjob_artifact_registry の行を “検証に成功 “とマークします。

認証

ファイル転送を認証するため、GeoNode の各レコードには2つのフィールドがあります:

  • 公開アクセス・キー (access_key フィールド)。
  • シークレットアクセスキー (secret_access_key フィールド)。

セカンダリサイトは JWT リクエストで自身を認証します。セカンダリサイトがファイルをダウンロードしたい場合、Authorization ヘッダを持つ HTTP リクエストを送信します:

Authorization: GL-Geo <access_key>:<JWT payload>

プライマリサイトは access_key フィールドを使用して対応するセカンダリサイトを検索し、ファイル要求を識別するための追加情報を含む JWT ペイロードを復号化します。これにより、セカンダリサイトが正しいデータベースIDの正しいファイルをダウンロードすることが保証されます。たとえば、LFSオブジェクトの場合、リクエストにはファイルのSHA256合計も含まれる必要があります。JWTペイロードの例は次のようになります:

{"data": {sha256: "31806bb23580caab78040f8c45d329f5016b0115"}, iat: "1234567890"}

要求されたファイルが要求された SHA256 和と一致する場合、GeoプライマリサイトはX-Sendfile機能を介してデータを送信し、NGINX は Rails や Workhorse に負荷をかけることなくファイル転送を処理します。

note
JWT は関係するマシン間でクロックが同期されている必要があり、そうでない場合は暗号化エラーで失敗する可能性があります。

GeoセカンダリーへのGitプッシュ

Git Push Proxy はgitlab-shell コンポーネントの内部に組み込まれた機能として存在します。セカンダリサイトでのみアクティビティを行います。セカンダリサイトからリポジトリをクローンしたユーザーが同じ URL にプッシュできるようにします。

セカンダリサイトに向けられた Gitpush リクエストはプライマリサイトに送られ、pull リクエストはセカンダリサイトで処理されます。

HTTPS リクエストと SSH リクエストの扱いは異なります:

  • HTTPS では、プライマリサイトのプロジェクトを指すHTTP 302 Redirect をユーザーに渡します。Git クライアントはそのステータスコードを理解し、リダイレクトを処理します。
  • SSH の場合はリダイレクトに相当する方法がないので、リクエストをプロキシする必要があります。これはgitlab-shell の内部で行われます。まずリクエストをHTTPプロトコルに変換し、それをプライマリサイトにプロキシします。

gitlab-shell デーモンは、/api/v4/allowed からの応答に基づいて、いつプロキシするか知っています。特別なHTTP 300 ステータスコードが返され、応答ボディで指定された「カスタムアクション」を実行します。レスポンスには、プロキシされたpush のオペレーションをプライマリサイトで実行するための追加データが含まれています。

トラッキングデータベースの使用

複製されたメインデータベースと共に、Geoセカンダリサイトは独自の独立したTracking データベースを持っています。

トラッキングデータベースには、セカンダリサイトの状態が含まれています。

アップグレードの一環として実行する必要があるデータベースマイグレーションは、各セカンダリサイトのトラッキングデータベースに適用する必要があります。

設定

データベースの設定はconfig/database.ymlにあります。ee/db/geo ディレクトリには、このデータベースのスキーマとマイグレーションがあります。

このデータベースのマイグレーションを書くには、次のコマンドを実行します:

rails g migration [args] [options] --database geo

Geo はgitlab_geo スキーマがサポートされるまでGitlab::Database::Migration[1.0] を使い続ける必要があり、当面はGitlab::Database::Migration[2.0]による検証が免除されます。この場合、マイグレーションデフォルトが 2.0 であるため、開発者が手動でマイグレーションファイルを修正し、[2.0] から[1.0] に変更する必要があります。

詳細については、マイグレーション[2.0]を使用するためにGeoマイグレーションを有効にするイシューを参照してください。

トラッキングデータベースをマイグレーションするには、以下を実行してください:

bundle exec rake db:migrate:geo

ファインダー

Geoはファインダーを使用しています。ファインダーは、トラッキングデータベースとメインデータベースで、プロジェクトや添付ファイルなどを検索する力仕事を引き受けてくれるクラスです。

Redis

セカンダリサイトのRedisは、プライマリサイトと同じように動作します。キャッシュ、セッションの保存、その他の永続的なデータの保存に使用されます。

プライマリサイトと セカンダリサイト間のRedisデータレプリケーションは使用されないため、セッションなどはサイト間で共有されません。

オブジェクトストレージ

GitLabはオプションでオブジェクトストレージを使い、ディスクに保存するデータを保存することができます。例えば

  • LFS オブジェクト
  • CI ジョブ アーティファクト
  • アップロードファイル

デフォルトでは、Geo はオブジェクトストレージに保存されているオブジェクトを複製しません。お客様の状況やニーズに応じて、複製することができます:

検証

検証状態

以下の図は、検証の仕組みを示しています。わかりやすくするため、一部の遷移は省略しています。

stateDiagram-v2 Pending --> Started Pending --> Disabled: No primary checksum Disabled --> Started: Primary checksum succeeded Started --> Succeeded Started --> Failed Succeeded --> Pending: Mark for reverify Failed --> Pending: Mark for reverify Failed --> Started: Retry

リポジトリの検証

リポジトリはチェックサムで検証されます。

プライマリサイトはリポジトリのチェックサムを計算します。基本的には、すべての Git 参照をハッシュし、そのハッシュをデータベースのproject_repository_states テーブルに保存します。

セカンダリサイトも同様にクローンのハッシュを計算し、プライマリサイトが計算した値と比較します。もし不一致があれば、Geo はこれを不一致としてマークし、管理者はGeo 管理エリアでこれを見ることができます。

Geo プロキシ機能

Geo セカンダリはウェブリクエストをプライマリにプロキシします。詳しくはGeo プロキシ (開発者向け) のページを読んでください。

用語解説

プライマリサイト

プライマリサイトは、読み書き機能を持つ Geo セットアップ内の単一のサイトです。これは真実の単一ソースであり、Geoセカンダリサイトはそこからデータを複製します。

Geo セットアップでは、プライマリサイトは 1 つしか存在できません。すべてのセカンダリサイトはそのプライマリサイトに接続します。

セカンダリサイト

セカンダリ・サイトは、地理的に異なる場所で実行されるプライマリ・サイトの読み取り専用のレプリカです。

ストリーミング・レプリケーション

Geo は PostgreSQL のストリーミングレプリケーション機能に依存しています。これはデータベースデータとデータベーススキーマを完全に複製します。データベースのレプリカは読み取り専用です。

ストリーミングレプリケーションはWrite Ahead Logs(WAL)に依存します。これらのログはレプリカにコピーされ、そこで再生されます。

ストリーミングレプリケーションはスキーマもレプリケートするので、データベースのマイグレーションはセカンダリサイトで実行する必要はありません。

データベースの追跡

各 Geoセカンダリサイトにあるデータベースで、それが存在するサイトの状態を保持します。詳しくはUsing the Tracking database をご覧ください。

Geo イベントログ

Geoprimarygeo_event_log テーブルにイベントを保存します。ログの各エントリには、特定のタイプのイベントが含まれます。これらのタイプのイベントには以下が含まれます:

  • リポジトリ削除イベント
  • リポジトリ 名前変更 イベント
  • リポジトリ変更イベント
  • リポジトリ作成イベント
  • ハッシュドストレージマイグレーションイベント
  • LFSオブジェクト削除イベント
  • ハッシュ化されたストレージ・アタッチメント・イベント
  • ジョブアーティファクト削除イベント
  • 削除イベントのアップロード

Geo Log Cursor デーモンを参照してください。

コード機能

Gitlab::Geo ユーティリティ

Geoに関連する小さなユーティリティメソッドは、ee/lib/gitlab/geo.rb ファイルに入ります。

これらのメソッドの多くは、RequestStore クラスを使用してキャッシュされ、コードベース全体でメソッドを使用する際のパフォーマンスへの影響を軽減しています。

現在のサイト

クラスメソッド.current_node は、現在のサイトのGeoNode レコードを返します。

gitlab.yml からhostportrelative_url_root の値を使用し、データベース内を検索して、どのサイトにいるのかを特定します (GeoNode.current_node を参照)。

一次または二次

現在のサイトがプライマリ・サイトか セカンダリ・サイトかを判断するには、.primary? および.secondary? クラス・メソッドを使用します。

これらのメソッドは、サイトが有効化されていない場合、サイト上で両方ともfalse を返すことが可能です。有効化」を参照してください。

Geo データベースは設定されていますか?

また、初期化時に発生する問題に対処する際に、さらに厄介なことがあります。いくつかの場所では、Gitlab::Geo.geo_database_configured? メソッドを使って、セカンダリサイトにしか存在しないトラッキングデータベースがサイトにあるかどうかをチェックしています。これは新しいサイトのブートストラップ中に起こりうるレースコンディションを克服するものです。

有効化

ユーザーがその機能を含む有効なライセンスを持っており、Geo Nodes 画面で少なくとも 1 つのサイトを定義している場合、Geo 機能が有効であるとみなします。

Gitlab::Geo.enabled?Gitlab::Geo.license_allows? メソッドを参照してください。

読み取り専用

Geoセカンダリサイトはすべて読み取り専用です。

読み取り専用データベースの一般原則は、すべての Geoセカンダリーサイトに適用されます。そのため、Gitlab::Database.read_only? メソッドは常にセカンダリサイトで true を返します。

サイトがセカンダリであるためにいくつかの書き込みアクションが許可されていない場合、Gitlab::Geo.secondary? の代わりにGitlab::Database.read_only? またはGitlab::Database.read_write? ガードを追加することを検討してください。

複製されたセットアップでは、データベース自体はすでに読み取り専用になっているので、そのために余計な手順を踏む必要はありません。

新機能のGeoサポートの確保

Geo はメインデータベースと CI データベースの PostgreSQL レプリケーションに依存しているため、新しいテーブルやフィールドを追加した場合、セカンダリの Geo サイトですでに動作するはずです。

しかし、メインおよび CI PostgreSQL データベース以外に保存される新しい種類のデータを導入する場合は、そのデータが Geo によって複製および検証されるようにする必要があります。これは、お客様がディザスタリカバリにおいてセカンダリサイトを信頼できるようにするために必要なことです。

以下のサブセクションでは、作業が必要かどうかを判断する方法と、作業が必要な場合の進め方について説明します。ご不明な点がございましたら、Geo チームまでお問い合わせください。

自分の機能との比較については、サポートされている Geo データタイプを参照してください。Geo が複製および検証するデータタイプの詳細な最新リストがあります。

Gitリポジトリ

Git リポジトリに支えられた機能を追加する場合は、Geo サポートを追加する必要があります。Geo セルフサービスフレームワークのリポジトリリプリケーター戦略をご覧ください。

Geo Replicate a new blob type テンプレートに基づいてイシューを作成し、ガイドラインに従ってください。

ブロブ

CarrierWave::Uploader::Base のサブクラスを追加する場合、Geo がブロブと呼ぶものを追加することになります。一般的に推奨されている](uploads/working_with_uploads.md#recommendations)のように、[AttachmentUploader を特にサブクラス化した場合、そのデータには何の作業も必要なく Geo サポートがあります。これは、AttachmentUploaderuploads テーブルを使用してUpload モデルでブロブを追跡しており、そのモデルに Geo サポートがすでに実装されているためです。

GitLab.comスケールで数百万行を想定しているなどの理由で、新しいテーブルでblobを追跡する場合は、Geoサポートを追加する必要があります。Geo セルフサービスフレームワークの blob レプリケーター戦略を参照してください。

Geoは、Uploader に対応するReplicator がない場合に失敗する仕様で新しい blob を検出します。

Geo Replicate a new Git repository type テンプレートに基づいてイシューを作成し、ガイドラインに従ってください。

複数の種類のデータを持つ機能

新しい複雑な機能が複数の種類のデータ、例えば Git リポジトリと blob によって支えられている場合、それぞれの種類のデータを別々に検討することができるでしょう。

Designs を例にとると、各イシューには Git リポジトリがあり、そのリポジトリには多くの LFS オブジェクトが存在します。

  • LFSオブジェクトはすでにGeoでサポートされていたので、Geo特有の作業は必要ありませんでした。
  • サムネイルの実装はUpload モデルを再利用したので、Geo 固有の作業は必要ありませんでした。
  • デザイン Git リポジトリは Geo では本質的にサポートされていなかったので、作業が必要でした。

別の例として、依存プロキシは DependencyProxy::BlobDependencyProxy::Manifest という2種類のブロブに支えられています。Geoセルフサービスフレームワークのブロブレプリケーター戦略は、それぞれのタイプで、互いに独立して使うことができます。

その他のデータ

新しい機能によって、Gitリポジトリやブロブ、あるいはその2つの組み合わせではない新しい種類のデータが導入される場合は、Geoチームに連絡してその扱い方を相談してください。

例として、コンテナレジストリデータは上記のカテゴリーには当てはまりません。データを所有するレジストリサービスによってバックアップされており、GitLabはレジストリサービスのAPIとやり取りします。そのため、コンテナレジストリのGeoサポートにはワンオフのアプローチが必要です。それでも、Geoセルフサービスフレームワークのグルーコードの多くを再利用することができます。

通信チャネルの歴史

コミュニケーション・チャンネルは最初の反復から変化してきました。ここで歴史的な決定と新しい実装に移行した理由を確認することができます。

カスタムコード (GitLab 8.6 以前)

GitLab 8.6以前のバージョンでは、プライマリサイトから セカンダリサイトへのHTTPリクエストによる通知を処理するためにカスタムコードを使用しています。

システムフック(GitLab 8.7 から 9.5)

その後、カスタムコードから離れ、システムフックを使い始めることになりました。より多くの人がシステムフックを使うようになり、この通信レイヤーの改善によって多くの人が恩恵を受けるようになりました。

私たちのAPIコード(Grape)には、このシステムフックからのすべてのリクエストを受け取る特定の内部エンドポイントがあります:/api/v4/geo/receive_events

各イベントをevent_name フィールドで切り替えてフィルタリングします。

Geo ログカーソル (GitLab 10.0 以上)

GitLab 10.0 以降では、System Webhookは使われなくなり、代わりにGeo LogCursor が使われます。Log Cursor はGeo::EventLog の行をトラバースして、前回ログをチェックした時からの変更があるかどうかを確認し、リポジトリの更新、削除、変更、名前の変更を処理します。

テーブルは複製されたデータベース内にあります。これには、以前の方法に比べて2つの利点があります:

  • レプリケーションは同期的であり、イベントの順序を保持します。
  • イベントのレプリケーションはデータベースの変更と同時に行われます。

セルフサービスのフレームワーク

作業中のリソースに簡単にGeoレプリケーションを追加したい場合は、セルフサービスフレームワークをご覧ください。

Geo 開発ワークフロー

GET:Geoパイプライン

e2e:package-and-test-eeパイプラインが成功した後、GET:Geo という名前のジョブを手動で起動することができます:

  1. GitLab プロジェクトで、マージリクエストのパイプラインタブを選択します。
  2. 最新のパイプラインのStage: qa ステージを選択すると、関連するすべてのジョブが展開され一覧表示されます。
  3. trigger-omnibus を選択すると、マージリクエストに対応するOmnibus GitLab Mirrorパイプラインが表示されます。
  4. GET:Geo ジョブはtrigger-qa ステージの内部で見つかり、トリガーされます。

このパイプラインは、GET を使用して1kGeo インストールをスピンアップし、インスタンスに対してgitlab-qa Geo シナリオを実行します。Geo 機能で作業する場合、qa-geo ジョブがトリガーされたGET:Geo pipelineで通過することを確認することをお勧めします。

インスタンスのプロビジョニングとティアダウンを制御するパイプラインは、The GitLab Environment Toolkit ConfigsGeo サブプロジェクトに含まれています。

新しい機能を追加するときは、動作を検証するために新しいテストを追加することを検討してください。手順については、QAドキュメントを参照してください。

アーキテクチャ

パイプラインは、複数の異なるプロジェクトの相互作用を伴います:

  • GitLab-e2e:package-and-test-ee ジョブ はこのプロジェクトのマージリクエストから起動します。
  • omnibus-gitlab - マージリクエストパイプラインからの変更を含む関連アーティファクトをビルドします。
  • GET-Configs/Geo- 評価可能な短期間の Geo インストールのライフサイクルを調整します。
  • GET- Geo インストールの作成と破棄に必要なロジックをコンテナ。GET-Configs/Geoで使用。
  • gitlab-qa - GitLab インスタンスに対して自動テストを実行するツール。
flowchart TD; GET:Geo-->getcg Provision-->Terraform Configure-->Ansible Geo-->Ansible QA-->gagq subgraph "omnibus-gitlab-mirror" GET:Geo end subgraph getcg [GitLab-environment-toolkit-configs/Geo] direction LR Generate-terraform-config-->Provision Provision-->Generate-ansible-config Generate-ansible-config-->Configure Configure-->Geo Geo-->QA QA-->Destroy-geo end subgraph get [GitLab Environment Toolkit] Terraform Ansible end subgraph GitLab QA gagq[GitLab QA Geo Scenario] end