1 问题背景
GreenPlum6.9.1的应用程序移植到鲲鹏服务器上,benchmark测试发现业务吞吐量没有达到硬件预期,需要做相应调优。
2 原因分析
- BIOS配置
主要针对CPU预取等BIOS配置进行优化,提升基础性能。
- 操作系统参数配置
结合网络和IO资源进行优化。
- 数据库层调优
结合热点函数发现资源瓶颈进行升入分析调优。
3 解决方案
3.1 BIOS层调优
重启服务器,按Esc键进入BIOS设置界面
1、关闭SMMU
依次进入“Advanced > MISC Config > > Support Smmu”,设置为Disabled
2、关闭CPU预取
依次进入“Advanced > MISC Config > CPU Prefetching Configuration”设置为Disabled。
3、设置PCIE max Payload size为512B
选择“Advanced > PCIe Configure”,把所有的PCIE口Max Payload Size 设置为 512B
注意:完成BIOS各项设置后按“F10”保存退出(永久有效)
3.2 OS层优化
(1)CPU开启性能模式
cpupower frequency-set -g performance
(2)网卡中断绑核优化
步骤 0:查看使用网卡的物理所属numa节点 # ethtool -i eth_name // 找到对应的bus-info # 根据bus-info 执行: lspci -vs 0000:02:00.0 步骤 1:停止irqbalance。 # systemctl stop irqbalance.service # systemctl disable irqbalance.service 步骤 2:设置网卡队列个数为CPU的核数,如48。 # ethtool -L eth_name combined 48 步骤 3:查询中断号。 # cat /proc/interrupts | grep $ eth_name | awk -F ':' '{print $1}' 步骤 4:根据中断号,将每个中断分别绑定在一个核上,其中cpuID为0表示core0。 # echo $cpuID > /proc/irq/$irq/smp_affinity_list //如对于中断号是1298 è1329(32个队列绑定在0-31的core上),可使用如下命令简化设置 # for((i=1298; i <=1298+31;i++));do echo $(((${i} - 1298))) > /proc/irq/${i}/smp_affinity_list;done //查看设置是否成功 # for((i=1298; i <=1298+31;i++));do cat /proc/irq/${i}/smp_affinity_list;done |
(3)设置网卡中断聚合参数,减少网络时延
ethtool -c eth_name // 查看当前配置 // 设置中断聚合,使更快响应网络请求,各参数根据场景需要调整到最佳值 ethtool -C enp125s0f0 adaptive-rx off adaptive-tx off rx-usecs 10 tx-usecs 10 rx-frames 10 tx-frames 10 |
(4)IO调度策略调优
cat deadline或noop > /sys/block/${device}/ queue/scheduler
当使用的HDD盘时,使用deadline调度策略,使用SSD盘时,优先使用noop调度策略。(针对数据盘操作)
3.3 GreenPlum数据库层调优
(1)数据库内置参数调优
对于GreenPlum数据库调优,可优先在子节点配置多个segement,segment数越多时每个节点上运行的Postgres进程也越多,类似于每个节点上会有多实例Pg数据库,适合发挥鲲鹏的多核优化,其次还可以基于GreenPlum的数据库参数进行适当优化。
gp_set_proc_affinity
该参数可以设置segment进程和主节点进程的cpu亲和性,在数据库启动时进行自动绑核。默认为off状态,推荐对子节点的segment进程绑核,主节点不绑核。
Host节点关闭:gp_set_proc_affinity off
segment节点打开:gp_set_proc_affinity on
注:还有一些进程共享参数的设置可参考解决鲲鹏Boostkit数据库调优文档,(https://support.huaweicloud.com/tngg-kunpengdbs/kunpenggreenplum_05_0015.html)
(2)鲲鹏加速库优化手段
Postgres使用到的压缩库为zstd,可以通过perf top查看当前的sql测试场景是否zstd压缩/解压缩成为热点,如果是则可以使用加速库zstd进行优化。
现场观察到zstd的相关热点函数占比较高,可进行针对性优化。
优化方法:
下载编译zstd: https://github.com/kunpengcompute/zstd
进行编译,将libzstd.so.1.4.4文件拷贝到系统目录/lib64/路径下,创建并覆盖libzstd对应软连接,运行时可观测热点调用的zstd加速库版本确认是否生效。
(3)低版本CRC热点函数优化(源码)
现象:热点:pg_comp_crc32c_sb8 集中在静态库:all: libpgport.a libpgport_srv.a
pg_comp_crc32c_sb8 这个函数有8%的热点;
src/include/port/pg_crc32c.h:60:extern pg_crc32c pg_comp_crc32c_sb8(pg_crc32c crc, const void *data, size_t len); src/include/port/pg_crc32c.h:72: ((crc) = pg_comp_crc32c_sb8((crc), (data), (len))) src/include/port/pg_crc32c.h:89:extern pg_crc32c pg_comp_crc32c_sb8(pg_crc32c crc, const void *data, size_t len); src/port/pg_crc32c_choose.c:58: pg_comp_crc32c = pg_comp_crc32c_sb8; |
修改src/port/pg_crc32c_sb8.c文件内容
优化:
Postgres数据库在11版本及以后才增加了armv8的crc等特性,对鲲鹏支持相对友好,在选用GreenPlum数据库版本时,优先推荐客户使用内核为Postgres 11及以后的版本。如果是内核数据库是低于postgre11版本,可采用将高版本中的src/port/pg_crc32c_armv8.c文件进行回合,优化crc为硬算模式。(回合后需要在configure中对CFLAGS增加-march=armv8-a+crc)
(4)高并发查询时主节点s_lock热点函数占用高场景优化
Perf top观测到的s_lock热点函数:
由于GreenPlum对于锁没有相关数据库配置参数调整,需在src/backend/storage/lmgr/s_lock.c文件修改spins_per_delay变量参数,减少自旋锁争抢程度,可根据实际并发情况调整,调整直到s_lock热点函数占用在预期范围即可。调整确定spins_per_delay变量时,需要同步测试其他场景(如insert、update等),避免过于追求单查询TPS,导致其他场景性能下降过大,综合各测试场景找到该参数的一个合理值。
修改代码行实例(参数值仅供参考,需结合实际情况设定):
4 总结
综上,调优相关思路总结如下:
- 熟悉业务数据流,了解整个大致原理及数据走向
- 检查对齐硬件配置资源
- 观察性能瓶颈点,不忽略任何可疑点
- 剖析组件原理,寻找新的优化措施
- 避免参数组合循环尝试优化,先做原理性分析再下手