Gitaly 和 Gitaly 集群

Gitaly 提供对 Git 仓库的高级 RPC 访问。极狐GitLab 使用它来读取和写入 Git 数据。

Gitaly 存在于每个极狐GitLab 安装实例中,并协调 Git 仓库的存储和检索。Gitaly 是:

  • 在单个 Omnibus GitLab 实例上运行的后台服务。
  • 根据扩展和可用性要求,分离到自己的实例并配置为完整的集群配置。

Gitaly 实现了客户端-服务器架构:

  • Gitaly 服务器是运行 Gitaly 本身的任何节点。
  • Gitaly 客户端是运行向 Gitaly 服务器发出请求的进程的任何节点。Gitaly 客户端也称为 Gitaly 消费者,包括:
    • Rails 应用
    • Shell
    • Workhorse
    • Elasticsearch Indexer

Gitaly 仅管理极狐GitLab 的 Git 仓库访问。其他类型的极狐GitLab 数据不能使用 Gitaly 访问。

极狐GitLab 通过配置的仓库存储访问仓库。每个新仓库都根据它们的配置权重存储在其中一个仓库存储中。每个仓库存储:

  • 使用存储路径直接访问仓库的 Gitaly 存储,其中每个仓库都存储在单个 Gitaly 节点上。所有请求都路由到此节点。
  • Gitaly 集群提供的一个虚拟存储,每个仓库可以存储在多个 Gitaly 节点上以实现容错。在 Gitaly 集群中:
    • 读取请求分布在多个 Gitaly 节点之间,可以提高性能。
    • 写请求被广播到仓库副本。

部署 Gitaly 集群之前

Gitaly 集群提供了容错的好处,但也带来了额外的设置和管理复杂性。 在部署 Gitaly 集群之前,请查看:

如果您还没有迁移到 Gitaly 集群,您有两个选择:

  • 一个分片的 Gitaly 实例。
  • Gitaly 集群。

如果您有任何问题,请联系技术支持。

已知问题

下表概述了影响 Gitaly 集群使用的当前已知问题。有关这些问题的当前状态,请参阅参考的议题和史诗。

问题 概述 如何规避
Gitaly Cluster + Geo - 重试失败同步的问题 如果在 Geo 次要站点上使用 Gitaly 集群,同步失败的仓库可能会在 Geo 尝试重新同步它们时继续失败。从此状态恢复需要支持人员的帮助才能运行手动步骤。 15.0 版本之前没有已知的解决方案。在 15.0 到 15.2 版本中,启用 gitaly_praefect_generated_replica_paths 功能标志。在 15.3 版本中,默认情况下启用功能标志。
由于升级后未应用迁移,Praefect 无法将数据插入数据库 如果数据库没有与已完成的迁移保持同步,则 Praefect 节点无法执行正常操作。 确保 Praefect 数据库已启动并在所有迁移完成的情况下运行(例如:/opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml sql-migrate-status 应该显示所有应用迁移的列表)。考虑请求技术支持。
从正在运行的集群中的快照恢复 Gitaly 集群节点 因为 Gitaly 集群以一致的状态运行,引入一个落后的节点会导致集群无法协调节点数据和其他节点数据。 不要从备份快照中恢复单个 Gitaly 集群节点。如果您必须从备份中恢复,最好关闭极狐GitLab,同时对所有 Gitaly 集群节点进行快照,并进行 Praefect 数据库转储。
运行 Kubernetes、Amazon ECS 或相似系统的限制 不支持 Praefect(Gitaly Cluster),并且 Gitaly 具有已知的限制。 使用我们的引用架构。

快照备份和恢复限制

Gitaly 集群不支持快照备份。快照备份可能会导致 Praefect 数据库与磁盘存储不同步的问题。由于 Praefect 在还原期间如何重建 Gitaly 磁盘信息的复制元数据,我们建议使用官方备份和还原 Rake 任务。

如果您无法使用任何一种方法,请联系客户支持以获取恢复帮助。

如果您在 Gitaly 集群上遇到问题或限制该怎么办

请联系客户支持以立即获得恢复或恢复方面的帮助。

磁盘要求

Gitaly 和 Gitaly 集群需要快速的本地存储才能有效执行,因为它们是基于 I/O 的繁重进程。因此,我们强烈建议所有 Gitaly 节点都使用固态硬盘 (SSD)。

这些 SSD 的吞吐量至少应为:

  • 每秒 8,000 次输入/输出操作 (IOPS) 用于读取操作。
  • 2,000 IOPS 用于写入操作。

这些 IOPS 值是初始建议值,可能会根据环境工作负载的规模调整为更大或更小的值。如果您在云提供商上运行环境,请参阅他们的文档以了解如何正确配置 IOPS。

