并发限制
为了避免压垮运行 Gitaly 的服务器,您可以限制以下内容的并发性:
- RPC。
- Pack 对象。
这些限制可以是固定的,也可以设置为自适应的。
限制 RPC 并发性
在克隆或拉取存储库时,各种 RPC 在后台运行。特别是,Git pack RPC:
-
SSHUploadPackWithSidechannel
(用于 Git SSH)。 -
PostUploadPackWithSidechannel
(用于 Git HTTP)。
这些 RPC 可能会消耗大量资源,在以下情况下可能会产生显著影响:
- 意外的高流量。
- 运行在不遵循最佳实践的大型存储库上。
您可以通过在 Gitaly 配置文件中使用并发限制来防止这些进程压垮您的 Gitaly 服务器。例如:
# 在 /etc/gitlab/gitlab.rb 中
gitaly['configuration'] = {
# ...
concurrency: [
{
rpc: '/gitaly.SmartHTTPService/PostUploadPackWithSidechannel',
max_per_repo: 20,
max_queue_wait: '1s',
max_queue_size: 10,
},
{
rpc: '/gitaly.SSHService/SSHUploadPackWithSidechannel',
max_per_repo: 20,
max_queue_wait: '1s',
max_queue_size: 10,
},
],
}
-
rpc
是要为每个存储库设置并发限制的 RPC 的名称。 -
max_per_repo
是每个存储库中给定 RPC 的最大并发 RPC 调用数。 -
max_queue_wait
是请求在并发队列中等待被 Gitaly 接收的最大时间。 -
max_queue_size
是并发队列(每个 RPC 方法)的最大大小,在达到此大小之前请求会被 Gitaly 拒绝。
这限制了给定 RPC 的并发 RPC 调用数。限制是按存储库应用的。在上面的示例中:
- 由 Gitaly 服务器服务的每个存储库最多可以有 20 个同时进行的
PostUploadPackWithSidechannel
和SSHUploadPackWithSidechannel
RPC 调用。 - 如果另一个请求进入一个已经使用了 20 个插槽的存储库,该请求将被排队。
- 如果请求在队列中等待超过 1 秒,它将被拒绝并出现错误。
- 如果队列增长超过 10,后续请求将被拒绝并出现错误。
您可以使用 Gitaly 日志和 Prometheus 观察此队列的行为。有关更多信息,请参阅相关文档。
限制 pack-objects 并发性
- 引入于极狐GitLab 15.11,使用名为
gitaly_pack_objects_limiting_remote_ip
的功能标志。默认禁用。- 在极狐GitLab 16.0 中 GA。功能标志
gitaly_pack_objects_limiting_remote_ip
被移除。
Gitaly 在处理 SSH 和 HTTPS 流量以克隆或拉取存储库时触发 git-pack-objects
进程。这些进程生成一个 pack-file
并可能消耗大量资源,特别是在意外的高流量或从大型存储库并发拉取时。在 GitLab.com 上,我们还观察到与互联网连接速度较慢的客户端有关的问题。
您可以通过在 Gitaly 配置文件中设置 pack-objects 并发限制来防止这些进程压垮您的 Gitaly 服务器。此设置限制每个远程 IP 地址的在途 pack-object 进程数。
示例配置:
# 在 /etc/gitlab/gitlab.rb 中
gitaly['pack_objects_limiting'] = {
'max_concurrency' => 15,
'max_queue_length' => 200,
'max_queue_wait' => '60s',
}
-
max_concurrency
是每个键的最大在途 pack-object 进程数。 -
max_queue_length
是并发队列(每个键)的最大大小,在达到此大小之前请求会被 Gitaly 拒绝。 -
max_queue_wait
是请求在并发队列中等待被 Gitaly 接收的最大时间。
在上面的示例中:
- 每个远程 IP 在一个 Gitaly 节点上最多可以有 15 个同时进行的 pack-object 进程。
- 如果另一个请求来自一个已经使用了 15 个插槽的 IP,该请求将被排队。
- 如果请求在队列中等待超过 1 分钟,它将被拒绝并出现错误。
- 如果队列增长超过 200,后续请求将被拒绝并出现错误。
当启用 pack-object 缓存时,pack-objects 限制仅在缓存未命中时生效。有关更多信息,请参阅 Pack-objects 缓存。
您可以使用 Gitaly 日志和 Prometheus 观察此队列的行为。有关更多信息,请参阅 监控 Gitaly pack-objects 并发限制。
自适应并发限制
- 引入于极狐GitLab 16.6。
Gitaly 支持两种并发限制:
- RPC 并发限制,允许您为每个 Gitaly RPC 配置最大并发请求数。限制是按 RPC 和存储库作用域的。
- Pack-objects 并发限制,限制每个 IP 的并发 Git 数据传输请求数。
如果超过此限制,则:
- 请求被放入队列中。
- 如果队列已满或请求在队列中停留时间过长,请求将被拒绝。
这两种并发限制都可以静态配置。虽然静态限制可以产生良好的保护效果,但它们也有一些缺点:
- 静态限制不适用于所有使用模式。没有一刀切的值。如果限制太低,大型存储库会受到负面影响。如果限制太高,则保护基本上失效。
- 维护并发限制的合理值很繁琐,尤其是在每个存储库的工作负载随时间变化时。
- 即使服务器空闲,请求也可能被拒绝,因为速率没有考虑到服务器的负载。
通过配置自适应并发限制,您可以克服所有这些缺点并保持并发限制的好处。自适应并发限制是可选的,并建立在两种并发限制类型之上。它使用加法增加/乘法减少 (AIMD) 算法。每个自适应限制:
- 在典型进程运行期间逐渐增加到某个上限。
- 当主机机器出现资源问题时迅速减少。
此机制为机器提供了一些 “呼吸” 的空间,并加速当前在途请求。
自适应限制器每 30 秒校准一次限制,并且:
- 在达到上限之前,每次增加一个限制。
- 当顶级 cgroup 的内存使用率超过 90%(不包括高度可回收的页面缓存)或 CPU 被限制 50% 或更多观察时间时,减少一半的限制。
否则,限制会增加一个,直到达到上限。
自适应限制是为每个 RPC 或 pack-objects 缓存单独启用的。然而,限制是在同一时间校准的。
启用 RPC 并发性的自适应性
先决条件:
- 由于自适应限制依赖于控制组,在使用自适应限制之前必须启用控制组。
以下是配置 RPC 并发性自适应限制的示例:
# 在 /etc/gitlab/gitlab.rb 中
gitaly['configuration'] = {
# ...
concurrency: [
{
rpc: '/gitaly.SmartHTTPService/PostUploadPackWithSidechannel',
max_queue_wait: '1s',
max_queue_size: 10,
adaptive: true,
min_limit: 10,
initial_limit: 20,
max_limit: 40
},
{
rpc: '/gitaly.SSHService/SSHUploadPackWithSidechannel',
max_queue_wait: '10s',
max_queue_size: 20,
adaptive: true,
min_limit: 10,
initial_limit: 50,
max_limit: 100
},
],
}
在此示例中:
-
adaptive
设置是否启用自适应性。如果设置,则忽略max_per_repo
值,使用以下配置。 -
initial_limit
是极狐GitLab 启动时每个存储库的并发限制。 -
max_limit
是配置 RPC 的最低每个存储库的并发限制。极狐GitLab 增加当前限制,直到达到此数字。 -
min_limit
是配置 RPC 的最低每个存储库的并发限制。当主机机器出现资源问题时,极狐GitLab 快速减少限制,直到达到此值。
有关更多信息,请参阅 RPC 并发性。
启用 pack-objects 并发性的自适应性
先决条件:
- 由于自适应限制依赖于控制组,在使用自适应限制之前必须启用控制组。
以下是配置 pack-objects 并发性自适应限制的示例:
# 在 /etc/gitlab/gitlab.rb 中
gitaly['pack_objects_limiting'] = {
'max_queue_length' => 200,
'max_queue_wait' => '60s',
'adaptive' => true,
'min_limit' => 10,
'initial_limit' => 20,
'max_limit' => 40
}
在此示例中:
-
adaptive
设置是否启用自适应性。如果设置,则忽略max_concurrency
值,使用以下配置。 -
initial_limit
是极狐GitLab 启动时每个 IP 的并发限制。 -
max_limit
是 pack-objects 的最低每个 IP 并发限制。极狐GitLab 增加当前限制,直到达到此数字。 -
min_limit
是 pack-objects 的最低每个 IP 并发限制。当主机机器出现资源问题时,极狐GitLab 快速减少限制,直到达到此值。
有关更多信息,请参阅 pack-objects 并发性。