导读:本期聚焦于蚂蚁创作的《CockroachDB 的 range lease 转移频率过高怎么办?locality 配置详解》,敬请观看详情。CockroachDB 集群出现 lease 转移过于频繁、节点间延迟抖动加大时,通常是 locality 与 zone 配置不合理导致的。本文从 range lease 的工作机制讲起,分析 lease holder 选择与 locality 约束的关系,说明为什么跨地域或跨机架部署时 lease 会在副本之间来回搬迁,并给出 geo-partitioning、副本放置约束、lease preference 等具体配置方法,同时介绍如何通过 DB 控制台和系统表观察 lease 转移次数,帮助读者定位根因并降低不必要的转移开销。

CockroachDB 是一款基于分布式共识协议的分布式 SQL 数据库,它把逻辑上的表数据切分成一个个 range,每个 range 默认有三个副本,其中只有一个副本持有 range lease,负责处理该 range 上的全部读写请求。正常情况下 lease 是相对稳定的,但在实际运维中经常遇到 lease 频繁转移的情况,表现出来就是延迟毛刺增多、节点之间流量来回摆动。这篇文章围绕 range lease 的转移频率问题,重点分析 locality 相关的配置如何影响 lease 的归属,以及应该如何调整配置让 lease 稳定下来。

CockroachDB 的 range lease 转移频率过高怎么办?locality 配置详解

range lease 的基本工作机制

每个 range 的多个副本分布在不同的节点上,通过 Raft 协议保证数据一致性。Raft 协议本身解决的是日志复制顺序问题,但读写请求需要一个明确的协调者,这个协调者就是 lease holder。lease holder 通过定期续约来维持自己的身份,默认的 lease 有效期大约是 9 秒,续约周期约为 3 秒。只要 lease holder 节点健康并且能够正常与多数派副本通信,lease 就会一直留在它手里。

lease 的转移通常发生在几种场景:一是节点故障或重启,lease 必须被其他副本接管;二是副本迁移,比如节点下线、负载均衡触发的 rebalance 操作,lease 会跟着副本移动;三是配置约束变化,当用户修改了 zone 配置中的约束条件后,系统会重新评估 lease 应该归属哪个副本;四是明确设置了 lease preference,当首选位置的副本状态变化时,lease 会主动搬到符合偏好的副本上。

理解这些触发条件非常关键,因为 lease 频繁转移往往不是系统 bug,而是配置与集群拓扑之间发生了某种冲突。比如把 lease preference 设置在了一个不稳定的位置,或者副本约束导致副本不断被重新放置,lease 自然也会跟着来回跳。

locality 与 lease 归属的关系

启动 CockroachDB 节点时可以通过 --locality 参数描述节点的物理位置,例如 --locality=region=cn-east,zone=az1,rack=r3。locality 本身是层级化的键值对,层级顺序从大到小排列。locality 主要影响两件事:副本放置(通过 zone 配置的 constraints)和 lease 放置(通过 lease preferences)。

一个常见的误区是认为只要副本分布对了,lease 就会自动跟着 locality 走。实际上,如果没有显式配置 lease preference,lease 通常会倾向于留在离多数派副本最近的位置,但在节点负载不均或发生 rebalance 时它可能出现在任何副本上。对于跨地域部署的集群,如果 lease 落在远离用户的地域,每个请求都要承担一次跨地域往返延迟,这就是很多用户感觉读写时快时慢的根本原因。

下面的示例展示了一个跨三地域集群的典型配置方式,先给数据库设置约束让副本按 3-2-2 分布,再把 lease 固定到用户所在地域:

-- 为特定数据库设置副本约束
ALTER DATABASE appdb CONFIGURE ZONE USING
  num_replicas = 7,
  constraints = '{"+region=cn-east": 3, "+region=cn-north": 2, "+region=cn-south": 2}';

-- 将 lease 偏好设置在主地域,备选地域次之
ALTER DATABASE appdb CONFIGURE ZONE USING
  lease_preferences = '[[+region=cn-east], [+region=cn-north]]';

需要注意 lease_preferences 的语法是嵌套数组的形式,内层数组表示同一优先级内的多个可选项,外层表示优先级从高到低。上面的写法表示优先选择 cn-east 地域的副本,如果 cn-east 没有可用副本则退到 cn-north。这种写法在主备地域架构中非常实用,既能保证正常情况下 lease 稳定在主地域,又能在主地域整体故障时自动降级。

定位 lease 频繁转移的原因

当怀疑 lease 转移过于频繁时,第一步是看数据。CockroachDB 的 Web 控制台有专门的 Replication 面板,其中 Lease Transfers 图表展示了单位时间内 lease 转移的次数。除此之外,也可以直接查询系统表来统计当前每个 range 的 lease 位置:

