Help us learn about your current experience with the documentation. Take the survey.
数据库负载均衡
通过数据库负载均衡,只读查询可以分布在多个 PostgreSQL 节点上以提高性能。
本文档提供了关于数据库负载均衡如何在 GitLab Rails 和 Sidekiq 中实现的技术概述。
术语
- Host:每个数据库主机。可以是主节点(primary)或副本节点(replica)。
- Primary:用于执行只写和读写操作的主 PostgreSQL 主机。
- Replica:用于执行只读操作的辅助 PostgreSQL 主机。
- Workload:需要数据库连接的 Rails 请求或 Sidekiq 作业。
组件
负载均衡过程涉及几个 Ruby 类。它们都在 Gitlab::Database::LoadBalancing 命名空间下:
HostLoadBalancerConnectionProxySession
每个工作负载都以 Gitlab::Database::LoadBalancing::Session 的新实例开始。Session 会跟踪已执行的数据库操作,然后确定该工作负载是否需要连接到主主机或副本主机。
当工作负载需要通过 ActiveRecord 进行数据库连接时,ConnectionProxy 首先将连接请求重定向到 LoadBalancer。ConnectionProxy 根据几个标准向 LoadBalancer 请求 read 或 read_write 连接:
- 查询是只读的还是需要写入的。
Session之前是否记录了写入操作。- 是否使用了任何特殊代码块来优先选择主节点或副本节点,例如:
use_primaryignore_writesuse_replicas_for_read_queriesfallback_to_replicas_for_ambiguous_queries
然后 LoadBalancer 从相应的数据库连接池中提供请求的连接。它提供以下两种之一:
- 来自主节点连接池的
read_write连接。 - 来自副本节点连接池的
read连接。
当响应 read 连接请求时,LoadBalancer 会首先尝试在副本主机之间负载均衡连接。它会查找下一个 online(在线)的副本主机,并从该主机的连接池中提供连接。如果副本主机与主节点保持同步(基于复制延迟大小或时间),则认为该副本主机是 online(在线)的。这些要求的阈值是可配置的。
部署策略
当通过功能标志推出更改时,考虑最初仅部署到 Sidekiq pod 以最小化风险。
为什么优先部署到 Sidekiq:
- 保持 API pod 稳定,确保在最坏的情况下 ChatOps 仍然可用以禁用功能标志。
- 后台作业可以自动重试,无需任何人工干预。
实现示例:
if feature_flag_enabled? && Gitlab::Runtime.sidekiq?
new_changes
else
existing_changes
end