暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

OceanBase 独立部署高级玩法三:副本数调整

数据库技术闲谈 2020-11-07
157


OB 以集群形态运行,集群可以跨机房跨城市部署。数据架构至少包含三副本,也有五副本。副本数越多,反脆弱性越强。本文主要分享调整数据副本数技术。这也是OB的独特能力之一。




1. 业务方案

在两地三中心场景中,比较重要的业务为了数据安全、性能和服务稳定性,也会采取 5 副本架构。(见工行案例:《OceanBase 蚂蚁自研数据库在大型银行重要业务系统投入使用》)。5 副本架构下,多副本使用 Paxos 协议同步。同一个分区,可以承受最大 2 个副本不可用故障。



这个架构下,主副本读写性能不变,但事务提交时性能受多数派副本的同步性能决定,实际场景主要是由同城双机房之间的网络延时决定。如果出现 2 个副本故障,或者单个机房故障,此时事务提交性能就还要由异地机房的备副本网络延时影响。

此时 OB 实例的事务性能能力会出现一定程度下降,如果业务不能承受这样的性能下降,OB 还有个措施就是将实例的副本数从 5 副本降级为 3 副本。





2. OB 环境准备

OB 集群的部署可以参考上文《OceanBase 独立部署高级玩法二 :2C8G版》。使用类似方法先部署一个 5 副本(1-1-1-1-1)的 OB 集群。

OB 的 5 副本降级为 3 副本时,只需要删除副本即可;3 副本升级为 5 副本时,OB 需要自动补齐副本数据。这个过程有参数可以控制副本复制力度。参数的使用参考《OB 开发测试建议 (中)——参数/变量设置》。具体用到的参数如下:


参数名

参数值

描述

参数范围

data_copy_concurrency

100

the maximum number of the data replication tasks. Range: [1,) in integer

集群

server_data_copy_out_concurrency

40

the maximum number of partitions allowed to migrate from the server. Range: [1, 1000], integer

server_data_copy_in_concurrency

40

the maximum number of partitions allowed to migrate to the server. Range: [1, 1000], integer

enable_rebalance

True

specifies whether the partition load-balancing is turned on. Value:  True:turned on  False: turned off

enable_auto_leader_switch

True

specifies whether partition leadership auto-switch is turned on. Value:  True:turned on;  False: turned off


OB集群和租户资源

OB 集群资源如下

select a.zone,concat(a.svr_ip,':',a.svr_port) observer, cpu_total, (cpu_total-cpu_assigned) cpu_free, round(mem_total/1024/1024/1024) mem_total_gb, round((mem_total-mem_assigned)/1024/1024/1024) mem_free_gb, b.status
from __all_virtual_server_stat a join __all_server b on (a.svr_ip=b.svr_ip and a.svr_port=b.svr_port)
order by a.zone, a.svr_ip
;

+--------+-------------------+-----------+----------+--------------+-------------+--------+
| zone | observer | cpu_total | cpu_free | mem_total_gb | mem_free_gb | status |
+--------+-------------------+-----------+----------+--------------+-------------+--------+
| ZONE_1 | 192.168.0.51:2882 | 54 | 9 | 252 | 36 | active |
| ZONE_2 | 192.168.0.52:2882 | 54 | 9 | 252 | 36 | active |
| ZONE_3 | 192.168.0.53:2882 | 54 | 9 | 252 | 36 | active |
| ZONE_4 | 192.168.0.54:2882 | 54 | 9 | 252 | 36 | active |
| ZONE_5 | 192.168.0.55:2882 | 54 | 9 | 252 | 36 | active |
+--------+-------------------+-----------+----------+--------------+-------------+--------+
5 rows in set (0.01 sec)

复制

OB 租户资源如下

