肥仔教程网

SEO 优化与 Web 开发技术学习分享平台

gpfdist性能优化介绍


,是Greenplum数据库最重要的数据批量加载技术,有着极高的性能。

先讲个故事,我们经历过很多的POC测试,虽然gpfdist外部表的加载性能一直领先友商,但是,在文件服务器带宽有限的情况下,我们往往很难取得碾压性的优势,尤其是文件服务器只有一根光纤的时候,测试的结果,往往是大家的性能几乎相同,所以,我在很长一段时间,都在考虑,如何可以突破性能的上限,大概一年前,我就跟我们的技术大牛同事聊这些思考,得到了一个大牛的共鸣,后来我就做了他的产品经理,他开始着手写一个可以在一定程度上代替gpfdist的命令,后来他的成品命名为lotus,本文后续的一些测试中,包括文件名和数据库的名称都是使用的lotus,就是源于这里,大牛的命令就叫lotus,我们讨论了gpfdist是单进程的服务,所以,大神的第一次入手就开始干多线程切分文件和分发文件的实现,我们进行了测试,但测试发现,网卡是个更大的性能瓶颈,然后我就给大牛提需求,上ZSTD压缩,我们还对ZSTD的各个压缩级别做了测试,最终,我们发现,ZSTD压缩,可以极大的节省网络带宽的开销,在大神上ZSTD需求期间,我就开始琢磨,我是不是可以改造一下gpfdist的代码,加入ZSTD压缩,经过两三周的学习和努力,最终有了ZSTD改造版的gpfdist,本文不会深入讲解如何改造gpfdist的过程,因为过程崎岖坎坷,只是介绍大概的优化思想。

关于大牛的命令,可以参见lotus文档了解大牛的神作。 本文的测试场景,大牛的命令可以做到3182 ms完成数据扫描,加载性能为3320 MB/s。

本文主要探讨如何来进行性能的调优。


首先,我们准备了一个测试数据文件:

[gpadmin@smdw ~]$ ll --block-size M /dev/shm/lotus.txt
-rw-r--r--. 1 root root 10567M Jul 27 15:07 /dev/shm/lotus.txt

文件尺寸为10567MB,为了确保整个测试过程不受磁盘性能的影响,我们将测试用的数据文件放到内存中,即/dev/shm目录下。


首先,我们在一个有72个Primary的集群,创建一个常规的gpfdist外部表,由于GP集群资源有限,设备比较老,这里主要是为了gpfdist的极限性能,所以,只对外部表执行count(*)的操作,不会真正的执行数据入库的操作。

CREATE READABLE EXTERNAL TABLE ext_test
(
  a text
)
LOCATION ('gpfdist://172.28.8.251:8080/dev/shm/lotus.txt')
FORMAT 'TEXT' (DELIMITER 'OFF');

启动gpfdist服务,使用简洁模式,指定了路径和端口,其他参数保持缺省值:

[root@smdw ~]# . /usr/local/greenplum-db-6.9.0/greenplum_path.sh
[root@smdw ~]# gpfdist -p 8080 -d /../ -s
2020-09-19 12:45:47 7512 INFO Before opening listening sockets - following listening sockets are available:
2020-09-19 12:45:47 7512 INFO IPV6 socket: [::]:8080
2020-09-19 12:45:47 7512 INFO IPV4 socket: 0.0.0.0:8080
2020-09-19 12:45:47 7512 INFO Trying to open listening socket:
2020-09-19 12:45:47 7512 INFO IPV6 socket: [::]:8080
2020-09-19 12:45:47 7512 INFO Opening listening socket succeeded
2020-09-19 12:45:47 7512 INFO Trying to open listening socket:
2020-09-19 12:45:47 7512 INFO IPV4 socket: 0.0.0.0:8080
Serving HTTP on port 8080, directory /

执行外部表的count(*)查询,为了准确的评估,我们进行连续3次查询:

lotus=# SELECT count(*) FROM ext_test;
NOTICE:  External scan from gpfdist(s) server will utilize 64 out of 72 segment databases
  count
----------
 89000000
(1 row)

Time: 9655.308 ms
lotus=# SELECT count(*) FROM ext_test;
NOTICE:  External scan from gpfdist(s) server will utilize 64 out of 72 segment databases
  count
----------
 89000000
(1 row)

Time: 9635.492 ms
lotus=# SELECT count(*) FROM ext_test;
NOTICE:  External scan from gpfdist(s) server will utilize 64 out of 72 segment databases
  count
