logo
GBase 8a
性能调优
文章

南大通用Gbase 8a MPP Cluster多并发insert缓慢优化

echo-duanhuanhuan
发表于2024-11-16 21:31:22372次浏览0个评论

多并发insert缓慢优化

场景分析

在业务上或者数据迁移时,经常会出现对同一张表进行多并发的insert values操作,GBase 8a 虽然支持标准的sql插入方式,但同一般的关系型数据库对比,8a的强项在于大事务和大数据量的处理上,在高并发事务处理能力上偏弱,因为8a的锁粒度等级仅达到表级别,无法像oracle那样支持到行锁,mysql那样支持到间隙锁,所以在对一个表并发插入时,会进行争抢表锁,在新的版本上insert values做了特殊处理,允许并发。但在提交阶段,即commit时,insert value会发生互斥出现等待,造成阻塞性能差的情况。

对于此类情况,有以下三种优化方案。

优化方案

1. 关闭自动提交,多个insert合并为一条事务进行提交。

在V86版本里,支持 set autocommit=0,设置当前会话自动提交关闭从而避免自动提交,而在v95版本直接设置set autocommit=0不会生效,需要先设置参数_t_gcluster_oldtransaction_support_set_autocommit,再关闭自动提交才能合并多个insert为一条事务。

具体操作如下:

######86版本######
set autocommit=0

insert into t1 values (1);

insert into t1 values (2);

insert into t1 values (3);

…

commit;
set autocommit=1;

######95版本######
set global _t_gcluster_oldtransaction_support_set_autocommit=1;
set autocommit=0;

insert into t1 values (1);

insert into t1 values (2);

insert into t1 values (3);

…

commit;
set autocommit=1;

请注意此类办法,在执行insert期间,并会不会直接给t1表上锁,其他会话仍然可以进行update或insert操作,只有最后的commit阶段才会阻止其他会话对t1表的写入操作,故可以提高并发插入的性能。

2. 拼接sql语句,攒批进行插入。

gbase 8a 除了支持标准的sql插入方式,还支持特殊的语法格式insert into table_name values (行1),(行2),…(行n);此类方式也可以降低并发带来的锁争用。

原始插入方式:
insert into t1 values (1);

insert into t1 values (2);

insert into t1 values (3);

.......

insert into t1 values (n);

改写后的插入方式:

insert into t1 values (1),(2),(3), ... ,(n);

对于此类攒批需要注意sql最大长度限制(一般设置5000-10000行进行一次改写),可修改以下参数调整
set global max_allowed_packet = 1073741824; 

3. 导出成文件后进行load加载进数据库

对于一些场景,可以将需要入库的数据,先导入至文本文件中,然后再使用load data infile的方式进行读文本文件加载入库,此类方式效率最高,也是最快速的方式,亦是最推荐的方式。具体语法如下:

load data infile 'sftp://gbase:******@172.16.9.*/home/gbase/t1.txt' into table t1 data_format 3 fields terminated by '|' enclosed by '"' ;

在实际的使用场景中,经常会出现并发写入文本而导致文本所在服务器的IO过高,乃至CPU飙升的情况出现,此类情况也会因为文件服务器的负载高而影响入库效率,也可以考虑先将文本导入redis,mongodb等一些内存数据库中,然后定时导出文本,再load加载8a数据库中.

评论

登录后才可以发表评论