select t1.name  pool_name, t2.`name` config_name, t2.max_cpu cpu,concat( round(t2.max_memory/1024/1024/1024) ,' G') memory, t3.zone, concat(t3.svr_ip,':',t3.`svr_port`) observer, t4.tenant_name
from __all_resource_pool t1 join __all_unit_config t2 on (t1.unit_config_id=t2.unit_config_id)
join __all_unit t3 on (t1.`resource_pool_id` = t3.`resource_pool_id`)
left join __all_tenant t4 on (t1.tenant_id=t4.tenant_id)
order by t4.tenant_name, t1.`resource_pool_id`, t2.`unit_config_id`, t3.unit_id
;

+-------------+-----------------+-----+--------+--------+-------------------+-------------+
| pool_name | config_name | cpu | memory | zone | observer | tenant_name |
+-------------+-----------------+-----+--------+--------+-------------------+-------------+
| bmsql_227 | unit_40c200g | 40 | 200 G | ZONE_1 | 192.168.0.51:2882 | bmsql227 |
| bmsql_227 | unit_40c200g | 40 | 200 G | ZONE_2 | 192.168.0.52:2882 | bmsql227 |
| bmsql_227 | unit_40c200g | 40 | 200 G | ZONE_3 | 192.168.0.53:2882 | bmsql227 |
| bmsql_227_1 | unit_40c200g | 40 | 200 G | ZONE_4 | 192.168.0.54:2882 | bmsql227 |
| bmsql_227_2 | unit_40c200g | 40 | 200 G | ZONE_5 | 192.168.0.55:2882 | bmsql227 |
| sys_pool | sys_unit_config | 5 | 16 G | ZONE_1 | 192.168.0.51:2882 | sys |
| sys_pool | sys_unit_config | 5 | 16 G | ZONE_2 | 192.168.0.52:2882 | sys |
| sys_pool | sys_unit_config | 5 | 16 G | ZONE_3 | 192.168.0.53:2882 | sys |
| sys_pool_1 | sys_unit_config | 5 | 16 G | ZONE_4 | 192.168.0.54:2882 | sys |
| sys_pool_2 | sys_unit_config | 5 | 16 G | ZONE_5 | 192.168.0.55:2882 | sys |
+-------------+-----------------+-----+--------+--------+-------------------+-------------+
10 rows in set (0.01 sec)

复制

细心的朋友或许会发现,上面有 2 个租户(一个内部 sys,一个业务租户 bmsql227)。每个租户有 5 个资源单元,但是有 3 个资源池。

在以前的《揭秘OceanBase的弹性伸缩和负载均衡原理》介绍中,一个 租户只绑定到一个资源池,一个资源池包含多个 ZONE 里规格一致的资源单元。最近的 OCP 在安装 OB 集群时采取了新的方法,每个 ZONE 建一个资源池,租户可以绑定多个资源池。每个资源池的资源规格可以不一样。尽管如此,外部客户 OB 集群资源规划建议不同 ZONE 使用同等规格的机器和资源池。

下面是创建示例:

create resource unit unit_4c16g max_cpu=4,min_cpu=4,max_memory='16G',min_memory='16G',max_iops=10000,min_iops=1000,max_session_num=100000,max_disk_size='1024G';

create resource pool test_pool_z1 unit='unit_4c16g' , unit_num=1, zone_list=('ZONE_1');
create resource pool test_pool_z2 unit='unit_4c16g' , unit_num=1, zone_list=('ZONE_2');
create resource pool test_pool_z3 unit='unit_4c16g' , unit_num=1, zone_list=('ZONE_3');
create resource pool test_pool_z4 unit='unit_4c16g' , unit_num=1, zone_list=('ZONE_4');
create resource pool test_pool_z5 unit='unit_4c16g' , unit_num=1, zone_list=('ZONE_5');

create tenant test227 resource_pool_list=('test_pool_z1','test_pool_z2','test_pool_z3','test_pool_z4','test_pool_z5'), primary_zone=RANDOM, comment='oracle tenant', charset='utf8' set ob_tcp_invited_nodes='%', ob_compatibility_mode='oracle' ;