对于存储库数据,出于性能和一致性原因,Gitaly 和 Gitaly 集群仅支持本地存储。 不支持 NFS 或基于云的文件系统等替代方案。

直接访问仓库

极狐GitLab 不建议使用 Git 客户端或任何其他工具直接访问存储在磁盘上的 Gitaly 仓库,因为 Gitaly 正在不断改进和更改。这些改进可能会使您的预设无效,从而导致性能下降、不稳定甚至数据丢失。例如:

  • Gitaly 进行了优化,例如 info/refs 广告缓存,它依赖于 Gitaly 通过使用官方 gRPC 接口控制和监视对仓库的访问。
  • Gitaly 集群有一些优化,例如容错和分布式读取,它们依赖于 gRPC 接口和数据库来确定仓库状态。
caution 直接访问 Git 仓库需要您自担风险,并且不受支持。

Gitaly

下面显示了极狐GitLab 设置为使用对 Gitaly 的直接访问:

Shard example

在这个例子中:

  • 每个仓库都存储在三个 Gitaly 存储之一上:storage-1storage-2storage-3
  • 每个存储都由一个 Gitaly 节点提供服务。
  • 三个 Gitaly 节点将数据存储在其文件系统上。

Gitaly 架构

下面说明了 Gitaly 客户端-服务器架构:

flowchart TD subgraph Gitaly clients A[GitLab Rails] B[GitLab Workhorse] C[GitLab Shell] D[...] end subgraph Gitaly E[Git integration] end F[Local filesystem] A -- gRPC --> Gitaly B -- gRPC--> Gitaly C -- gRPC --> Gitaly D -- gRPC --> Gitaly E --> F

Gitaly 集群

Git 存储是通过极狐GitLab 中的 Gitaly 服务提供的,对于极狐GitLab 的运行至关重要。当用户、仓库和活动的数量增加时,通过以下方式适当扩展 Gitaly 非常重要:

  • 在因资源耗尽降低 Git、Gitaly 和极狐GitLab 应用程序的性能之前,增加可供 Git 使用的 CPU 和内存资源。
  • 在因达到存储限制而导致写入操作失败之前,增加可用存储。
  • 消除单点故障以提高容错能力。如果服务降级会阻止您将更改部署到生产环境,应将 Git 视为关键任务。

Gitaly 可以在集群配置中运行:

  • 扩展 Gitaly 服务。
  • 增加容错能力。

在此配置中,每个 Git 仓库都可以存储在集群中的多个 Gitaly 节点上。

使用 Gitaly 集群通过以下方式提高容错能力:

  • 将写入操作复制到热备用 Gitaly 节点。
  • 检测 Gitaly 节点故障。
  • 自动将 Git 请求路由到可用的 Gitaly 节点。
note Gitaly 集群的技术支持仅限于专业版和旗舰版客户。

下面显示了极狐GitLab 设置为访问 storage-1,这是 Gitaly 集群提供的虚拟存储:

Cluster example

在这个例子中:

  • 存储库存储在名为 storage-1 的虚拟存储中。
  • 三个 Gitaly 节点提供 storage-1 访问:gitaly-1gitaly-2gitaly-3
  • 三个 Gitaly 节点在三个独立的哈希存储位置共享数据。
  • 复制系数3。每个仓库维护三个副本。

假设单个节点故障,Gitaly 集群的可用性目标是:

  • 恢复点目标 (RPO):小于 1 分钟。

    写入是异步复制的。任何尚未复制到新提升的主节点的写入都将丢失。

    强一致性 在某些情况下可以防止丢失。

  • 恢复时间目标 (RTO):小于 10 秒。 每个 Praefect 节点每秒运行一次运行状况检查来检测中断。故障转移需要在每个 Praefect 节点上连续进行十次失败的健康检查。

caution 如果发生完整的集群故障,则应执行灾难恢复计划。这会影响上面讨论的 RPO 和 RTO。

与 Geo 比较

Gitaly 集群和 Geo 都提供冗余。然而:

  • Gitaly Cluster 为数据存储提供容错能力,对用户是不可见的。用户不知道何时使用 Gitaly 集群。
  • Geo 为整个极狐GitLab 实例提供复制和灾难恢复。用户知道他们何时使用 Geo 进行复制。Geo 复制多种数据类型,包括 Git 数据。

下表概述了 Gitaly 集群和 Geo 之间的主要区别:

工具 节点 位置 延迟容忍度 故障转移 一致性 提供冗余
Gitaly 集群 多个 单个 不到 1 秒,理想情况下是个位数毫秒 自动 强一致性 Git 中的数据存储
Geo 多个 多个 最多一分钟 手动 最终一致性 整个极狐GitLab 实例

虚拟存储

虚拟存储使在极狐GitLab 中拥有单个仓库存储,使简化仓库管理成为可能。

