---
title: "OceanBase 读写分离最佳实践 - OceanBase 最佳实践 | OceanBase 文档中心"
description: OceanBase 读写分离最佳实践 为缓解企业数据库的读写压力，降低读写操作之间的相互影响，OceanBase 数据库提供了读写分离的能力，将读写操作分开处理，提升系统的响应速度，助力企业构建高效稳定的数据库系统。本文结合 OceanBase 数据库的弱一致性读原理，解读了 OceanBase 数据库内读写分离的实…
image: https://mdn.alipayobjects.com/huamei_22khvb/afts/img/A*OSPzQ6GUQF4AAAAAQHAAAAgAeiGDAQ/original
---
切换语言

- 中文站 - 简体中文
- International - English
- 日本站 - 日本語

# OceanBase 读写分离最佳实践

更新时间：2026-07-28

[编辑](https://github.com/oceanbase/best-practices-doc/edit/master/zh-CN/50.deploy/500.read-write-separation-best-practices.md) 适用产品： OceanBase 数据库 适用场景： 安装部署  

为缓解企业数据库的读写压力，降低读写操作之间的相互影响，OceanBase 数据库提供了读写分离的能力，将读写操作分开处理，提升系统的响应速度，助力企业构建高效稳定的数据库系统。本文结合 OceanBase 数据库的弱一致性读原理，解读了 OceanBase 数据库内读写分离的实现方式及配置方法。

## V4.X OceanBase 读写分离最佳实践

### 弱一致性读

在分布式系统中，数据库天然的多副本特性决定了数据读取支持多种一致性读。强一致性读保证读操作的可线性化，即总是可以读到最新版本的数据；相对的，弱一致性读则无法保证在每一次读取时，一定能够读到最新的数据。

OceanBase 数据库是基于 Multi-Paxos 的分布式数据库，数据以多副本的形式保存在不同的 Zone 或者节点上。在数据更新的时候，主（Leader）副本负责承担修改语句的执行，同时同步 clog 提交日志到其他副本节点，只要包含 Leader 副本在内的多数派副本的日志落盘，事务就算提交成功。在这个过程中，一定有除 Leader 副本以外的其他副本节点进行了日志持久化，保证了容灾的能力；同时， Leader 副本之外的其他多数派节点并不保证日志落盘以后，完成 Follower 副本的更新回放，因此，相比 Leader 副本的数据来说，可能存在落后的数据状态的副本。

OceanBase 数据库提供了两种一致性级别（Consistency Level）：STRONG 和 WEAK。STRONG 指强一致性，即读取最新数据，将请求路由给 Leader 副本；WEAK 指弱一致性，即不要求读取最新数据，将请求优先路由给 Follower 副本。OceanBase 数据库的写操作始终为强一致性，即始终由 Leader 副本提供服务；读操作默认也是强一致性，由 Leader 副本提供服务，用户也可以根据需要指定弱一致性读，由 Follower 副本优先提供读服务。

在一些数据访问时效不敏感的业务中，通过从 Leader 副本写入数据，再从 Follower 副本读取数据，可以实现数据的读写分离，从而充分利用资源，提高数据库读取的运行效率。在该场景下，Follower 副本的数据访问属于弱一致性读，为了便于对数据读取延迟的控制，OceanBase 数据库提供了租户级配置项 [max_stale_time_for_weak_consistency](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000001035564) 来定义最大的弱读落后的容忍时间，即有界旧（Bounded Staleness）一致性读，保证读取的数据不会落后于最新数据的特定时间，默认为 5 秒。如果一个副本的落后时间超过该阈值，则该副本将不可读，内部重试机制会重试其他有效副本；如果所有副本都不可读，则持续重试，直到语句超时。

不同的弱一致性读请求会路由到不同的副本上，不同副本上读到的数据即使保证了有界旧一致性读，却无法保证多个请求之间数据的新旧，因此，OceanBase 数据库又提供了另外的单调（Monotonic）读一致性的特性，通过设置租户级配置项 [enable_monotonic_weak_read](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000001035609) 来保证。其实现方式是，如果进程已经看到过数据对象的某个值，则任何后续访问均不会再返回该值之前的值。这样，在满足用户弱一致性读的同时，也实现了弱一致性读的版本单调性。

### 集群内的读写分离

由于 OceanBase 集群的 SQL 读写均默认路由到 Leader 副本执行，为了减轻 Leader 副本节点的业务压力，充分利用节点资源，我们可以在多副本配置的集群内，借助 OceanBase 数据库代理 (（OceanBase Database Proxy，ODP）) 的路由能力，由 Leader 副本实现强读和写，弱读由就近的 Follower 副本承担，从而实现读写分离。

一个业务系统对数据库的访问，有的 SQL 的访问需要强读，有的需要弱读，因此，集群内的读写分离有一个重要的问题，需要明确哪些业务 SQL 是强一致性读，哪些业务 SQL 是弱一致性读。也就是说，弱读的执行粒度是 SQL 级别。通常，我们可以在应用程序中进行如下设置：

- 直接指定只读 SQL 要求弱读，即 SQL 级别弱读。
 - 指定当前 Session 中所有读取 SQL 均为弱一致性读。

另外，对于弱读的 SQL 请求，ODP 提供了路由选项来指定请求路由的行为，可以根据副本物理位置、副本类型等将 SQL 发送到期望的副本上执行读取操作。

#### 配置弱一致性读相关的配置项

配置弱一致性读前，需要根据实际环境配置以下配置项，以明确弱读的预期行为。

| 配置项名称 | 默认值 | 生效范围 | 描述 | 设置建议及影响 |
| --- | --- | --- | --- | --- |
| enable_monotonic_weak_read | False | 租户级 | 是否开启单调读 | 根据业务实际场景，按需调整 |
| max_stale_time_for_weak_consistency | 5 秒 | 租户级 | 弱一致性读的 最大落后时间 | 建议保持默认值。 |
| weak_read_version_refresh_interval | 50 毫秒 | 集群级 | 弱一致性读版本号的刷新周期 | - 建议保持默认值。 - 值为 `0` 时将关闭单调读能力。 - 值过大（例如，超过配置项 `max_stale_time_for_weak_consistency` 的值）将会因为 Follower 副本落后过多，无法提供弱读。 |

#### 选择路由策略来配置读写分离

当应用程序访问 OceanBase 集群时，弱读支持以下路由策略：

- 主备均衡路由：弱读请求可以路由到 Leader 副本读取，也可以路由到 Follower 副本读取，流量按照副本均匀分配。
 - 备优先读策略：客户端的弱读请求总是优先读取 Follower 副本，而非主备均衡选择。

##### 主备均衡路由策略

主备均衡路由策略为默认策略，即是设置了应用弱一致性读之后的默认路由行为。仅需要指定 SQL 语句的弱一致性读，无需再进行其他设置，集群部署也为常规部署。

设置 SQL 语句为弱一致性读的方法如下：

- 通过 SQL 中携带 Hint 来指定弱一致性读

  该方式仅对该条 SQL 有效。示例如下：

  ```shell
  obclient> SELECT /*+read_consistency(weak)*/ * FROM t1;

  ```
 - 通过 Session 级变量来指定弱一致性读

  该方式仅对当前 Session 生效。示例如下：

  ```shell
  obclient> SET ob_read_consistency='weak';

  ```
 - 通过 Global 级变量来指定弱一致性读

  该方式对该租户的所有连接均会生效。示例如下：

  ```shell
  obclient> SET GLOBAL ob_read_consistency='weak';

  ```

#### 说明

由于应用的数据库访问通常是强读和弱读混合的情况，故一般使用前两种方式来指定 SQL 弱一致性读。

##### 备优先读策略

该路由策略主要通过 ODP 配置项 `proxy_route_policy` 或者用户级系统变量 `proxy_route_policy` 来控制备优先读路由，优先读 Follower 副本, 而非主备均衡选择，集群部署为常规部署即可。配置方法如下：

1. 配置集群内所有 Zone 的 LDC，包括 REGION 和 IDC。

   部署 OceanBase 集群时，如果未配置 REGION 和 IDC 的值，则默认 REGION 的值为 `default_region`， IDC 的值为空。为目标 Zone 配置 REGION 和 IDC 的方法如下：

      1. 使用 `root` 用户登录 OceanBase 集群的 `sys` 租户。
      2. 通过 `ALTER SYSTEM MODIFY ZONE` 命令修改 Zone 的 REGION 和 IDC。

        以下示例中，`REGION` 通常设置为城市名（大小写敏感）。`IDC` 代表该 Zone 所处的机房信息，通常设置为机房名（小写），`z1` 为当前设置的 Zone 的名称。它们的关系是一个 OceanBase 集群中有若干个 Region，一个 Region 有若干个 Zone，一个 Zone 对应一个 IDC 属性。

        ```shell
        obclient> ALTER SYSTEM MODIFY ZONE z1 SET REGION= 'SHANGHAI';

        ```

        ```shell
        obclient> ALTER SYSTEM MODIFY ZONE z1 SET IDC = 'zue';

        ```
      3. 验证配置是否成功。

        ```shell
        obclient> SELECT * FROM oceanbase.DBA_OB_ZONES;

        ```
 2. 配置 ODP 的 LDC。

      1. 使用 `root` 用户通过 ODP 登录 OceanBase 集群的 `sys` 租户。
      2. 通过 `ALTER PROXYCONFIG` 命令修改 ODP 的 IDC。

        以下示例中，`proxy_idc_name` 用于指定 ODP 所属的 IDC，用于区分与 OBServer 节点是否为同一个 IDC，进而根据路由规则确定路由方式，将请求就近路由到本 IDC 的 ODP。

        ```shell
        obclient> ALTER PROXYCONFIG SET proxy_idc_name='zue';

        ```
      3. 确认配置是否成功。

        ```shell
        obclient> SHOW PROXYINFO IDC;

        ```
 3. 配置 OceanBase 数据库用户的 ODP 弱读请求路由策略。

      1. 使用 `root` 用户通过 ODP 登录 OceanBase 集群的 `sys` 租户。
      2. 配置 ODP 的路由策略。

        支持通过 ODP 配置项 `proxy_route_policy` 或者用户变量 `proxy_route_policy` 来配置路由策略。主要有以下几种路由选项：

             - `follower_first`：默认值，表示将弱读请求优先路由到 Follower 副本，即使该 Follower 副本在合并状态。如果 Follower 副本均不可用，将弱读请求路由到 Leader 副本。
             - `follower_only`：表示将弱读请求路由到 Follower 副本，如果 Follower 副本均不可用，断开与客户端的连接。

        配置示例如下：

             - 通过 ODP 配置项 `proxy_route_policy` 设置将弱读请求优先路由到同机房的 Follower 副本。

              该方式对所有会话均生效。

              ```shell
              obclient> ALTER PROXYCONFIG SET proxy_route_policy='follower_first';

              ```
             - 通过用户变量 `proxy_route_policy` 设置将弱读请求优先路由到同机房的 Follower 副本。

              该方式需要在每一次会话中都进行设置。

              ```shell
              obclient> SET @proxy_route_policy='follower_first';

        ```shell
        obclient> SHOW PROXYSESSION VARIABLES;

        ```
 4. 配置 SQL 语句为弱一致性读。

      1. 用户租户通过 ODP 方式登录 OceanBase 集群。
      2. 指定 SQL 语句为弱一致性读。

              ```  

#### 备副本延迟阈值

读写分离部署场景下，ODP 会优先将弱读请求转发到 Follower 副本，而 Follower 副本所保存的数据与 Leader 副本的最新数据存在一定的延迟，导致弱读请求读取 Follower 副本的数据时读到的可能不是最新数据。针对该场景，ODP 和 OceanBase 数据库提供了备副本延迟阈值的功能来控制弱读数据的最大延迟时间。有关备副本延迟阈值的详细介绍及配置，参见 [备副本延迟阈值](https://www.oceanbase.com/docs/common-odp-doc-cn-1000000001409940)。

### 在驱动上配置弱一致性读

#### Java 驱动（OceanBase Connector/J）

OceanBase Connector/J（JDBC）支持在 URL 串中增加 `sessionVariables=ob_read_consistency=weak` 来设置弱读，也就是说，可以通过设置 JDBC 会话级的变量来指定弱读，且该方式仅对当前会话生效。如果希望通过该 JDBC 连接接入数据库的所有请求都执行弱读，可以设置该参数。示例如下：

```shell
jdbc:oceanbase://172.xx.xx.xx:2881/test?useSSL=false&useServerPrepStmts=true&sessionVariables=ob_read_consistency=weak

```

有关如何使用 OceanBase Connector/J 驱动连接并接入 OceanBase 数据库的详细操作及说明，参见 [创建 Java 示例应用程序](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000001033244)。

#### OceanBase Connector/ODBC

无专门的弱读设置，依赖于 SQL 或者数据库变量参数来控制弱读。

### 验证 SQL 弱读

配置成功后，可以通过查询 `GV$OB_SQL_AUDIT` 视图中的 `consistency_level` 字段来确定 SQL 是否执行了弱读。示例如下：

1. 创建表 `tbl1`。

   ```shell
   obclient> CREATE TABLE tbl1(id int);

   ```
 2. 向表中插入数据，并显示提交事务。

   ```shell
   obclient> INSERT INTO tbl1 VALUES(100);

   ```

   ```shell
   obclient> COMMIT;

   ```
 3. 分别执行以下 SQL 语句。

   ```shell
   obclient> SELECT * FROM tbl1;

   ```

   ```shell
   obclient> SELECT /*+read_consistency(weak)*/ * FROM tbl1;

   ```
 4. 查询 `GV$OB_SQL_AUDIT` 视图。

   ```shell
   obclient> SELECT svr_ip,query_sql,consistency_level FROM oceanbase.GV$OB_SQL_AUDIT WHERE query_sql LIKE '%FROM tbl1';

   ```

   查询结果的示例如下：

   ```shell
   +----------------+------------------------------------------------+-------------------+
   | svr_ip         | query_sql                                      | consistency_level |
   +----------------+------------------------------------------------+-------------------+
   | 172.xx.xx.34   | SELECT * FROM tbl1                             |                 3 |
   | 172.xx.xx.35   | SELECT /*+read_consistency(weak)*/ * FROM tbl1 |                 2 |
   +----------------+------------------------------------------------+-------------------+
   2 rows in set

   ```

   查询结果中，一致性级别为 `3` 表示强一致性读，为 `2` 表示弱一致性读。

## V3.X OceanBase 读写分离最佳实践

在一些数据访问时效不敏感的业务中，通过从 Leader 副本写入数据，再从 Follower 副本读取数据，可以实现数据的读写分离，从而充分利用资源，提高数据库读取的运行效率。在该场景下，Follower 副本的数据访问属于弱一致性读，为了便于对数据读取延迟的控制，OceanBase 数据库提供了租户级配置项 [max_stale_time_for_weak_consistency](https://www.oceanbase.com/docs/enterprise-oceanbase-database-cn-10000000000945181) 来定义最大的弱读落后的容忍时间，即有界旧（Bounded Staleness）一致性读，保证读取的数据不会落后于主集群最新数据的特定时间，默认为 5 秒。如果备集群落后超过该阈值，则读操作会重试等待，直到超时或者备集群追上主集群，或者选择其他副本（主集群）。

不同的弱一致性读请求会路由到不同的副本上，不同副本上读到的数据即使保证了有界旧一致性读，却无法保证多个请求之间数据的新旧，因此，OceanBase 数据库又提供了另外的单调（Monotonic）读一致性的特性，通过设置租户级配置项 [enable_monotonic_weak_read](https://www.oceanbase.com/docs/enterprise-oceanbase-database-cn-10000000000945177) 来保证。其实现方式是，如果进程已经看到过数据对象的某个值，则任何后续访问均不会再返回该值之前的值。这样，在用户能够接受的数据弱一致性读的同时，也实现了弱一致性读的版本单调性。

### 单个集群内的读写分离

由于 OceanBase 集群的 SQL 读写均默认路由到 Leader 副本执行，为了减轻 Leader 副本节点的业务压力，充分利用节点资源，我们可以在多副本配置的集群内，借助 OceanBase 数据库代理 (（OceanBase Database Proxy，ODP）) 的路由能力，由 Leader 副本实现强读和写，弱读由就近的 Follower 副本承担，从而实现读写分离。

#### 选择路由策略配置读写分离

当应用程序访问 OceanBase 集群时，弱读支持以下路由策略：

  ```

        ```

        ```shell
        obclient> SELECT * FROM oceanbase.__all_zone;

        配置示例如下：

              ```  

### 主备集群的读写分离

在传统数据库中，不少只读类的报表业务由于对数据及时性的敏感度较低，DBA 会将该类应用业务迁移至备库之行，既可以满足统计查询业务需求，也减少了主库的压力。在 OceanBase 数据库的主备库架构下，我们也可以利用备库来实现上述目的，并且可以借助 ODP 就近路由到本机房的副本。

#### 配置备集群的弱一致性读

备集群提供了类似于主集群 Follower 副本一样的弱一致性读功能，但由于备集群的副本类型均为 Follower 副本，因此针对主备副本的路由策略不再生效。可以通过如下设置来实现备集群的弱一致性读：

1. 使用 `root` 用户登录备集群的 `sys` 租户。
 2. 设置租户级配置项 `enable_monotonic_weak_read` 和 `max_stale_time_for_weak_consistency`，控制弱一致性读服务行为。
 3. 指定 SQL 级弱读。

       ```

#### 注意

备集群的普通租户仅支持弱一致性读，如果发起强一致性读、写或者 DDL 操作，则会报错。

#### 配置读写分离

读写分离配置通常有以下两种方案：

- 备库只读：该方案主要面向对时间延迟不敏感的查询统计类业务，可以充分利用备集群资源，进行大数据量的决策分析。
 - 写主读备：该方案指的是采用主集群写入数据，备集群负责数据读取的方式。

  由于该方式依赖应用去实现读写操作上的分离，ODP 以及 OceanBase 数据库均不支持该类型的读写分离能力。

以下主要介绍备库只读的读写分离配置。

##### 备集群配置

1. 配置备集群内所有 Zone 的 LDC，包括 REGION 和 IDC。

   为目标 Zone 配置 REGION 和 IDC 的方法如下：

      1. 使用 `root` 用户登录备集群的 `sys` 租户。
      2. 通过 `ALTER SYSTEM MODIFY ZONE` 命令修改 Zone 的 REGION 和 IDC。

        ```

      1. 使用 `root` 用户通过 ODP 登录备集群的 `sys` 租户。
      2. 通过 `ALTER PROXYCONFIG` 命令修改 ODP 的 IDC。

        ```
 3. 配置备集群弱读的租户级配置项，控制弱读行为。

      1. 使用 `root` 用户通过 ODP 登录备集群的 `sys` 租户。
      2. 执行以下命令，设置配置项。

        ```shell
        obclient> ALTER SYSTEM SET enable_monotonic_weak_read = true TENANT=mysqltenant;

        ```

        ```shell
        obclient> ALTER SYSTEM SET max_stale_time_for_weak_consistency ='10s' TENANT=mysqltenant;

        ```

        #### 说明

        修改配置项的值时，如果希望应用到备集群的所有租户，可以指定 `TENANT=all`。
 4. 应用配置弱一致性读。

   可以配置 SQL 级弱一致性读，或者可以通过 JDBC 连接串属性指定连接会话为一致性读。有关，通过 JDBC 连接会话指定弱读属性的详细设置，参见本文 **在驱动上配置弱一致性读** 的内容。

   配置 SQL 级弱一致性读的方法如下：

      1. 用户租户通过 ODP 方式登录备集群。
      2. 指定 SQL 语句为弱一致性读。

              ```

##### ODP 配置

由于主备库的集群名是相同的，通过在 OCP 上配置的以 ConfigURL 为启动方式的 ODP 在访问数据库时，默认会将 SQL 请求发送到主集群，故，如果要指定 ODP 访问备集群，可以通过以下两种方法来实现：

- 方法一：通过 ODP 访问数据库时，在访问用户名中，对集群名的引用需要包括备集群的 `cluster_id`，即格式为 `username@tenant_name#cluster_name:cluster_id`。其中，`cluster_id` 可以从 OCP 集群列表中获取。

  示例如下：

  ```shell
  obclient -h10.10.10.1 -u*****@obtenant#obdemo:xxxx -P2883 -p****** -c -A oceanbase

  ```
 - 方法二：通过 OCP 部署默认访问备集群的 OBProxy，并选择启动方式为 `RsList`，`RsList` 指定为备集群的 RsList。

  有关创建 OBProxy 集群的详细操作，参见 [创建 OBProxy 集群](https://www.oceanbase.com/docs/enterprise-oceanbase-ocp-cn-1000000000022347)。

##### 应用配置

如果应用采用了 JDBC 方式连接数据库，同时在应用代码中又不希望增加弱读 Hint，那么，我们可以在 JDBC 连接串中指定弱读的会话变量，详细设置参见本文 **在驱动上配置弱一致性读** 的内容。

### 在驱动上配置弱一致性读

```

### 验证 SQL 弱读

配置成功后，可以通过查询 GV$SQL_AUDIT 视图中的 `consistency_level` 字段来确定 SQL 是否执行了弱读。示例如下：

   ```

   ```

   ```
 4. 查询 GV$SQL_AUDIT 视图。

   ```shell
   obclient> SELECT svr_ip,query_sql,consistency_level FROM oceanbase.GV$SQL_AUDIT WHERE query_sql LIKE '%FROM tbl1';

   ```

   ```

 下一篇 ![有帮助](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*y6ocSqN8cqsAAAAAAAAAAAAAARQnAQ)![无帮助](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*BG9IQJyLHF8AAAAAAAAAAAAAARQnAQ)![反馈](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*eTWdQKCRKHwAAAAAAAAAAAAAARQnAQ)[AI](https://www.oceanbase.com/obi) 咨询热线
