OceanBase作为典型的高可用分布式关系数据库, 使用Paxos协议进行日志同步, 天然支持多地多中心的部署方式, 可以提供高可靠的容灾保证. 但当真正多地多中心部署时, 任何数据库都会面临异地路由延迟问题.

    以典型的三地五中心部署架构为例, 杭州/上海分别部署两个zone, 深圳部署一个zone. 已知同城之间的ping延迟0.1ms左右, 杭州与上海之间的延迟5ms左右, 杭州与深圳之间的延迟24ms左右, 上海与深圳之间延迟29ms左右. 假设App部署在杭州, 那么App在登录OceanBase数据库时, 或者登陆之后执行SQL语句时, OceanBase客户端路由与OceanBase内部RPC路由倘若没有进行多地部署的优化, 那么App的RT稳定性和最佳性能将不能得到保障. 为了解决这个问题, OceanBase LDC路由应运而生.

    LDC通常和弱一致性读一共使用, 本文详细说明如何正确使用弱一致性读和LDC.

    弱一致性读

    目前有两种指定弱一致性读的方式,优先级依次提高:

    • 全局系统变量, 用户设置当前租户全局系统变量set @@global.ob_read_consistency='weak', 对当前租户当前集群所有会话都生效;

    • session系统变量, 用户设置当前租户系统变量set @@ob_read_consistency='weak', 只对当前会话生效;

    • sql hint, 用户在select中加/*+ read_consistency(weak)*/的Hint, 仅本语句生效;

    在OceanBase中,事务中的select不一定是强一致性读,是由事务的第一条语句决定事务的read_consistency类型。

    1. setAutoCommit = false;
    2. select /*+ read_consistency (weak)*/ xxxxxx;
    3. insert xxxxx; // 报错

    LDC

    LDC是指proxy按照根据城市/机房等信息就近路由访问observer,这需要OBServer设置好自身所处的机房和城市信息,需要proxy提供自身所处的机房信息。

    OBServer

    OBServer 的每个 Zone 设置 region属性/idc属性,region通常代表城市的概念, 通常设置为城市名(大小写敏感。 idc代表该zone所处的机房信息,通常设置机房名(小写)。一个cluster有若干个region,一个region有若干个Zone,一个zone只有一个idc属性。

    设置sql:

    1. alter system modify zone "z1" set region = "SHANGHAI";
    2. alter system modify zone "z1" set idc = "zue";

    检查observer LDC设置内容是否生效:

    1. select * from __all_zone;

    LDC - 图1

    1. select * from __all_virtual_zone_st

    LDC - 图2

    proxy

    1. proxy支持客户端&集中式部署,因此proxy的LDC的支持全局级别&session级别,即可以全局设置默认的LDC,也可以每个session可以指定使用不同的LDC。
    • 全局级别, 配置项proxy_idc_name用来控制全局级别的当前IDC机房信息,默认为空。配置项的设置可以通过启动参数/登陆修改/ocp配置项更新进行,例如从1.2.1版本之后在proxy的启动脚本obproxtyd.sh中使用-i 机房名启动传入,或者proxy运行后通过alter proxyconfig set proxy_idc_name='机房名';设置;
    • session级别,设置用户变量set @proxy_idc_name='xx'控制session级别的当前机房信息,默认不指定。
    1. 优先级:session变量 > 配置项。当用户指定session变量proxy_idc_name时,覆盖全局proxy_idc_name设置。优先级组合效果如下表所示。

    LDC - 图3

    1. 使用proxy LDC时,上层(如zdal)需要做的工作:
    • 如果proxy上的所有集群明确都使用LDC, 那么通过更改配置项的方式, 修改配置项proxy_idc_name, 或者直接在obproxyd.sh脚本中使用-i 机房名传入.
    • 如果仅部分集群/Session明确使用LDC, 在创建物理连接后设置有效的session变量proxy_idc_name即可, 如set @proxy_idc_name='机房名';. 若设置无效的机房名, 将退化为不使用LDC.
    • 如果某个集群or连接明确不使用LDC, 在创建物理连接后设置session变量proxy_idc_name为空即可, 如set @proxy_idc_name='';;
    1. 通过执行内部命令show proxyinfo idc;可以检查proxy内部识别的LDC部署情况。

    LDC - 图4