1. 需求背景
ADB PG是一个经典MPP数据库,长项在于查询分析处理,面对客户联机分析和联机交易(HTAP)场景就显得力不从心,我们在某银行核心系统DB2 for LUW迁移到ADB PG时就遇到类似问题,因此我们提出ADB PG+RDS PG混搭技术架构(如下图所示)来解决客户此类HTAP需求。该混搭架构的精髓在于扬长避短,充分发挥分析型数据库和交易型数据库的长处和特性,分析型数据库专注于数据加工跑批场景,然后批量加工的结果数据卸载到RDS PG,通过RDS PG对外提供高并发对客交易服务。
2. 难点及应对方案选型
联合ADB PG和RDS PG混搭技术架构的难点在于数据同步上,即如何实现ADB PG的数据高效同步到RDS PG数据库上?为此,我们联合客户及开发商进行了摸索尝试,主要对两种方案进行测试:
2.1 方案一:管道COPY
采用传统Linux管道方式,ADB PG集群的数据通过COPY方式读取到终端,然后通过管道重定向输入到RDS PG集群。
2.2 方案二:端到端并行COPY
利用segment的并行copy能力,adb pg集群的数据并行拷贝到RDS PG的一写多读实例集群中。
很直观端到端并行COPY的效率更高,但是受限于阿里飞天云平台环境限制,实际操作复杂度上更高;管道方式对平台环境限制较小,更容易操作上手。
3. 应对方案效率对比
我们采用某银行账户信息表dw_dpfm02,该表包含记录数134,877,283条,对应表结构DDL如下所示:
CREATE TABLE public.dw_dpfm02 (
acct character varying(22) NOT NULL,
accs character varying(6) NOT NULL,
acct_type character varying(1),
hd_flag character varying(1),
cls_flag character varying(1),
ccy character varying(2),
prd_id character varying(3),
sbno character varying(8),
opn_date date,
str_date date,
end_date date,
term integer,
term_type character varying(1),
bale numeric(17,2),
balen numeric(17,2),
lbale numeric(17,2),
lstdte date,
node character varying(5),
accchr character varying(1),
tductl character varying(1),
frz_flag character varying(3),
mrt_flag character varying(1),
prv_flag character varying(1),
dt_flag character varying(1),
bk_flag character varying(5),
del_flag integer,
partition_date date
);
可行性测试的环境为飞天企业版V312,ADB PG规格为64 segment,RDS PG为8C32G的规格实例。
以下我们分别使用管道和端到端copy方式测试复制表dw_dpfm02到rds pg的可行性及效率:
3.1 管道COPY方式实现及效率
管道方式实现的逻辑示意图如下所示,ADB PG的segment进行分组导出到Linux 终端,然后再管道输入到RDS PG的一写多读集群实例中。
实现脚本代码如下所示,在后台adb pg的segment分组导出数据,并需要进行程序进行轮询判断是否导数完成。
................
#ADB分区表数据copy到RDS PG分区表中(并发执行通过进程号判断执行进度)
nohup psql -h ${domain_adb} -p 3432 -d ${dbname_adb} -U ${username_adb} -c "\copy (select * from dw_dpfm02_${syncdate} where gp_segment_id between 0 and 15) to stdout" | psql -h ${domain_rdspg} -c "\timing" -p 3433 -d ${dbname_rdspg} -U ${username_rdspg} -c "\copy dw_dpfm02_${syncdate} from stdin" &
c1=$!
echo `date +'%Y-%m-%d %H:%M:%S'` "c1 process start"
nohup psql -h ${domain_adb} -p 3432 -d ${dbname_adb} -U ${username_adb} -c "\copy (select * from dw_dpfm02_${syncdate} where gp_segment_id between 16 and 31) to stdout" | psql -h ${domain_rdspg} -c "\timing" -p 3433 -d ${dbname_rdspg} -U ${username_rdspg} -c "\copy dw_dpfm02_${syncdate} from stdin" &
c2=$!
echo `date +'%Y-%m-%d %H:%M:%S'` "c2 process start"
nohup psql -h ${domain_adb} -p 3432 -d ${dbname_adb} -U ${username_adb} -c "\copy (select * from dw_dpfm02_${syncdate} where gp_segment_id between 32 and 47) to stdout" | psql -h ${domain_rdspg} -c "\timing" -p 3433 -d ${dbname_rdspg} -U ${username_rdspg} -c "\copy dw_dpfm02_${syncdate} from stdin" &
c3=$!
echo `date +'%Y-%m-%d %H:%M:%S'` "c3 process start"
nohup psql -h ${domain_adb} -p 3432 -d ${dbname_adb} -U ${username_adb} -c "\copy (select * from dw_dpfm02_${syncdate} where gp_segment_id between 48 and 63) to stdout" | psql -h ${domain_rdspg} -c "\timing" -p 3433 -d ${dbname_rdspg} -U ${username_rdspg} -c "\copy dw_dpfm02_${syncdate} from stdin" &
c4=$!
echo `date +'%Y-%m-%d %H:%M:%S'` "c4 process start"
cl=$(ps -ef|egrep ''$c1'|'$c2'|'$c3'|'$c4''|grep -v 'grep'|wc -l)
echo `date +'%Y-%m-%d %H:%M:%S'` "cl:${cl}"
while [ $cl -ne 0 ]
do
sleep 1
cl=$(ps -ef|egrep ''$c1'|'$c2'|'$c3'|'$c4''|grep -v 'grep'|wc -l)
echo `date +'%Y-%m-%d %H:%M:%S'` "cl:${cl}"
done
................
上述脚本全程完成导数耗时约789秒。
Time: 789192.053 ms (13:09.192)
3.2 端到端并行COPY方式实现及效率
端到端copy方式相比管道方式简单很多,如下所示只需在ADB PG端发起一个COPY命令,即可把各个segment的数据快速导出到本地,然后再把本地segment数据分别并发copy到远端RDS PG中。
---------copy的sql 脚本:copy_dw_dpfm02.sql
\timing on
copy dw_dpfm02_20211103 to PROGRAM '
cat > /dw_dpfm02_20211103.txt;
export PGPASSWORD=${rdspg_password};
psql -U${username_rdspg} -h ${domain_rdspg} -p 3433 -d postgres -c "\copy dw_dpfm02 from ''/dw_dpfm02_20211103.txt'';";
rm -rf /dw_dpfm02_20211103.txt;
' with on segment NULL '' encoding 'UTF8' ;
----------调用copy_dw_dpfm02.sql执行,执行结果如下:
$$ export PGPASSWORD=${adbpg_aurora_password};psql gpdb -U aurora -h ${domain_adbpg} -p 3432 -atf load_dw_dpfm02.sql
\timing on
Timing is on.
copy dw_dpfm02_20211103 to PROGRAM '
cat > /dw_dpfm02_20211103.txt;
export PGPASSWORD=${rdspg_password};
psql -U${username_rdspg} -h ${domain_rdspg} -p 3433 -d postgres -c "\copy dw_dpfm02 from ''/dw_dpfm02_20211103.txt'';";
rm -rf /dw_dpfm02_20211103.txt;
' with on segment NULL '' encoding 'UTF8';
COPY 134614146
Time: 337510.271 ms (05:37.510)
实践中发现在飞天企业版V312使用端到端并行copy方式需要克服以下两大条件:
(1)必须使用ADB PG的超级运维账号aurora进行COPY,用户自定义账号不具备执行COPY权限
(2)并行COPY中的RDS PG需要使用经典网络域名访问ADB PG的segment服务器,默认的VPC网络域名访问行不通。
3.3 效率对比
对比发现使用端到端并行COPY效率远远高于管道COPY实现方式,整体性能提升134%左右。
换算成每秒同步记录数Record Per Second(RPS)的话,使用管道COPY约为17万RPS,端到端并行COPY约为40万RPS,效率相差两倍之多。
4. 最佳实践场景总结
在飞天云平台上如果可以放开aurora超级账号权限,优选端到端并行COPY方式;如果有账号权限管控需求,退而求其次选用管道COPY方式。
优势 |
劣势 |
|
管道COPY |
1、平台无感知,通行方法 2、无需集群超级账号 |
效率偏低 |
端到端并行COPY |
1、效率高 2、维护简单 |
限制条件苛刻: 1、adb pg需要aurora超级账号copy 2、rds pg需要申请经典网络地址 |