首批通过分布式安全可靠测评,为关键业务系统打造
OBKV-Table 弱读和就近读
更新时间:2026-07-23 19:56:22
OBKV-Table 支持弱一致性读和就近机房读特性,本文档介绍了弱读和就近读的原理、支持版本、路由策略、使用方法。
传统强一致性读模式,容易导致高并发或低延迟场景下的性能瓶颈。为此,OBKV-Table 支持弱一致性读(Weak Read,下文简称弱读)和就近机房读(Near Read,下文简称就近读),帮助用户更灵活地平衡数据一致性与访问效率。
原理
想象一个场景,你的数据库部署在多个机房(比如北京、上海、广州),数据会复制多份。

如果是传统强一致性读模式,客户端会优先选择主副本(Leader)进行读取,这样会导致两种问题:
- Leader 压力大,容易成为性能瓶颈。且如果 Leader 故障,会导致整个机房不可用。
- 广州和上海的用户读取数据,也要经过北京机房,导致网络延迟增加。
因此,我们引入了弱读和就近读的方式来解决这个问题:
- 弱读:允许客户端从非主副本(如 Follower 或 Replica)读取数据。此模式下读取数据会产生略微延迟,但能够提升读取性能和系统可用性。
- 就近读:客户端优先选择与自身地理位置或网络距离最近的机房副本读取数据,降低网络延迟,提高访问速度与用户体验。
支持版本
使用本功能需要满足 OceanBase 集群、ODP 和 OBKV-Table Java 客户端版本要求:
| 组件 | 支持版本 |
|---|---|
| ObServer | 4.4.2.0 及以上 |
| ODP | 4.3.6.2 |
| OBKV-Table | 2.3.0 |
直连模式使用步骤
步骤一:配置 OceanBase 集群 IDC
使用 root@sys 登录 OceanBase 集群,按照以下步骤配置 OceanBase 集群的机房信息。假设集群包含三个 Zone,每个 Zone 下有一个 OBServer 节点,示例中每个 Zone 的 IP 分别为 10.0.0.1、10.0.0.2、10.0.0.3:
设置
z1的地区。REGION参数用于指定 Zone 所在的地域信息,建议使用城市名(大小写敏感)。ALTER SYSTEM MODIFY ZONE "z1" SET REGION = "SHANGHAI";设置
z1的机房。IDC参数用于指定 Zone 所在的机房信息,建议使用机房名(小写)。ALTER SYSTEM MODIFY ZONE "z1" SET IDC = "zue";
完成后,集群部署情况如下表所示:
| OBServer 节点 IP | Zone | IDC | Region |
|---|---|---|---|
| 10.0.0.1 | z1 | zue | SHANGHAI |
| 10.0.0.2 | z2 | xue | SHANGHAI |
| 10.0.0.3 | z3 | yue | HANGZHOU |
步骤二:配置客户端弱读参数
接口和参数说明
| 接口 | 参数说明 | 是否大小写敏感 | 可选值 | 功能说明 |
|---|---|---|---|---|
| public void setReadConsistency(ObReadConsistency readConsistency) | readConsistency:一致性级别 | 否 |
|
一致性级别,用于控制是否开启弱读:
|
| public void setCurrentIDC(String idc) | idc:客户端所在机房名 | 否 | 实际机房名 | 客户端所在机房名:
|
| public void setRoutePolicy(ObRoutePolicy policy) | policy:路由策略 | 否 |
|
路由策略:
|
参数设置优先级说明:目前 OBKV-Table 支持全局参数和语句级别参数两种优先级,优先级为:语句级别参数 > 全局级别参数。以下列出支持的几种具体设置方式。
在 ObTableClient 中设置弱读全局参数
如下示例展示了如何在 ObTableClient 中设置弱读相关参数:将一致性级别设为 ObReadConsistency.WEAK,指定客户端当前机房为 "idc1",并选择 ObRoutePolicy.FOLLOWER_FIRST 路由策略。配置完成后,查询操作会优先路由到 "idc1" 机房的 follower 副本,从而实现性能提升和延迟降低。
ObTableClient client = new ObTableClient();
... // 设置其他连接参数
client.setCurrentIDC("idc1");
client.setReadConsistency(ObReadConsistency.WEAK);
client.setRoutePolicy(ObRoutePolicy.FOLLOWER_FIRST);
client.init();
在查询中设置语句级别的弱读参数
示例在 ObTableClient 中设置客户端当前所在机房为 "idc1",路由策略为 ObRoutePolicy.FOLLOWER_FIRST;在 get 操作中设置了一致性级别为 ObReadConsistency.WEAK;这样,在进行 get 操作时,会优先路由到 "idc1" 机房的 follower 副本。
ObTableClient client = new ObTableClient();
... // 设置其他连接参数
client.setCurrentIDC("idc1"); // 设置当前 idc
client.setRoutePolicy(ObRoutePolicy.FOLLOWER_FIRST); // 设置路由策略
client.init();
String tableName = "test";
String rowkey = "key";
Map<String, Object> result = client.get(tableName).setRowKey(row(colVal("c1", rowkey)))
.setReadConsistency(ObReadConsistency.WEAK) // 设置弱一致性读
.select("c2").execute();
示例在 ObTableClient 中设置客户端当前所在机房为 "idc1",路由策略为 ObRoutePolicy.FOLLOWER_FIRST;在 BatchOperation 接口中设置了一致性级别为ObReadConsistency.WEAK;这样,在进行 batch get 操作时,会优先路由到 "idc1" 机房的 follower 副本。
ObTableClient client = new ObTableClient();
... // 设置其他连接参数
client.setCurrentIDC("idc1"); // 设置当前 idc
client.setRoutePolicy(ObRoutePolicy.FOLLOWER_FIRST); // 设置路由策略
client.init();
String tableName = "test";
String rowkey1 = "key1";
String rowkey2 = "key2";
BatchOperation batch = client.batchOperation(tableName);
batch.setReadConsistency(ObReadConsistency.WEAK); // 设置弱一致性读。注意:同一批 get 中必须设置全部弱读,不支持部分弱读
Get get1 = client.get(tableName).setRowKey(row(colVal("c1", rowkey1)))
.select("c2");
Get get2 = client.get(tableName).setRowKey(row(colVal("c1", rowkey2)))
.select("c2");
batch.addOperation(get1, get2);
BatchOperationResult res = batch.execute();
示例在 ObTableClient 中设置客户端当前所在机房为 "idc1",路由策略为 ObRoutePolicy.FOLLOWER_FIRST;在 query 操作中设置了一致性级别为 ObReadConsistency.WEAK;这样,在进行 query 操作时,会优先路由到 "idc1" 机房的 follower 副本。
ObTableClient client = new ObTableClient();
... // 设置其他连接参数
client.setCurrentIDC("idc1"); // 设置当前 idc
client.setRoutePolicy(ObRoutePolicy.FOLLOWER_FIRST); // 设置路由策略
client.init();
String tableName = "test";
String startRowkey = "key1";
String endRowkey = "key5";
QueryResultSet res = client.query(tableName)
.addScanRange(new Object[] { startRowkey }, new Object[] { endRowkey })
.setScanRangeColumns("c1")
.setReadConsistency(ObReadConsistency.WEAK)
.select("c2")
.execute();
while (res.next()) {
Map<String, Object> valueMap = res.getRow();
System.out.println(valueMap.get("c2"));
}
ODP 模式使用步骤
步骤一:配置 OceanBase 集群 IDC
使用 root@sys 登录 OceanBase 集群,按照以下步骤配置集群的机房与地区信息。假设集群包含三个 Zone,每个 Zone 下有一个 OBServer 节点,以下以 z1 的配置为例:
设置 z1 的地区。
REGION参数用于指定 Zone 所在地域信息,建议设置为城市名(大小写敏感)。ALTER SYSTEM MODIFY ZONE "z1" SET REGION = "SHANGHAI";设置 z1 的机房。
IDC参数用于指定 Zone 所在机房信息,建议设置为机房实际名称(小写)。ALTER SYSTEM MODIFY ZONE "z1" SET IDC = "zue";
完成后,集群部署信息如下表所示:
| OBServer 节点 IP | Zone | IDC | Region |
|---|---|---|---|
| 10.0.0.1 | z1 | zue | SHANGHAI |
| 10.0.0.2 | z2 | xue | SHANGHAI |
| 10.0.0.3 | z3 | yue | HANGZHOU |
步骤二:配置 ODP 弱读参数
通过设置
proxy_idc_name参数,可以指定 ODP 在 LDC 体系中所属的机房,结合实际部署,可以让弱读流量更优地路由到对应机房的副本。比如,将所有弱读请求优先路由至 z1 所在的机房,可参考如下配置:ALTER PROXYCONFIG SET proxy_idc_name = 'zue';通过设置
proxy_route_policy参数,可以进一步指定副本路由策略。下例为优先读取 Follower 副本:ALTER PROXYCONFIG SET proxy_route_policy = 'follower_first';
步骤三:配置客户端弱读参数
参考 直连模式使用步骤-步骤二:配置客户端弱读参数 中的示例,设置弱读参数。