暂无图片
暂无图片
3
暂无图片
暂无图片
暂无图片

OceanBase 弱读运维实战:配置、优先级与避坑指南

原创 金同学 6天前
101

适用版本:OceanBase 4.x + ODP 4.x。本文结论均基于 OB 4.2.5 / ODP 4.3.x 行为整理。

一、什么是弱读

弱读(弱一致性读):读请求可以走备副本,允许读到的数据不是最新的,但保证版本单调递增(不会越读越旧),同时把压力从主副本分摊到备副本。

对比项 强读 (STRONG) 弱读 (WEAK)
读哪个副本 leader 备副本(follower)
数据新鲜度 保证最新已提交 允许滞后,但版本单调递增
主副本压力 全部在 leader 分散到备副本
典型场景 交易、实时业务 报表、历史查询、对延迟不敏感的业务

注意:集群没有备副本时,弱读请求仍会落到 leader。

二、弱读的两种路由策略

弱一致性读有两种路由策略,读写分离和LDC路由。其中LDC路由的优先级高于读写分离,ODP在选择副本的时候,先检查LDC路由,再走读写分离路由。

2.1 读写分离

设置路由策略

某些场景下,我们希望将分析型的查询请求发送到从副本执行,此时就可以使用读写分离路由策略,通过将读请求发送到备副本,降低主副本的压力。

ODP通过配置项 proxy_route_policy 设置路由策略:

  • follower_first:弱读请求优先路由到备副本,如果备副本都不可用,弱读请求路由到主副本。
  • follower_only:弱读请求路由到备副本,如果备副本都不可用,断开和客户端的连接。

场景一

# 路由策略 alter proxyconfig set proxy_route_policy=''; # ODP 在z1、z2、z3 三个副本随机选择副本转发弱读请求 SELECT /*+READ_CONSISTENCY(WEAK) */ * FROM T; # primary zone1;zone2,zone3

场景二

# 路由策略 alter proxyconfig set proxy_route_policy='FOLLOWER_FIRST'; # ODP 优先选择z2、z3 转发弱读请求,如果z2、z3都不可用,则转发到z1 SELECT /*+READ_CONSISTENCY(WEAK) */ * FROM T;

场景三

# 路由策略 alter proxyconfig set proxy_route_policy='FOLLOWER_ONLY'; # ODP 只选择z2、z3 转发弱读请求,如果z2、z3都不可用,则请求报错 SELECT /*+READ_CONSISTENCY(WEAK) */ * FROM T;

2.2 LDC路由

OceanBase 数据库作为典型的高可用分布式关系型数据库,使用 Paxos 协议进行日志同步,天然支持多地多中心的部署方式以提供高可靠的容灾保证。但当采用多地多中心的部署架构时,弱一致性读会均匀访问数据的所有主从副本,当访问非本地域机房上的副本时,系统响应时间将大大增加。

引入逻辑数据中心(Logical Data Center,LDC)路由正是为了解决这一问题,通过给 OceanBase 集群的每个 Zone 设置 Region 属性和IDC 属性,并给 ODP 指定 IDC 名称配置项后,当数据请求发到 ODP 时,ODP将弱读请求按“同机房>同地区>异地”的优先级顺序进行OBServer 的选取。

  • LDC的路由设置需要三个步骤:配置 OceanBase 集群、配置 ODP、应用配置弱一致性读。
    image.png

1> OB集群LDC配置

  1. 使用 root 用户登录集群的 sys 租户
  2. 登录后,执行以下示例语句配置 LDC
ALTER SYSTEM MODIFY zone "zone1" SET region = "Shanghai"; ALTER SYSTEM MODIFY zone "zone1" SET idc = "Jiading"; ALTER SYSTEM MODIFY zone "zone2" SET region = "Zhejiang"; ALTER SYSTEM MODIFY zone "zone2" SET idc = "Hangzhou"; ALTER SYSTEM MODIFY zone "zone3" SET region = "Shanghai"; ALTER SYSTEM MODIFY zone "zone3" SET idc = "Waigaoqiao";

集群节点与LDC配置信息示例

OBServer 节点 IP Zone IDC Region
10.0.0.1 zone1 Jiading Shanghai
10.0.0.2 zone2 Hangzhou Zhejiang
10.0.0.3 zone3 Waigaoqiao Shanghai
  1. 检查 OBServer 节点中 LDC 设置内容是否生效
select * from dba_ob_zones;

2> ODP的LDC配置
通过配置 proxy_idc_name 指定 ODP 在 LDC 逻辑中所处的位置。

  1. sys租户登陆,修改ODP的proxy_idc_name配置
ALTER PROXYCONFIG SET proxy_idc_name= 'Hangzhou';
  1. 为 ODP 配置 LDC 后可通过下述语句检查配置是否生效。
SHOW PROXYINFO IDC;

2.3 最佳实践

在odp上操作

# 第1步:开启弱读 ALTER PROXYCONFIG SET obproxy_read_consistency = 1; # 第2步:设置路由策略。 在允许弱读的前提下,优先Follower节点 ALTER PROXYCONFIG SET proxy_route_policy = 'follower_first'; # 第3步:proxy_idc_name 参数决定就近范围,路由时优先选本机房的observer follower副本。前提条件:observer已配置IDC机房信息。 alter PROXYCONFIG set proxy_idc_name = 'Hangzhou'; # odp所在机房

注意:

在 ODP 架构下,当ODP开启弱读后,即使把 observer 全局参数 ob_read_consistency 改成 STRONG,请求不会因此路由到leader副本,ODP 路由按自己的判断发备follower副本。而observer全局参数 ob_read_consistency 主要用于observer直连场景。