----------
 89000000
(1 row)

Time: 9633.638 ms

平均耗时为9641 ms。

┌nmon─16g──────[H for help]───Hostname=smdw─────────Refresh= 2secs ───12:49.07────────────────────────────────────────────────────────────────────────────────────────┐
│ CPU Utilisation ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────               │
│---------------------------+-------------------------------------------------+                                                                                       │
│CPU User%  Sys% Wait%  Idle|0          |25         |50          |75       100|                                                                                       │
│  1   0.0   0.0   0.0 100.0|>                                                |                                                                                       │
│  2   0.0   0.6   0.0  99.4| >                                               |                                                                                       │
│  3   0.0   1.0   0.0  99.0|>                                                |                                                                                       │
│  4   0.5   3.6   0.0  95.9|s>                                               |                                                                                       │
│  5   0.0   0.0   0.0 100.0|>                                                |                                                                                       │
│  6   0.0   0.5   0.0  99.5|>                                                |                                                                                       │
│  7   0.5   0.5   0.5  98.5|>                                                |                                                                                       │
│  8   1.0  12.1   0.0  86.9|ssssss>                                          |                                                                                       │
│  9   0.0   0.0   0.0 100.0|>                                                |                                                                                       │
│ 10   1.0   6.1   0.0  92.9|sss>                                             |                                                                                       │
│ 11   0.0   0.0   0.0 100.0|>                                                |                                                                                       │
│ 12   1.0   9.5   0.0  89.4|ssss>                                            |                                                                                       │
│ 13   0.5   3.5   0.0  96.0|s>                                               |                                                                                       │
│ 14   0.5   4.5   0.0  94.9|ss  >                                            |                                                                                       │
│ 15   1.0  12.1   0.0  86.9|ssssss>                                          |                                                                                       │
│ 16   1.0  14.1   0.0  84.9|sssssss >                                        |                                                                                       │
│ 17   0.0   0.0   0.0 100.0|>                                                |                                                                                       │
│ 18   0.0   3.5   0.0  96.5|s>                                               |                                                                                       │
│ 19   0.0   0.0   0.0 100.0|>                                                |                                                                                       │
│ 20   0.0   0.0   0.0 100.0|>                                                |                                                                                       │
│ 21   0.5   5.5   0.5  93.5|ss>                                              |                                                                                       │
│ 22   1.5  12.6   0.0  85.9|ssssss>                                          |                                                                                       │
│ 23   0.5   4.1   0.0  95.3|ss >                                             |                                                                                       │
│ 24   1.0  14.6   0.0  84.4|sssssss>                                         |                                                                                       │
│---------------------------+-------------------------------------------------+                                                                                       │
│Avg   0.4   4.6   0.0  95.0|ss>                                              |                                                                                       │
│---------------------------+-------------------------------------------------+                                                                                       │
│ Network I/O ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────               │
│I/F Name Recv=KB/s Trans=KB/s packin packout insize outsize Peak->Recv Trans                                                                                         │
│      lo      1.2       1.2       4.0    4.0   307.5  307.5       16.1     16.1                                                                                      │
│virbr0-ni     0.0       0.0       0.0    0.0     0.0    0.0        0.0      0.0                                                                                      │
│  virbr0      0.0       0.0       0.0    0.0     0.0    0.0        0.0      0.0                                                                                      │
│     em3      0.0       0.0       0.0    0.0     0.0    0.0        0.0      0.0                                                                                      │
│     em1      0.0       0.0       0.0    0.0     0.0    0.0        0.1      0.0                                                                                      │
│     em2      0.0       0.2       0.5    1.0    64.0  230.0        0.4      0.9                                                                                      │
│     em4      0.0       0.0       0.0    0.0     0.0    0.0        0.0      0.0                                                                                      │
│    p1p1   1792.2  1130760.9  27804.925717.6    66.045023.6     1832.9 1130760.9                                                                                     │
│    p1p2      0.0       0.0       0.0    0.0     0.0    0.0        0.0      0.0                                                                                      │
│──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

从nmon的输出来看,网卡的性能已经达到极限了。接下来,我们使用两个网口进行数据获取操作:

DROP EXTERNAL TABLE ext_test;
CREATE READABLE EXTERNAL TABLE ext_test
(
  a text
)
LOCATION (
    'gpfdist://172.28.8.251:8080/dev/shm/lotus.txt',
    'gpfdist://172.28.12.251:8080/dev/shm/lotus.txt'
 )