-- 查看当前 lease 分布在哪些节点上
SELECT lease_holder, count(*) AS range_count
  FROM crdb_internal.ranges
 GROUP BY lease_holder
 ORDER BY range_count DESC;

-- 查看热点 range 的 lease 归属
SELECT range_id, database_name, table_name, lease_holder
  FROM crdb_internal.ranges
 WHERE table_name = 'orders'
 LIMIT 50;

拿到数据之后,重点观察转移的模式。如果转移集中在某个节点,多半是这个节点磁盘慢、CPU 过载或者网络抖动,导致它续约失败。如果转移是全局性的、周期性的,那大概率是配置层面的问题,比如有人频繁修改 zone 配置,或者 lease preference 指向的副本集合本身在不停变化。还有一种情况是节点存储即将耗尽触发了持续的 rebalance,副本在搬迁,lease 自然也跟着动。

排查时可以结合 crdb_internal.kv_flow_control_handles 和节点详细页面的网络与磁盘指标一起看。如果 lease 转移和磁盘写入延迟的毛刺在时间上对得上,基本可以断定是存储层的问题,应该先处理慢盘而不是改配置。

优化 locality 配置的实践建议

第一,对于跨地域集群,优先使用 geo-partitioning 而不是全局统一的 zone 配置。geo-partitioning 允许按行级别指定数据归属的地域,配合 regional 表或者分区级别的 lease preference,可以让数据和 lease 一起靠近用户。这样每个地域的用户请求基本都在本地闭环,跨地域流量只剩下 Raft 日志复制。

-- 创建区域化的分区表,每个分区独立配置副本与 lease
CREATE TABLE orders (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  region STRING NOT NULL,
  amount DECIMAL,
  created_at TIMESTAMPTZ DEFAULT now()
) PARTITION BY LIST (region);

ALTER TABLE orders PARTITION BY LIST (region) (
  PARTITION east VALUES IN ('cn-east'),
  PARTITION north VALUES IN ('cn-north')
);

ALTER PARTITION east OF TABLE orders
  CONFIGURE ZONE USING
    constraints = '{"+region=cn-east": 3}',
    lease_preferences = '[[+region=cn-east]]';

第二,locality 层级要设计得合理。不要在层级中混入会变化的属性,比如把实例编号或者临时标签写进 locality,这样会让约束匹配变得混乱。层级应该是 region、az、rack 这种稳定的物理结构,最多再加上 cloud 或 provider 描述混合云场景。层级写反(比如 rack 在前 region 在后)虽然不会报错,但会让后续基于前缀的约束表达非常别扭。

第三,避免对 lease preference 设置过多优先级层级。每一层偏好都是一个潜在的转移触发点,层级越多,系统在不同状态下重新评估 lease 位置的频率就越高。实践中两层偏好(主选加一个备选)通常是稳定性和容灾能力的最佳平衡。同时务必保证每个偏好层级下存在健康的副本,如果 preference 指向的地域一个副本都没有,系统会反复尝试匹配并产生大量无效的转移日志。

验证与监控配置效果

调整配置之后,建议用如下方式验证效果:先对比调整前后 Web 控制台中 Lease Transfers 曲线,理想状态下日常稳态的转移次数应该趋近于零,只有在节点重启或人为运维操作时出现尖峰。其次观察 P99 延迟的变化,lease 靠近用户后,跨地域往返的开销消失,读延迟的改善通常非常明显。

还可以在系统表中确认 lease 是否真正落到了预期的 locality 上,写一个定时任务把 crdb_internal.ranges 中 lease holder 节点的 locality 与期望值做比对,一旦出现偏移就告警。这种主动监控比事后排查要省心得多,特别是对于规模较大、range 数量上百万的集群,靠人工翻面板几乎不可能及时发现局部的 lease 漂移。

总结一下,range lease 频繁转移的根源大多是配置与拓扑不匹配:副本约束、lease preference、节点 locality 三者要形成一致的规划。把数据副本、lease 和用户流量放在同一个 locality 组里,是让 CockroachDB 跨地域集群稳定低延迟运行的核心原则。

CockroachDBrange leaselocality修改时间:2026-09-09 07:24:40

免责声明:已尽一切努力确保本网站所含信息的准确性。网站作品多为原创整理与精心创作,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们进行处理Email:chomcom@qq.com。
引用或转载本作品时,请注明当前出处:https://www.ipipp.com/html/20260909/53270.html,基于非商业用途的前提下,欢迎转载或二创本作品。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。