Help us learn about your current experience with the documentation. Take the survey.

Geo 自助服务框架

随着我们持续实施和迭代该框架,本文档可能会发生变化。 在 epic 中跟踪进展。 如果您需要复制新的数据类型,请联系 Geo 团队讨论选项。您可以在 Slack 的 #g_geo 频道联系他们,或在 issue 或 merge request 中提及 @geo-team

Geo 提供了一个 API,使得在 Geo 站点之间轻松复制数据类型成为可能。该 API 以 Ruby 领域特定语言(DSL)的形式呈现,旨在让创建数据类型的工程师以最小的努力实现数据复制。

Geo 是"完成定义"中的要求

Geo 是 GitLab 的 灾难恢复 解决方案。一个强大的灾难恢复方案必须复制 所有 GitLab 数据,以便在发生灾难时,所有 GitLab 服务都能以最小的数据损失完全成功恢复。

因此,GitLab 生成数据的 Geo 复制和验证支持是 完成定义 的一部分。这确保了新功能发布时带有 Geo 支持,我们的客户不会面临数据丢失的风险。

使用自助服务框架(SSF)添加 Geo 支持很容易,本文档详细介绍了各种数据类型的实现方法。但是,如果您需要一个更全面的指南来帮助您决定是否以及如何为新 GitLab 功能添加 Geo 支持,可以从这里开始

术语

在深入了解 API 之前,开发人员需要了解一些 Geo 特定的命名约定:

  • 模型: 模型是一个 Active Model,在整个 Rails 代码库中都是这样称呼的。它通常与数据库表相关联。从 Geo 的角度来看,一个模型可以拥有一个或多个资源。

  • 资源: 资源是属于模型并由 GitLab 功能生成的一块数据。它使用存储机制进行持久化。默认情况下,资源不是 Geo 可复制的。

  • 数据类型: 数据类型是资源的存储方式。每个资源都应该属于 Geo 支持的数据类型之一:

    • Git 仓库
    • Blob
    • 数据库

    更多详情,请参见 数据类型

  • Geo 可复制资源: 可复制资源是 Geo 希望在各个 Geo 站点之间同步的资源。可复制资源有一组有限的支持数据类型。实现属于已知数据类型之一的资源的复制所需的工作量很小。

  • Geo 复制器: Geo 复制器是知道如何复制可复制资源的对象。它负责:

    • 触发事件(生产者)
    • 消费事件(消费者)

    它与 Geo 可复制资源数据类型相关联。所有复制器都有一个通用接口,可用于处理(即生产和消费)事件。它负责处理主站点(事件产生地)和次站点(事件消费地)之间的通信。希望在其功能中集成 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/

现有复制器策略

在编写新的复制器策略之前,请检查以下内容,看看您的资源是否已经可以被现有策略之一处理。如果您不确定,请咨询 Geo 团队。

Blob 复制器策略

使用 CarrierWave’s Uploader::Base 的模型通过 Geo::BlobReplicatorStrategy 模块得到 Geo 支持。例如,请参阅 如何为流水线制品实现 Geo 复制

每个文件都应该有自己的主 ID 和模型。Geo 强烈建议将每个文件都视为一等公民,因为根据我们的经验,这大大简化了复制和验证状态的跟踪。

要实现新的 blob 类型模型的 Geo 复制,使用提供的 issue 模板打开一个 issue

要查看实现步骤而不打开 issue,查看 issue 模板文件

仓库复制器策略

引用磁盘上任何 Git 仓库的模型通过 Geo::RepositoryReplicatorStrategy 模块得到 Geo 支持。例如,请参阅 如何为组级 Wiki 实现 Geo 复制。请注意,这个 issue 没有实现验证,因为 Git 仓库验证尚未添加到 Geo 自助服务框架中。实现验证的示例可以在 添加代码片段仓库验证 的 merge request 中找到。

每个 Git 仓库都应该有自己的主 ID 和模型。

要实现新的 Git 仓库类型模型的 Geo 复制,使用提供的 issue 模板打开一个 issue

要查看实现步骤而不打开 issue,查看 issue 模板文件