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 集群并希望继续使用 NFS,请继续使用您正在使用的服务。NFS 在 14.x 版本中受支持,但已弃用。计划于今年结束所有版本的极狐GitLab 对在 NFS 上存储 Git 仓库数据的支持。
- 尚未迁移到 Gitaly 集群但想要从 NFS 迁移,您有两种选择:
- 一个分片的 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 数据库转储。 |
重建或替换现有的 Gitaly 集群节点 | 无法替换现有节点,因为依赖 Praefect 数据库来确定每个 Gitaly 节点的当前状态。 | 目前没有已知的解决方案。 |
快照备份和恢复限制
Gitaly 集群不支持快照备份。快照备份可能会导致 Praefect 数据库与磁盘存储不同步的问题。由于 Praefect 在还原期间如何重建 Gitaly 磁盘信息的复制元数据,我们建议使用官方备份和还原 Rake 任务。
如果您无法使用任何一种方法,请联系客户支持以获取恢复帮助。
如果您在 Gitaly 集群上遇到问题或限制该怎么办
请联系客户支持以立即获得恢复或恢复方面的帮助。
直接访问仓库
极狐GitLab 不建议使用 Git 客户端或任何其他工具直接访问存储在磁盘上的 Gitaly 仓库,因为 Gitaly 正在不断改进和更改。这些改进可能会使您的预设无效,从而导致性能下降、不稳定甚至数据丢失。例如:
- Gitaly 进行了优化,例如
info/refs
广告缓存,它依赖于 Gitaly 通过使用官方 gRPC 接口控制和监视对仓库的访问。 - Gitaly 集群有一些优化,例如容错和分布式读取,它们依赖于 gRPC 接口和数据库来确定仓库状态。
Gitaly
下面显示了极狐GitLab 设置为使用对 Gitaly 的直接访问:
在这个例子中:
- 每个仓库都存储在三个 Gitaly 存储之一上:
storage-1
、storage-2
或storage-3
。 - 每个存储都由一个 Gitaly 节点提供服务。
- 三个 Gitaly 节点将数据存储在其文件系统上。
Gitaly 架构
下面说明了 Gitaly 客户端-服务器架构:
Gitaly 集群
Git 存储是通过极狐GitLab 中的 Gitaly 服务提供的,对于极狐GitLab 的运行至关重要。当用户、仓库和活动的数量增加时,通过以下方式适当扩展 Gitaly 非常重要:
- 在因资源耗尽降低 Git、Gitaly 和极狐GitLab 应用程序的性能之前,增加可供 Git 使用的 CPU 和内存资源。
- 在因达到存储限制而导致写入操作失败之前,增加可用存储。
- 消除单点故障以提高容错能力。如果服务降级会阻止您将更改部署到生产环境,应将 Git 视为关键任务。
Gitaly 可以在集群配置中运行:
- 扩展 Gitaly 服务。
- 增加容错能力。
在此配置中,每个 Git 仓库都可以存储在集群中的多个 Gitaly 节点上。
使用 Gitaly 集群通过以下方式提高容错能力:
- 将写入操作复制到热备用 Gitaly 节点。
- 检测 Gitaly 节点故障。
- 自动将 Git 请求路由到可用的 Gitaly 节点。
下面显示了极狐GitLab 设置为访问 storage-1
,这是 Gitaly 集群提供的虚拟存储:
在这个例子中:
- 存储库存储在名为
storage-1
的虚拟存储中。 - 三个 Gitaly 节点提供
storage-1
访问:gitaly-1
、gitaly-2
和gitaly-3
。 - 三个 Gitaly 节点在三个独立的哈希存储位置共享数据。
-
复制系数 是
3
。每个仓库维护三个副本。
假设单个节点故障,Gitaly 集群的可用性目标是:
-
恢复点目标 (RPO):小于 1 分钟。
写入是异步复制的。任何尚未复制到新提升的主节点的写入都将丢失。
强一致性 在某些情况下可以防止丢失。
-
恢复时间目标 (RTO):小于 10 秒。 每个 Praefect 节点每秒运行一次运行状况检查来检测中断。故障转移需要在每个 Praefect 节点上连续进行十次失败的健康检查。
与 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 集群的必需组件。
功能
Gitaly 集群提供以下功能:
- Gitaly 节点之间的分布式读取。
- 次要副本的强一致性。
- 仓库的复制系数,用于增加冗余。
- 自动故障转移,从主要 Gitaly 节点到次要 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 集群
在迁移到 Gitaly 集群之前:
- 查看部署 Gitaly 集群之前。
- 升级到最新版本的极狐GitLab。
要迁移到 Gitaly 集群:
- 创建所需的存储。请参阅仓库存储建议。
- 创建并配置 Gitaly 集群。
- 使用 TPC 配置现有的 Gitaly 实例,如果还没有这样配置的话。
- 移动仓库。要迁移到 Gitaly 集群,必须移动存储在 Gitaly 集群之外的现有仓库。没有自动迁移,但可以使用极狐GitLab API 安排移动。
即使您不使用 default
仓库存储,也必须确保已对其进行配置。
迁移出 Gitaly 集群
如果发现 Gitaly 集群的限制和取舍不适合您的环境,您可以将 Gitaly 集群迁移到分片的 Gitaly 实例:
- 创建并配置一个新的 Gitaly 服务器。
- 移动仓库到新创建的存储。您可以按分片或按组移动它们,这样您就有机会将它们分布在多个 Gitaly 服务器上。