三、弱读怎么配,优先级规则?

以上讲了 ODP 架构的弱读配置,但实际场景里大家还会遇到 hint、会话变量、ODP、Observer 甚至 OMS 里的弱读配置,它们各自管什么、怎么配、优先级谁高谁低,一直困扰不少人,下面是我的一些总结,希望帮助到你。

3.1 不同客户端的弱读配置

方式 配置位置 生效范围 适用场景
SQL hint SQL 语句内 单条语句 精准控制、临时验证
会话变量 ob_read_consistency=2 客户端 SET / JDBC 连接参数 单个连接 按连接分流
ODP 参数 obproxy_read_consistency=1 OCP 修改代理参数 ALTER PROXYCONFIG ODP 上所有新老会话 全局弱读(推荐)
observer 全局 ob_read_consistency ALTER SYSTEM SET 内核执行语义 仅直连 observer 场景

3.2 使用示例

示例 1:单条 SQL 弱读(hint,最高优先级)

SELECT /*+ READ_CONSISTENCY(WEAK) */ * FROM orders WHERE user_id = 1001;

示例 2:当前连接弱读(会话变量)

SET ob_read_consistency = 2; -- 1=FROZEN, 2=WEAK, 3=STRONG

示例 3:JDBC 连接池级别弱读

jdbc:oceanbase://10.0.0.1:2883/mydb?sessionVariables=ob_read_consistency=2

示例 4:整个 ODP 弱读(推荐)

-- 以 root@proxysys 连接 ODP 执行,或在 OCP 的代理参数中修改 ALTER PROXYCONFIG SET obproxy_read_consistency = 1; -- 1=follower 弱读,0=leader(默认)

示例 5:直连 observer 场景(无 ODP)

ALTER SYSTEM SET ob_read_consistency = 'WEAK'; -- 全局;主要影响新会话

验证弱读是否生效(两条路)

  1. ODP 日志关键字:current use weak read(需相应日志级别)
  2. OCP

3.3 优先级规则

优先级从高到低:

层级 来源 说明
1 SQL hint /*+ READ_CONSISTENCY(WEAK) */ 最高
2 客户端会话变量(SET / JDBC sessionVariables) 连接级;ODP 参数不变时不会被覆盖
3 ODP 参数 obproxy_read_consistency 连接时自动注入为会话变量(1→WEAK);参数变更时重新注入、反压客户端设置
4 observer 全局变量 ob_read_consistency 直连场景的主开关;ODP 架构下不参与路由
说明:
  1. 优先级上,一般情况客户端高于 ODP;但运维在 OCP 改了 obproxy_read_consistency 后,ODP 会重新注入并覆盖客户端已 SET 的值。
  2. ODP 参数变更后(OCP 修改),存量连接无需重连:配置同步完成后,下一个请求自动生效。

ODP 弱读参数的内部转换规则如下:

# ODP弱读参数在会话建连时转换规则 obproxy_read_consistency=1 '1 表示follower,自动注入会话变量:SET ob_read_consistency=2(WEAK)' obproxy_read_consistency=0 '0 表示leader(默认值),自动注入会话变量:SET ob_read_consistency=3(STRONG)'

四、避坑指南

1. 读写分离兜底陷阱
ODP 打开 enable_read_write_split=true 之后(默认 false),非事务里的 SELECT 只要没写 hint STRONG,就会默认走弱读。这个时候 obproxy_read_consistency=0、SET ob_read_consistency=3 都不管用。如果遇到"配了强读结果还是读到了备副本",就先检查这个开关。

# 弱读参数 ob_read_consistency=2 # 设置数字2,表示WEAK ob_read_consistency=3 # 设置数字3,表示STRONG

2. 参数设成 1 之后,客户端的 SET 会被拒绝
obproxy_read_consistency=1 生效后,会话会被标记成 follower 用户,这时候再执行 SET ob_read_consistency,ODP 会直接报错拒掉(set ob_read_consitency is not allowed)。唯一的例外是 SQL hint 还能盖过去。

3. 优先用 SQL hint
需要"整体弱读、个别业务强读"的话,ODP 参数配 1,个别 SQL 加 /*+ READ_CONSISTENCY(STRONG) */;反过来也一样。再有一种建议,是单独部署一个"弱读专属"的 ODP。

4. 弱读生效条件

  • 语句是 SELECT(非 SELECT 一律强读)
  • 非 FOR UPDATE
  • 不在事务中(事务内默认强读,除非配了 enable_transaction_split)
  • 集群存在可用备副本/只读区
  • server 版本支持弱读

5. observer 全局变量 ≠ ODP 弱读开关
想让 ODP 上的流量走弱读,应该配 ODP 参数或客户端 hint/SET;改 observer 全局 ob_read_consistency 只影响"到了 server 后怎么读",不会产生弱读路由。

五、弱读速查

单条弱读:   SELECT /*+ READ_CONSISTENCY(WEAK) */ ...
连接弱读:   SET ob_read_consistency = 2;
全局弱读:   ODP: obproxy_read_consistency = 1 (OCP / ALTER PROXYCONFIG)
优先级:     hint > 客户端 SET > ODP 参数 > observer 全局
生效条件:   非事务 SELECT + 有备副本 + 无 FOR UPDATE
头号大坑:   enable_read_write_split 开启后默认弱读,强读只能靠 hint
最后修改时间:2026-09-30 09:08:45
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

文章被以下合辑收录

评论