复制


业务压力模拟

这里用 benchmarksql 的 tpcc 场景压测 OB 来模拟业务压力。具体方法请参考《OceanBase 2.x体验:用BenchmarkSQL跑TPC-C》。

下面是dooba 监控脚本。dooba 脚本位置  /home/admin/oceanbase/bin/dooba ,只有 rpm 安装的 OB 才有.

从监控可以看到 5 台机器都有流量访问。

查看业务表分区的位置 SQL,供后面减副本后对比用

SELECT t.tenant_id,a.tenant_name,d.database_name,t.table_name,tg.tablegroup_name,t.part_num,t2.partition_id, t2.zone, t2.svr_ip ,round( t2.data_size/1024/1024/1024) data_size_gb
,a.primary_zone , if(t.locality='' or t.locality is null, a.locality, t.locality) as locality
from oceanbase.__all_tenant as a
join oceanbase.__all_virtual_database as d on (a.tenant_id=d.tenant_id)
join oceanbase.__all_virtual_table as t on (t.tenant_id=d.tenant_id and t.database_id=d.database_id)
join oceanbase.__all_virtual_meta_table as t2 on (t.tenant_id=t2.tenant_id and (t.table_id=t2.table_id or t.tablegroup_id=t2.table_id) and t2.role in (1))
left join oceanbase.__all_virtual_tablegroup as tg on (t.tenant_id=tg.tenant_id and t.tablegroup_id=tg.tablegroup_id)
where a.tenant_id in (1007) and t.table_type in (3) and d.database_name like 'TPCC%'
;

复制


3. OB 减副本:5 副本降级为 3 副本。

首先要做的是租户减副本。

OB集群除了业务租户外,还有个默认租户 sys。sys 减副本放到最后。

如果租户 primary_zone 指定了具体的 ZONE 而那个 ZONE 是要被减掉的,则需要先切换 PRIMARY_ZONE。

默认租户的 locality 值是 'FULL{1}@ZONE_1, FULL{1}@ZONE_2, FULL{1}@ZONE_3,FULL{1}@ZONE_4,FULL{1}@ZONE_5'。租户减副本主要是修改 locality 属性。

alter tenant bmsql227 locality='FULL{1}@ZONE_1, FULL{1}@ZONE_2, FULL{1}@ZONE_3';

复制

业务租户下的表默认继承租户的多副本属性,但复制表可能例外。

alter table BMSQL_ITEM locality='F,R{all_server}@ZONE_1, F,R{all_server}@ZONE_2, F,R{all_server}@ZONE_3';

复制


性能压测流量也很快从5zone缩减到3zone


租户减副本的时候 OB 内部在自动的删除目标 ZONE 上的副本。可以查看内部总控服务事件日志。总控服务介绍请参考《OceanBase数据库实践入门——了解总控服务》。


SELECT DATE_FORMAT(gmt_create, '%b%d %H:%i:%s') gmt_create_ , module, event, name1, value1, name2, value2, rs_svr_ip
FROM __all_rootservice_event_history
WHERE 1 = 1 and module in ('balancer','leader_coordinator') and gmt_create >= '2020-11-06 10:50:00'
ORDER BY gmt_create DESC
LIMIT 1000;

复制

结果这里不贴了。总结为下列表格


module

event

name1

value1

name2

value2

balancer

start_batch_remove_member

destiontion

"192.168.0.52:2882"

task_info_count

119

start_remove_member

partition

{tid:1106108697542659, partition_id:0, part_cnt:0}

member

{zone:"ZONE_5", unit_id:18446744073709551615, member:{server:"192.168.0.55:2882", timestamp:1604633484896819, flag:0, replica_type:0, region:"default_region", memstore_percent:100}}

finish_batch_remove_member

destination

"192.168.0.52:2882"

task_info_count

119

finish_remove_member

partition

{tid:1106108697542659, partition_id:0, part_cnt:0}

member

