X

「实战系列」Greenplum6JDBCinsert性能媲美MySQL

导语:近些年,大数据技术在IT界里已经是必提的话题了,朋友圈里经常看到一些同事们、项目合作公司朋友们转发的大数据相关文章。最近工作中也在做一款与数据相关的产品,不幸的是,真正遇到数据量大的时候,发现常用的 MySQL 等数据库真是顶不住。百度一下,当前流行的 Greenplum 数据库映入眼帘。仔细一查,发现 Greenplum 还是个开源数据库,再去各大招聘网站和 APP 查看了一下,招聘 Greenplum 相关人才的还真不少。在一番调研后,经测试发现,参数调优后的 Greenplum 数据库 Insert 写入性能有很大程度提升,完成 100W 数据写入由每秒 780 条提升到 2252 条,写入速度已经与 MySQL 相媲美了。用这篇文章来记录一下我的测试与调参过程。

开始接触 Greenplum 是一次机缘巧合,当时领导让调研下 Greenplum 的性能,于是我在公司用了四台虚拟机,开始搭建起来。记得当时 Greenplum 的 6.0 版本还没发布,我便搭建了一个 5.X 的版本,并用常规的 JDBC 等操作关系数据库的方式来使用 Greenplum,不料发现数据写入很慢。网上百度发现不只是我一个人这么认为,试验了一些网上的方法也无济于事。

没过几天,在 Github 上搜索 GPDB 相关内容时,发现 Greenplum 发布了 6.0 版本,同时也查到了 Greenplum 中文社区 ( greenplum.cn ) 里的一篇相关文章,文章中提到 Greenplum 6.0 在 OLTP 上有很大提升,推掉5的环境,当天就将 Greenplum 改为了 6.0 的,继续用 JDBC 来 insert 数据,发现还是很慢,一开始怀疑自己的测试程序有问题,于是先后几次用 Greenplum 自己的驱动包、kettle 的 API、datax 工具等几种方式测试,结果仍然没有太大变化。无奈只好继续在网上搜索,后来搜到阿里有篇文章对 Greenplum 的数据写入问题有过总结,印象比较深的是 insert 语句用批量 values 方式、用 copy 方式写入等。

感觉又没过去几天,在 Greenplum 技术群里听说 Greenplum 又出新版本了,便想着下周再试试。谁知等我再次准备升级环境测试时,Github 上最新的已经是 6.2.1 版本了。再次测试,感觉数据写入速度好像还不如6.0的。于是去 Greenplum 技术群组中求助,得到一位大侠指点,要提高 OLTP 的写入性能,需要调整 Greenplum 的一些默认配置参数,经尝试,果然很不一样。

接下来看看我的测试与调参过程吧。

一、测试过程

测试的数据库包括Greenplum集群版本、Oracle单机版本、MySQL单机版本。

1、系统环境

3、Oracle 环境

3.1 软件版本

  1. Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 – 64bit Production

3.2 单机环境

4.3 数据库驱动

5.3 测试代码

public static void test(PropertiesConfig config) throws Exception {
long begin = System.currentTimeMillis();
try {
Class.forName(config.driverClassName);
try (Connection conn = DriverManager.getConnection(config.jdbcUrl, config.username, config.password);) {
String sql = “insert into \”t_test_tang_1\” (\”ID\”,\”NAME\”) values (?,?)”;
if (config.jdbcUrl.indexOf(“mysql”) > 0) {
sql = “insert into t_test_tang_1 (ID,NAME) values (?,?)”;
}
try(PreparedStatement ps = conn.prepareStatement(sql);){
conn.setAutoCommit(false);
System.out.println(“Opened database successfully”);

long id = 1;
String namePrefix = RandomStringUtils.randomAlphanumeric(1024);
for(int i=0; i<1000; i++) {
for(int j=0; j<1000; j++) {
ps.setLong(1, id);
ps.setString(2, namePrefix);
ps.addBatch();
id++;
}
ps.executeBatch();
conn.commit();
}
} catch (Exception e) {
conn.rollback();
System.err.println(e.getClass().getName() + “: ” + e.getMessage());
}
}
} catch (Exception e) {
e.printStackTrace();
}

long end = System.currentTimeMillis();
System.out.println(“total elipse = ” + (end – begin)+” ms”);
}二、测试结果

用上述代码,基于三种数据库的配置进行相同代码过程测试,测试结果如下:

1、第一次测试:

本次测试使用的 Greenplum 为 6.0 版本,并使用默认配置参数

Greenplum 调整的参数如下:

(1)全局死锁检测开关
在Greenplum 6中其默认关闭,需要打开它才可以支持并发更新/删除操作;
gpconfig -c gp_enable_global_deadlock_detector -v on

(2) 禁用GPORCA优化器(据说GPDB6默认的优化器为:GPORCA)
gpconfig -c optimizer -v off

(3)关闭日志
此GUC减少不必要的日志,避免日志输出对I/O性能的干扰。
gpconfig -c log_statement -v none

注意:参数配置修改后,使用 gpstop -u 重新加载配置,并用 gpconfig -s 检查了各个参数确认为修改成功。