ADB PG最佳实践之高效复制数据到RDS PG

简介: ADB PG是一个经典MPP数据库,长项在于查询分析处理,面对客户联机分析和联机交易(HTAP)场景就显得力不从心,我们在某银行核心系统DB2 for LUW迁移到ADB PG时就遇到类似问题,因此我们提出ADB PG+RDS PG混搭技术架构,来解决客户此类HTAP需求。该混搭架构的精髓在于扬长避短,充分发挥分析型数据库和交易型数据库的长处和特性,分析型数据库专注于数据加工跑批场景,然后批量加工的结果数据卸载到RDS PG,通过RDS PG对外提供高并发对客交易服务。


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需要申请经典网络地址

作者介绍
目录