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

note
この文書は、フレームワークの実装と反復を続ける中で変更される可能性があります。エピックで進捗状況をご確認ください。新しいデータタイプを複製する必要がある場合は、Geo チームに連絡してオプションについて相談してください。Slack の#g_geo に連絡するか、イシューまたはマージリクエストに@geo-team と記載してください。

Geo は、Geo サイト間でデータタイプを簡単に複製できる API を提供しています。この API は Ruby Domain-Specific Language(DSL) として提供されており、データ型を作成したエンジニアの労力を最小限に抑えてデータの複製を可能にすることを目的としています。

Geo は、done の定義における要件です。

Geoはディザスタリカバリ用のGitLabソリューションです。堅牢なディザスタリカバリソリューションは、ディザスタリカバリのイベントが発生した際に、全てのGitLabサービスが最小限のデータ損失で全体的に正常に復元できるように、全てのGitLabデータを複製する必要があります。

この理由から、GeoレプリケーションとGitLab生成データの検証サポートは、完了の定義の一部です。これにより、新機能がGeoサポートと共に出荷され、お客様がデータ損失にさらされないことを保証します。

Self Service Framework(SSF) を使って Geo サポートを追加するのは簡単で、様々なタイプのデータについてこのページで詳しく説明しています。しかし、GitLabの新機能にGeoサポートを追加する必要があるかどうか、またどのように追加するかを決めるのに役立つ、より一般的なガイドについては、ここから始めることができます

命名法

APIを使いこなす前に、開発者はGeo特有の命名規則を知っておく必要があります:

  • モデル:モデルとは Active Model のことで、Rails コードベース全体ではこのように呼ばれています。通常はデータベースのテーブルに関連付けられています。Geoから見ると、モデルは1つ以上のリソースを持つことができます。

  • リソース:リソースはモデルに属し、GitLabの機能によって生成されるデータの一部です。ストレージメカニズムを使って永続化されます。デフォルトでは、リソースはGeo複製可能ではありません。

  • データ型:データ型はリソースの保存方法です。各リソースはGeoがサポートしているデータタイプのどれかに当てはまる必要があります:
    • Gitリポジトリ
    • ブロブ
    • データベース

    詳細については、データタイプを参照してください。

  • Geo Replicable:Replicable は Geo が Geo サイト間で同期させたいリソースです。レプリケーブルのデータ型は限られています。既知のデータタイプに属するリソースのレプリケーションを実装するのに必要な労力は最小限です。

  • Geo レプリケーター:Geoレプリケーターは、複製可能なものを複製する方法を知っているオブジェクトです。その役割は次のとおりです:
    • イベントの発射(プロデューサー)
    • イベントを消費する(消費者)

    これは Geo Replicable データ型と結びついています。すべてのレプリケーターは、イベントの処理(つまり、生成と消費)に使用できる共通のインターフェースを持っています。プライマリ・サイト(イベントが生成される場所)とセカンダリ・サイト(イベントが消費される場所)間の通信を行います。Geoを機能に組み込みたいエンジニアは、レプリケータのAPIを使ってこれを実現します。

  • Geoドメイン固有言語:どのリソースをどのように複製するかをエンジニアが簡単に指定できるようにする構文上の糖分。

Geoドメイン固有言語

レプリケーター

まず最初に、レプリケーターを書く必要があります。レプリケータはee/app/replicators/geo内部で動作します。複数のリソースが同じモデルに関連付けられている場合でも、レプリケートする必要があるリソースごとに、別々のレプリケータを指定する必要があります。

例えば、以下のレプリケーターはパッケージファイルをレプリケートします:

module Geo
  class PackageFileReplicator < Gitlab::Geo::Replicator
    # Include one of the strategies your resource needs
    include ::Geo::BlobReplicatorStrategy

    # Specify the CarrierWave uploader needed by the used strategy
    def carrierwave_uploader
      model_record.file
    end

    # Specify the model this replicator belongs to
    def self.model
      ::Packages::PackageFile
    end
  end
end

クラス名は一意でなければなりません。クラス名は一意でなければなりません。また、レジストリのテーブル名と密接に結びついているので、 この例ではレジストリテーブルをpackage_file_registry とします。

Geo がサポートするさまざまなデータ型には、含めるべきさまざまな戦略があります。ニーズに合ったものを選んでください。

モデルへのリンク

このリプリケータをモデルに結びつけるには、モデルコードに以下を追加する必要があります:

class Packages::PackageFile < ApplicationRecord
  include ::Geo::ReplicableModel

  with_replicator Geo::PackageFileReplicator
end

API

これが設定されていれば、モデルを通してリプリケータにアクセスするのは簡単です:

package_file = Packages::PackageFile.find(4) # just a random ID as example
replicator = package_file.replicator

あるいは、レプリケーターからモデルを取り戻すこともできます:

replicator.model_record
=> <Packages::PackageFile id:4>

レプリケーターは、ActiveRecord フックなどでイベントを生成するために使うことができます:

  after_create_commit -> { replicator.publish_created_event }

ライブラリ

すべてのフレームワークはee/lib/gitlab/geo/にあります。

既存のレプリケーター戦略

新しい種類の Replicator 戦略を書く前に、あなたのリソースが既存の戦略のどれかですでに処理できるかどうかを以下で確認してください。わからない場合はGeoチームに相談してください。

ブロブ レプリケーター ストラテジー

CarrierWave の Uploader::Base を使用するモデルは、Geo のGeo::BlobReplicatorStrategy モジュールでサポートされます。例えば、パイプラインアーティファクトに Geo レプリケーションがどのように実装されたかをご覧ください。

各ファイルは、独自のプライマリ ID とモデルを持つことが期待されています。Geo では、一つひとつのファイルを第一級市民として扱うことを強く推奨しています。なぜなら、私たちの経験では、これによりレプリケーションと検証状態の追跡が大幅に簡素化されるからです。

新しい blob 型モデルの Geo レプリケーションを実装するには、提供されているイシュー テンプレートでイシューを開いてください。

イシューを開かずに実装手順を見るには、イシュー・テンプレート・ファイルをご覧ください。

リポジトリ・レプリケーター戦略

ディスク上の Git リポジトリを参照するモデルは、Geo のGeo::RepositoryReplicatorStrategy モジュールでサポートされています。例えば、グループレベルの Wiki に対して Geo レプリケーションがどのように実装されたかをご覧ください。Git リポジトリの検証は Geo のセルフサービスフレームワークにまだ追加されていないため、このイシューでは検証を実装していないことに注意してください。検証を実装した例は、スニペットリポジトリの検証を追加するためのマージリクエストにあります。

Git リポジトリはそれぞれ、プライマリ ID とモデルを持っているはずです。

新しい Git リポジトリ型のモデルの Geo レプリケーションを実装するには、提供されている課題テンプレートでイシューを開いてください。

イシューを開かずに実装手順を見るには、イシュー・テンプレート・ファイルをご覧ください。