{zone:"ZONE_5", unit_id:18446744073709551615, member:{server:"192.168.0.55:2882", timestamp:1604633484896819, flag:0, replica_type:0, region:"default_region", memstore_percent:100}}

start_batch_remove_member

destiontion

"192.168.0.51:2882"

task_info_count

2

start_remove_member

partition

{tid:1106658453357545, partition_id:2, part_cnt:0}

member

{zone:"ZONE_4", unit_id:18446744073709551615, member:{server:"192.168.0.54:2882", timestamp:1604633545265814, flag:0, replica_type:0, region:"default_region", memstore_percent:100}}

finish_batch_remove_member

destination

"192.168.0.51:2882"

task_info_count

2

finish_remove_member

partition

{tid:1106658453357545, partition_id:2, part_cnt:0}

member

{zone:"ZONE_4", unit_id:18446744073709551615, member:{server:"192.168.0.54:2882", timestamp:1604633545265814, flag:0, replica_type:0, region:"default_region", memstore_percent:100}}

tenant_balance_started

start_time

1604631536694360



leader_coordinator

switch_leader

current_rs

"192.168.0.51:2882"

tenant_id

1007

balancer

tenant_balance_finished

finish_time

1604631552475353

task_count

248







其中很多任务的粒度都是分区级别,OB 在每个节点上同时执行数据清理或迁移任务的个数受前面提到的参数限制。


业务租户减副本结束后就剩 sys 租户了。

alter tenant sys locality='FULL{1}@ZONE_1, FULL{1}@ZONE_2, FULL{1}@ZONE_3';

复制


当所有业务租户副本从 5 降级为 3 后,性能问题就彻底解决了。

如果目的是下线某2 个 zone,则后面还需要做租户的资源池释放和集群的 ZONE 数目降级,即下线掉 2 个 ZONE。


释放租户在目标 ZONE 的资源池时,每次只能释放一个。

alter tenant bmsql227 resource_pool_list=('bmsql_227','bmsql_227_1');
alter tenant bmsql227 resource_pool_list=('bmsql_227');

alter tenant sys resource_pool_list = ('sys_pool','sys_pool_1');
alter tenant sys resource_pool_list = ('sys_pool');

复制


所有租户资源池释放后,就是集群机器和 zone 删除。

alter system delete server '192.168.0.55:2882' zone ZONE_5;
alter system delete server '192.168.0.54:2882' zone ZONE_4;

alter system delete zone 'zone4';
alter system delete zone 'zone5';


select a.zone,concat(a.svr_ip,':',a.svr_port) observer, cpu_total, (cpu_total-cpu_assigned) cpu_free

, round(mem_total/1024/1024/1024) mem_total_gb

, round((mem_total-mem_assigned)/1024/1024/1024) mem_free_gb, b.status

from __all_virtual_server_stat a join __all_server b on (a.svr_ip=b.svr_ip and a.svr_port=b.svr_port)
order by a.zone, a.svr_ip
;

+--------+-------------------+-----------+----------+--------------+-------------+--------+
| zone | observer | cpu_total | cpu_free | mem_total_gb | mem_free_gb | status |
+--------+-------------------+-----------+----------+--------------+-------------+--------+
| ZONE_1 | 192.168.0.51:2882 | 54 | 5 | 252 | 20 | active |
| ZONE_2 | 192.168.0.52:2882 | 54 | 5 | 252 | 20 | active |
| ZONE_3 | 192.168.0.53:2882 | 54 | 5 | 252 | 20 | active |
+--------+-------------------+-----------+----------+--------------+-------------+--------+
3 rows in set (0.02 sec)

复制


4. OB 加副本:3 副本升级为 5 副本。

