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

如果是传统强一致性读模式,客户端会优先选择主副本(Leader)进行读取,这样会导致两种问题:
- Leader 压力大,容易成为性能瓶颈。且如果 Leader 故障,会导致整个机房不可用。
- 广州和上海的用户读取数据,也要经过北京机房,导致网络延迟增加。
因此,我们引入了弱读和就近读的方式来解决这个问题:
- 弱读:允许客户端从非主副本(如 Follower 或 Replica)读取数据。此模式下读取数据会产生略微延迟,但能够提升读取性能和系统可用性。
- 就近读:客户端优先选择与自身地理位置或网络距离最近的机房副本读取数据,降低网络延迟,提高访问速度与用户体验。
支持版本
使用本功能需要满足 OceanBase 集群、ODP 和 OBKV-HBase 客户端版本要求:
| 组件 | 支持版本 |
|---|---|
| ObServer | 4.4.2.0 及以上 |
| ODP | 4.3.6.2 |
| OBKV-HBase | 2.5.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 |
步骤二:配置客户端弱读参数
参数说明
设置弱读的关键参数如下表所示:
| 参数 | 类型 | 是否大小写敏感 | 可选值 | 默认值 | 说明 |
|---|---|---|---|---|---|
| hbase.htable.read.consistency | String | 否 | "strong"、"weak" | "strong" |
|
| hbase.htable.client.idc | String | 否 | 实际机房名 | "" |
|
| hbase.htable.client.route.policy | String | 否 | "follower_first"、"follower_only" | "follower_first" |
|
参数设置优先级说明:目前 OBKV-HBase 支持全局参数和语句级别参数两种优先级,优先级为:语句级别参数 > 全局级别参数。以下列出支持的几种具体设置方式。
在配置文件中设置弱读全局参数
此方法适用于从原生 HBase 平滑迁移到 OBKV-HBase,且无需修改已有业务代码。你只需在 hbase-site.xml 或 core-site.xml 配置文件中设置弱读全局参数,便可实现弱读能力。
如下示例,通过在 hbase-site.xml 文件中设置 "hbase.htable.read.consistency" 为 "weak","hbase.htable.client.idc" 为 "idc1","hbase.htable.client.route.policy" 为 "follower_first",即可让查询操作优先路由到 "idc1" 机房的 follower 副本进行读取。
<configuration>
<property>
<name>hbase.htable.read.consistency</name>
<value>weak</value>
</property>
<property>
<name>hbase.htable.client.idc</name>
<value>idc1</value>
</property>
<property>
<name>hbase.htable.client.route.policy</name>
<value>follower_first</value>
</property>
</configuration>
在代码中设置弱读全局参数
此方法适用于需要修改代码的业务,你只需在代码中设置弱读全局参数,便可实现弱读能力。如下示例,通过在 configuration 中设置 "hbase.htable.client.idc" 为 "idc1","hbase.htable.client.route.policy" 为 "follower_first","hbase.htable.read.consistency" 为 "weak",即可让查询操作优先路由到 "idc1" 机房的 follower 副本进行读取。
import static com.alipay.oceanbase.hbase.constants.OHConstants.*;
Configuration config = HBaseConfiguration.create();
config.set(HBASE_HTABLE_CLIENT_IDC, "idc1"); // 设置客户端机房信息
config.set(HBASE_HTABLE_CLIENT_ROUTE_POLICY, "follower_first"); // 设置路由策略
config.set(HBASE_HTABLE_READ_CONSISTENCY, "weak"); // 设置一致性级别
在代码中设置语句级别弱读参数
此方法适用于需要修改代码的业务,你只需在代码中设置语句级别弱读参数,便可实现弱读能力。
这里给出几个不同场景的使用示例:
如下示例先在 configuration 中设置了 "hbase.htable.client.idc" 为 "idc1","hbase.htable.client.route.policy" 为 "follower_first";然后在 get 操作中,通过 setAttribute 设置 "hbase.htable.read.consistency" 为 "weak"。这样,在执行 get 操作时,会优先路由到 "idc1" 机房的 follower 副本。
String tableName = "test";
Configuration config = HBaseConfiguration.create();
config.set(HBASE_HTABLE_CLIENT_IDC, "idc1"); // 设置客户端机房信息
config.set(HBASE_HTABLE_CLIENT_ROUTE_POLICY, "follower_first"); // 设置路由策略
Connection hbaseConnection = ConnectionFactory.createConnection(config);
Table table = hbaseConnection.getTable(TableName.valueOf(tableName));
String family = "cf1";
String rowkey = "k1";
Get get = new Get(rowkey.getBytes());
get.setAttribute(HBASE_HTABLE_READ_CONSISTENCY, "weak".getBytes()); // 设置语句级别读一致性
get.addColumn(family.getBytes(), "q1".getBytes());
Result result = table.get(get);
如下示例先在 configuration 中设置了 "hbase.htable.client.idc" 为 "idc1","hbase.htable.client.route.policy" 为 "follower_first";然后在 list<get> 操作中,通过 setAttribute 设置 "hbase.htable.read.consistency" 为 "weak"。这样,在执行 list<get> 操作时,会优先路由到 "idc1" 机房的 follower 副本。
String tableName = "test";
Configuration config = HBaseConfiguration.create();
config.set(HBASE_HTABLE_CLIENT_IDC, "idc1"); // 设置客户端机房信息
config.set(HBASE_HTABLE_CLIENT_ROUTE_POLICY, "follower_first"); // 设置路由策略
Connection hbaseConnection = ConnectionFactory.createConnection(config);
Table table = hbaseConnection.getTable(TableName.valueOf(tableName));
List<Get> gets = new ArrayList<>();
String family = "cf1";
String rowkey1 = "k1";
// 同一批 get 中必须设置全部弱读,不支持部分弱读
Get get1 = new Get(rowkey1.getBytes());
get1.setAttribute(HBASE_HTABLE_READ_CONSISTENCY, "weak".getBytes()); // 设置语句级别读一致性
get1.addColumn(family.getBytes(), "q1".getBytes());
String rowkey2 = "k2";
Get get2 = new Get(rowkey2.getBytes());
get2.setAttribute(HBASE_HTABLE_READ_CONSISTENCY, "weak".getBytes()); // 设置语句级别读一致性
get2.addColumn(family.getBytes(), "q2".getBytes());
gets.add(get1, get2);
Result[] res = table.get(gets);
示例先在 configuration 中设置了 "hbase.htable.client.idc" 为 "idc1","hbase.htable.client.route.policy" 为 "follower_first";然后在 scan 操作中,通过 setAttribute 设置 "hbase.htable.read.consistency" 为 "weak"。这样,在执行 scan 操作时,会优先路由到 "idc1" 机房的 follower 副本。
String tableName = "test";
Configuration config = HBaseConfiguration.create();
config.set(HBASE_HTABLE_CLIENT_IDC, "idc1"); // 设置客户端机房信息
config.set(HBASE_HTABLE_CLIENT_ROUTE_POLICY, "follower_first"); // 设置路由策略
Connection hbaseConnection = ConnectionFactory.createConnection(config);
Table table = hbaseConnection.getTable(TableName.valueOf(tableName));
String family = "cf1";
String rowkey = "k1";
Scan scan = new Scan();
scan.withStartRow(rowkey.getBytes());
scan.setAttribute(HBASE_HTABLE_READ_CONSISTENCY, "weak".getBytes()); // 设置语句级别读一致性
scan.addColumn(family.getBytes(), "q1".getBytes());
ResultScanner resultScanner = table.getScanner(scan);
Result result;
while ((result = resultScanner.next()) != null) {
byte[] value = result.getValue(family.getBytes(), "q1".getBytes());
}
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';
步骤三:配置客户端弱读参数
参考 直连模式使用步骤-步骤二:配置客户端弱读参数 中的示例,设置弱读参数。