FORMAT 'TEXT' (DELIMITER 'OFF');

接下来,进行连续3次查询:

lotus=# SELECT count(*) FROM ext_test;
  count
----------
 89000000
(1 row)

Time: 6529.515 ms
lotus=# SELECT count(*) FROM ext_test;
  count
----------
 89000000
(1 row)

Time: 6631.681 ms
lotus=# SELECT count(*) FROM ext_test;
  count
----------
 89000000
(1 row)

Time: 6335.189 ms

平均耗时为6498 ms。 我们通过观察nmon的输出发现,有一个CPU Core已经100%繁忙了,根据我们的经验,我们尝试调整gpfdist的-m参数来增加gpfdist分割数据的效率:

[root@smdw ~]# gpfdist -p 8080 -d /../ -s -m 128000
2020-09-19 12:58:06 11018 INFO Before opening listening sockets - following listening sockets are available:
2020-09-19 12:58:06 11018 INFO IPV6 socket: [::]:8080
2020-09-19 12:58:06 11018 INFO IPV4 socket: 0.0.0.0:8080
2020-09-19 12:58:06 11018 INFO Trying to open listening socket:
2020-09-19 12:58:06 11018 INFO IPV6 socket: [::]:8080
2020-09-19 12:58:06 11018 INFO Opening listening socket succeeded
2020-09-19 12:58:06 11018 INFO Trying to open listening socket:
2020-09-19 12:58:06 11018 INFO IPV4 socket: 0.0.0.0:8080
Serving HTTP on port 8080, directory /

再次测试,平均耗时为5475 ms。性能已经到了极限。


接下来,我们介绍gpfdist的深入优化,首先,我们尝试修改gpfdist源码,加入了异步数据传输和ZSTD压缩传输特性,并使用execute外部表来进行数据获取,我们并没有修改Greenplum的Server端的代码,所以,需要借助execute外部表来完成这个优化测试。测试如下:

[root@smdw tmp]# ./gpfdist -p 8080 -d /../ -s -m 440000
2020-09-19 13:03:47 12544 INFO Before opening listening sockets - following listening sockets are available:
2020-09-19 13:03:47 12544 INFO IPV6 socket: [::]:8080
2020-09-19 13:03:47 12544 INFO IPV4 socket: 0.0.0.0:8080
2020-09-19 13:03:47 12544 INFO Trying to open listening socket:
2020-09-19 13:03:47 12544 INFO IPV6 socket: [::]:8080
2020-09-19 13:03:47 12544 INFO Opening listening socket succeeded
2020-09-19 13:03:47 12544 INFO Trying to open listening socket:
2020-09-19 13:03:47 12544 INFO IPV4 socket: 0.0.0.0:8080
Serving HTTP on port 8080, directory /

创建新的外部表:

CREATE READABLE EXTERNAL WEB TABLE ext_testexcu
(
  a text
)
 EXECUTE E'sh /tmp/gcurl.sh smdw:8080/dev/shm/lotus.txt' 
 FORMAT 'text' (delimiter 'off' null E'\\N' escape E'\\');

进行连续3次测试:

lotus=# SELECT count(*) FROM ext_testexcu;
  count
----------
 89000000
(1 row)

Time: 4189.400 ms
lotus=# SELECT count(*) FROM ext_testexcu;
  count
----------
 89000000
(1 row)

Time: 4213.136 ms
lotus=# SELECT count(*) FROM ext_testexcu;
  count
----------
 89000000
(1 row)

Time: 4179.077 ms

平均耗时为4193 ms。


总结

gpfdist优化情况平均耗时平均加载性能瓶颈点gpfdist服务器带宽消耗无优化9641 ms1096 MB/s网络带宽1096 MB/s增加网络带宽6498 ms1626 MB/sCPU主频1626 MB/s-m为1280005475 ms1930 MB/s网络带宽/CPU主频1930 MB/s修改源码加入ZSTD压缩传输和异步数据传输4193 ms2520 MB/sCPU主频大约380 MB/s

对gpfdist进行ZSTD压缩传输和异步数据传输的优化,主要目的是,降低网络带宽的消耗,充分利用多CPU Core的计算能力。尤其是在网络带宽有限的环境,可以发挥极大的性能优势。

来自:
https://github.com/water32/gpfaq/

控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言