如果是从 3 副本升级为 5 副本,则把上面过程反过来执行。

  • OB 集群增加新的 ZONE: ZONE_5 , ZONE_4 。命令是 add zone 。

  • 新的机器上 observer 进程初始化,分别指定 ZONE 为:ZONE_5  , ZONE_4 。

  • OB 集群给 ZONE_5 ZONE_4 分别增加对应的机器,命令 add server 。此时集群变为 5 副本,但是集群内部的租户依然是 3 副本架构。命令是 add server 。

  • 为每个租户在ZONE_5 ZONE4 分别准备对应的资源池。命令:create resource pool 。

  • 修改每个租户的 locality,增加新的资源池。命令:alter resource pool 。此时 OB 内部自动在目标 ZONE_5 和 ZONE_4 添加新的副本。生产环境建议每次增加一个 ZONE。

  • 修改租户里的复制表的 locality ,增加 ZONE_5 和 ZONE_4 。



参考示例脚本:

create resource unit unit_4c16g max_cpu=4,min_cpu=4,max_memory='16G',min_memory='16G',max_iops=10000,min_iops=1000,max_session_num=100000,max_disk_size='1024G';

create resource pool test_pool_z1 unit='unit_4c16g' , unit_num=1, zone_list=('ZONE_1');
create resource pool test_pool_z2 unit='unit_4c16g' , unit_num=1, zone_list=('ZONE_2');
create resource pool test_pool_z3 unit='unit_4c16g' , unit_num=1, zone_list=('ZONE_3');
create resource pool test_pool_z4 unit='unit_4c16g' , unit_num=1, zone_list=('ZONE_4');
create resource pool test_pool_z5 unit='unit_4c16g' , unit_num=1, zone_list=('ZONE_5');


create tenant test227 resource_pool_list=('test_pool_z1','test_pool_z2','test_pool_z3','test_pool_z4','test_pool_z5'), primary_zone=RANDOM, comment='oracle tenant', charset='utf8' set ob_tcp_invited_nodes='%', ob_compatibility_mode='oracle' ;

-- sys@test227 登录租户 test227
create user tpcc identified by 123456;
grant connect,resource to tpcc;
grant dba to tpcc;

-- 换tpcc@test227 用户连接租户。

create table bmsql_config (
cfg_name varchar2(30) primary key,
cfg_value varchar2(50)
);

create tablegroup TPCC_GROUP partition by hash partitions 5;

create table bmsql_warehouse (
w_id integer not null,
w_ytd decimal(12,2),
w_tax decimal(4,4),
w_name varchar2(10),
w_street_1 varchar2(20),
w_street_2 varchar2(20),
w_city varchar2(20),
w_state char(2),
w_zip char(9),
primary key(w_id)
)tablegroup=TPCC_GROUP partition by hash(w_id) partitions 5;

create table bmsql_item (
i_id integer not null,
i_name varchar2(24),
i_price decimal(5,2),
i_data varchar2(50),
i_im_id integer,
PRIMARY KEY (i_id)
)locality='F,R{all_server}@ZONE_1, F,R{all_server}@ZONE_2, F,R{all_server}@ZONE_3, F,R{all_server}@ZONE_4,F,R{all_server}@ZONE_5' primary_zone='ZONE_2' duplicate_scope='cluster';


alter tenant test227 locality='FULL{1}@ZONE_1, FULL{1}@ZONE_2, FULL{1}@ZONE_3';


alter table BMSQL_ITEM locality='F,R{all_server}@ZONE_1, F,R{all_server}@ZONE_2, F,R{all_server}@ZONE_3';

alter tenant sys resource_pool_list = ('sys_pool','sys_pool_1');
alter tenant sys resource_pool_list = ('sys_pool');
alter tenant test227 resource_pool_list=('test_pool_z1','test_pool_z2','test_pool_z3','test_pool_z4');
alter tenant test227 resource_pool_list=('test_pool_z1','test_pool_z2','test_pool_z3');
drop resource pool sys_pool_1 ;
drop resource pool sys_pool_2 ;
drop resource pool test_pool_z4 ;
drop resource pool test_pool_z5 ;

复制



5.  其他参考

文章转载自数据库技术闲谈,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论