OBProxy执行流程
收到用户请求后,OBProxy的执行流程:
1. parse sql,通过简易parse,解析出sql涉及的table name、database name
2. fetch route entry,根据用户的tenant name、database name、table name、partition
id 向observer拉取该partition的路由表
3. sort route entry,根据各种相关属性对路由表中ip进行排序
read_consisitency:强一致性读or弱一致性读
目标server状态 :正在合并or常态
路由精准度: PS or TS
LDC 匹配: 本地、同城、异地
Zone 类型
读写分离的ob_route_policy取值
4. filter by congestion,从路由表中依次尝试目标ip,通过黑名单进行过滤
5. forward request,将用户请求转发给目标server和路由相关的一些基础概念,这些基础概念和OBproxy路由密切相关,根据不同的配置,Obproxy 进行综合的路由排序:
LDC配置:
本地:同城同机房(IDC相同)
同城:同城不同机房(IDC不同,Region 相同)
异地: 不同的地域(Region不同)
Observer状态:常态vs正在合并
租户的Zone类型:读写型vs只读型
路由精准度: 优先精准度高的
OBproxy中有目标partition的路由信息(PS)
OBproxy中没有Partition的路由信息,只有租户的路由信息(TS)
LDC简介
IDC:互联网数据中心,可以简单看成一个物理机房
LDC:logical data center ,是对 IDC 的一种逻辑划分
Region:地域信息,通常代表一个城市,包含一个或多个IDC,每个IDC部署一个或多个zone。一个OB集群可以包含若干个Region,每个Region包含若干个IDC,每个IDC部署若干个zone
LDC配置:集群的配置
LDC是指proxy按照根据城市/机房等信息就近路由访问observer, 这需要observer设置好自身所处的机房和城市信息, 需要proxy提供自身所处的机房信息。设置SQL如下:
alter system modify zone “z1” set region = “SHANGHAI”;
alter system modify zone “z1” set idc = “zue”;
检查observer LDC设置内容是否生效,结果如下图所示:
select * from __all_zone;
LDC配置 :Obproxy的配置
proxy支持客户端&集中式部署,因此proxy的LDC的支持全局级别&session级别,即可以全局设置默认的LDC,也可以每个session可以指定使用不同的LDC。
全局级别:配置项proxy_idc_name用来控制全局级别的当前IDC机房信息, 默认为空。配置项的设置可以通过启动参数/登陆修改/ocp配置项更新进行, 在proxy的启动脚本中使用-i机房名启动传入,或者proxy运行后通过alter proxyconfig set proxy_idc_name='机房名';设置
session级别:设置用户变量set @proxy_idc_name='xx'控制session级别的当前机房信息, 默认不指定,用户可以通过进行设置
优先级: session变量 > 配置项。当用户指定session变量proxy_idc_name时,覆盖全局proxy_idc_name设置
LDC配置 :IDC配置和LDC匹配情况查询
OBProxy配置机房名方式:
首次启动时通过启动参数(推荐):
./bin/obproxy -p2883 -e -o
obproxy_config_server_url='ocp_config_server_url',proxy_idc_name='hz001'-n trade
修改proxy配置项
mysql> alter proxyconfig set proxy_idc_name='hz001';
通过执行内部命令“show proxyinfo idc;”可以检查proxy内部识别的LDC部署情况
OBProxy主要路由策略
写请求:
写请求路由到ReadWrite zone的主副本
读请求:
强一致性读
默认的路由策略为强一致性读路由策略
需要读取partition的leader副本的数据,即SQL必须转发到涉及partition的leader server上执行, 以此保证获取到实时最新的数据
强一致性读适用于对读写一致性要求高的场景
弱一致性读:主备均衡路由策略(默认);备优先读策略;读写分离策略
弱一致性读:配置弱一致性读
OceanBase数据库可以通过设置ob_read_consistency参数进行一致性读配置
Global级别
用户设置当前租户全局系统session变量set global ob_read_consistency=‘weak’,对当前租户所有会话都生效(当前会话不生效)
session级别
通过设置set ob_read_consistency=‘weak’,只对当前正在连接的session(会话)生效
SQL Hint,用户在select中加/*+ read_consistency(weak)*/的Hint,仅本语句生效
弱一致性读:主备均衡路由策略(默认)
OBProxy 默认的路由方式为主备均衡路由
首先考虑 Region,相同 Region 的 OBServer 优先于不同 Region 的 OBServer
其次考虑合并状态,不处于合并状态的 OBServer 优先于处于合并状态的 OBServer
最后考虑 IDC 关系,相同 IDC 的 OBServer 优先于不同 IDC 的 OBServer
详细的路由顺序
1. 相同 Region,相同 IDC 并且不处于合并状态的 OBServer
2. 相同 Region,不同 IDC 并且不处于合并状态的 OBServer
3. 相同 Region,相同 IDC 并且处于合并状态的 OBServer
4. 相同 Region,不同 IDC 并且处于合并状态的 OBServer
5. 不同 Region 并且不处于合并状态的 OBServer
6. 不同 Region 并且处于合并状态的 OBServer
弱一致性读:备优先读策略
OBProxy 支持备优先读路由策略,通过用户级别系统变量 proxy_route_policy 控制备优先读路由。备优先读仅在弱一致性读时生效,且优先读 follower 而非主备均衡选择
使用 root 用户登录集群的 sys 租户后,运行下述语句对用户系统变量 proxy_route_policy 进行设置:
设置命令:SET @proxy_route_policy='[policy]’;
验证命令:select @proxy_route_policy;|show proxysession variables;
弱一致性读:读写分离策略
读写分离部署,要求客户端将写请求路由到 ReadWrite Zone主副本,将弱一致性读请求路由到ReadOnly Zone使用 root 用户登录到集群的业务租户,运行下述语句设置 Global 级别系统变量 ob_route_policy 为对应取值即可,默认取值为 readonly_zone_first:
设置命令:set @@global.ob_route_policy=readonly_zone_first;
值 | 路由策略 | 说明 |
readonly_zone_first | 1.本地常态读库PS -> 2.同城常态读库PS -> 3.本地合并读库PS -> 4.同城合并读库PS -> | 默认值, 读库优先访问 优先级: zone类型 > 合并状态 > idc状态 |
only_readonly_zone | 1.本地常态读库PS -> 2.同城常态读库PS -> 3.本地合并读库PS -> 4.同城合并读库PS -> 5.本地常态读库TS -> | 只访问读库 优先级: 合并状态 > idc状态 |
unmerge_zone_first | 1.本地常态读库PS -> 2.同城常态读库PS -> 3.本地常态写库PS -> 4.同城常态写库PS-> | 优先访问不在合并的zone 优先级:合并状态 > zone类型 > idc状态 |
OBProxy使用限制
proxy parser在根据SQL选择server时,有以下几点特殊的逻辑:
proxy parser只解析Begin/START/TRANSACTON/SET/和其他DML,如果遇到其他单词开头的语句,proxy的parser会直接跳过,认为该语句不包含表名
proxy parser会按照第一条包含实体表名的stmtement进行路由,如果整个stmtement都不包含表名,则将请求发送至上一条SQL所发送的server
observer会根据执行计划的类型,来告诉proxy是否将请求路由至正确的server,如果路由失败,proxy会更新location,当前的反馈机制如下:
server返回第一条DML的命中情况
以下几种情况(select可以等价替换成update/delete/replace/insert,下同),proxy能够将请求发送至正确的server,并且server能够按照proxy的命中情况进行反馈:
begin; select * from t1; commit;
set @@autocommit = 1; insert into t1 values(); se
show warnings; select * from t1;
t @@autocommit = 0;
select * from t1; insert into t2 values;
set @@ob_trx_timeout = 10000000; begin; select * from t1; commit;
以下情况,proxy会将请求发送至上一个SQL所使用的server
create table t1 (id int primary key); create table t2 (id int primary key);
不建议使用的语句
以下几种情况(第一个DML是非实体表),proxy能够将请求发送至正确的server,但是server反馈的信息可能不准,不建议使用:
select '1'; select * from t1;
select '1' from dual; select * from t1;
以下情况,proxy可能能够将请求路由至正确的server,但是server端反馈信息可能不准,不建议使用:
create table t1 (id int primary key); insert into t1 values();
以下几种情况,proxy会强制将请求路由至上一次使用的server,server端反馈信息可能不准,不建议使用:
show warnings; select * from t1;
show count(\*) errors; select * from t1;