带有 Gitaly 集群的虚拟存储通常可以替代直接的 Gitaly 存储配置。 但是,这是以在多个 Gitaly 节点上存储每个仓库所需的额外存储空间为代价的。与直接 Gitaly 存储相比,使用 Gitaly 集群虚拟存储的好处是:

  • 改进了容错性,因为每个 Gitaly 节点都有每个仓库的副本。
  • 提高了资源利用率,减少了对特定于分片的峰值负载的过度配置需求,因为读取负载分布在 Gitaly 节点上。
  • 不需要手动重新平衡性能,因为读取负载分布在 Gitaly 节点上。
  • 更简单的管理,因为所有 Gitaly 节点都是相同的。

可以使用复制系数配置仓库副本的数量。

与普通 Gitaly 存储一样,虚拟存储可以分片。

组件

Gitaly 集群由多个组件组成:

  • 负载均衡器,用于分发请求并提供对 Praefect 节点的容错访问。
  • Praefect 节点,用于管理集群并将请求路由到 Gitaly 节点。
  • PostgreSQL 数据库,用于持久化集群元数据和 PgBouncer,推荐用于池化 Praefect 的数据库连接。
  • Gitaly 节点提供仓库存储和 Git 访问。

架构

Praefect 是 Gitaly 的路由器和事务管理器,也是运行 Gitaly 集群的必需组件。

Architecture diagram

功能

Gitaly 集群提供以下功能:

分布式读取

Gitaly 集群支持跨为虚拟存储配置的 Gitaly 节点分布读取操作。

所有标有 ACCESSOR 选项的 RPC 都被重定向到最新且健康的 Gitaly 节点。例如,GetBlob

最新(Up to date)意味着:

  • 没有为此 Gitaly 节点安排的复制操作。
  • 最后一个复制操作处于完成状态。

如果出现以下情况,则选择主节点来处理请求:

  • 没有最新的节点。
  • 在节点选择期间发生任何其他错误。

您可以使用 Prometheus 监控读取分布

强一致性

  • 引入于 13.1 版本,作为 alpha 功能,默认禁用。
  • 升级为 beta 于 13.2版本,默认禁用。
  • 在 13.3 版本中,除非禁用 primary-wins 投票策略,否则禁用。
  • 默认启用于 13.4 版本。
  • 从 13.5 版本开始,您必须在 Gitaly 节点上使用 Git v2.28.0 或更高版本才能启用强一致性。
  • 从 13.6 版本开始,primary-wins 投票策略和 gitaly_reference_transactions_primary_wins 功能标志删除。
  • 从 14.0 版本开始,Gitaly 集群仅支持强一致性,删除了 gitaly_reference_transactions 功能标志。

Gitaly 集群通过将更改同步写入所有健康、最新的副本来提供强一致性。如果副本在事务发生时已过时或不健康,则写入将异步复制到它。

如果强一致性不可用,Gitaly 集群保证最终一致性。在这种情况下,在对主 Gitaly 节点的写入发生后,Gitaly 集群会将所有写入复制到次要 Gitaly 节点。

强一致性是 14.0 及更高版本中的主要复制方法。一部分操作仍然使用复制作业(最终一致性)而不是强一致性。

复制系数

复制系数是 Gitaly 集群维护给定仓库的副本数。更高的复制参数:

  • 提供更好的冗余和读取工作负载分布。
  • 导致更高的存储成本。

默认情况下,Gitaly 集群将仓库复制到虚拟存储中的每个存储。

有关配置信息,请参阅配置复制参数

配置 Gitaly 集群

有关配置 Gitaly 集群的更多信息,请参阅配置 Gitaly 集群

迁移到 Gitaly 集群

caution Gitaly 集群中存在一些已知问题。在继续之前查看以下信息。

在迁移到 Gitaly 集群之前:

要迁移到 Gitaly 集群:

  1. 创建所需的存储。请参阅仓库存储建议
  2. 创建并配置 Gitaly 集群
  3. 使用 TPC 配置现有的 Gitaly 实例,如果还没有这样配置的话。
  4. 移动仓库。要迁移到 Gitaly 集群,必须移动存储在 Gitaly 集群之外的现有仓库。没有自动迁移,但可以使用极狐GitLab API 安排移动。

即使您不使用 default 仓库存储,也必须确保已对其进行配置。

迁移出 Gitaly 集群

如果发现 Gitaly 集群的限制和取舍不适合您的环境,您可以将 Gitaly 集群迁移到分片的 Gitaly 实例:

  1. 创建并配置一个新的 Gitaly 服务器
  2. 移动仓库到新创建的存储。您可以按分片或按组移动它们,这样您就有机会将它们分布在多个 Gitaly 服务器上。