Gazelle 加速openGauss使用说明
背景介绍
openGauss是一款高性能数据库,Gazelle作为一款高性能用户态协议栈,能够大幅提高应用的网络I/O吞吐能力。通过使用Gazelle加速openGauss,可有效提高openGauss性能。 gazelle在openGauss单机场景中,能够提升15%的性能,一主一备场景中,能够提升5%的性能。
功能约束
- 当前验证使用的openGauss版本是openGauss 6.0.0(LTS)版本,其他版本未做过验证,可能不支持。
- 当前gazelle验证通过openGauss单机、一主一备场景的加速使能,其他场景未做过验证,可能不支持。
- Gazelle不支持端口复用:如果在用户态协议栈的IP上使用了某个端口,其他IP不能再使用这个端口。
用户态环境搭建
前置条件
- 数据库安装完成以及完成内核态数据库正常启动。内核态具体可参考:openGauss官网
- 安装gazelle及依赖
yum -y install gazelle dpdk libconfig numactl libboundscheck libcap
- benchmark 安装使用可参考 benchmarkSql使用
Gazelle环境配置
通过以下命令查看支持的大页大小。
ll /sys/kernel/mm/hugepages/
一般来说,每个numa节点需要设置2-3G的大页内存。通常为4个numa节点,即需要8-12G的大页内存。根据支持的大页大小设置大页数量。
例如加入hugepages-1048576kB
(1G)的大页,这里选择的是20个大页。对应内存为20GB,足够分配使用。需要保证数量为4的倍数。这个数值不宜过大,过大时会占据过多操作系统内存。
echo 20 > /sys/kernel/mm/hugepages/hugepages-1048576kB/nr_hugepages
#设置完成之后,在本地创建磁盘挂载:
mkdir /mnt/hugepages-1G
mount -t hugetlbfs -o pagesize=1G nodev /mnt/hugepages-1G
#加载ko
modprobe vfio enable_unsafe_noiommu_mode=1
modprobe vfio-pci
说明:
Gazelle部署详见Gazelle用户指南
不同网卡绑定用户态方法详见Gazelle网卡支持及使用
配置lstack.conf文件
使用对应数据库用户编写lstack.conf,即保证用户具备该文件的访问权限。
几个关键配置项说明及修改点:
- dpdk_args
3096,3096,3096,3096
为每个numa设置的内存大小。这里设置3GB。
/mnt/hugepages-1G
修改为大页环境配置中设置的路径。
- num_cpus
30,31,62,63,94,95,126,127
:lstack设置的网络中断核。这里设置的是每个numa的最后两个CPU号。一共使用8个中断。
- app_bind_numa
该参数决定是否将epoll/poll线程绑定到对应的numa节点上。需设置为0,即不绑定。gazelle绑核策略与gauss绑核策略冲突,此处使用gauss绑核策略。
- host_addr、mask_addr、gateway_addr、devices
获取需要的网卡ip信息。一般通过使用ip addr show
命令查看,即可获取所需信息。gateway_addr一般是ip将最后一位改为1。可以通过route -n
查看gateway。
需要配置的网卡信息:
host_addr:20.20.20.119
mask_addr:255.255.255.0
gateway_addr:20.20.20.1
devices:78:b4:6a:40:16:30
执行ip addr show
命令后截取的网卡信息:
8: enp7s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 78:b4:6a:40:16:30 brd ff:ff:ff:ff:ff:ff
inet 20.20.20.149/24 brd 20.20.20.255 scope global enp7s0
valid_lft forever preferred_lft forever
- app_exclude_cpus
排除的CPU编号。openGauss采用CPU0作为xlog写入线程。采用app_exclude_cpus="0"
这个方式排除对CPU0的绑核处理。
- listen_shadow 是否使用影子fd监听,0为关闭,1为开启。单listen线程,多协议栈线程时使能。此处需要开启。
配置文件参考实例:
dpdk_args=["--socket-mem", "3096,3096,3096,3096", "--huge-dir", "/mnt/hugepages-1G", "--proc-type", "primary", "--legacy-mem"]
use_ltran=0
kni_switch=0
low_power_mode=0
#needed mbuf count = tcp_conn_count * mbuf_count_per_conn
tcp_conn_count = 1500
mbuf_count_per_conn = 350
# send ring size, default is 32, max is 2048
send_ring_size = 32
# 0: when send ring full, send return
# 1: when send ring full, alloc mbuf from mempool to send data
expand_send_ring = 0
#protocol stack thread per loop params
#read data form protocol stack into recv_ring
read_connect_number = 4
#process rpc msg number
rpc_number = 4
#read nic pkts number
nic_read_number = 128
#each cpu core start a protocol stack thread.
num_cpus="30,31,62,63,94,95,126,127"
#app worker thread bind to numa in epoll/poll.
app_bind_numa=0
#app main thread affinity set by dpdk.
main_thread_affinity=0
host_addr="20.20.20.119"
mask_addr="255.255.255.0"
gateway_addr="20.20.20.1"
devices="78:b4:6a:40:16:31"
udp_enable=0
#0: use rss rule
#1: use tcp tuple rule to specify packet to nic queue
tuple_filter=0
#tuple_filter=1, below cfg valid
num_process=1
process_numa="0,1"
process_idx=0
#tuple_filer=0, below cfg valid
listen_shadow=1
#exclude cpu
app_exclude_cpus="0"
提权
对gaussdb二进制、liblstack.so提权,对ls命令提权。
#对gaussdb二进制提权
sudo setcap 'cap_chown,cap_dac_override,cap_dac_read_search,cap_sys_rawio,cap_net_admin,cap_net_raw,cap_sys_admin+eip' `which gaussdb`
#对liblstack.so提权
sudo chmod u+s /usr/lib64/liblstack.so
#对ls命令提权
setcap 'cap_chown,cap_dac_override,cap_dac_read_search,cap_sys_rawio,cap_net_admin,cap_net_raw,cap_sys_admin+eip' $(which ls)
提权之后的gaussdb不会再从LD_LIBRARY_PATH中查找动态库路径,因此还需要配置全局动态库路径:vim /etc/ld.so.conf.d/opengauss.conf
。将实际的动态库对应路径内容写入。
/home/code/openGauss-server/dest/lib
必要路径权限
需要修改大页内存对应的文件路径权限和liblstack.so权限,允许用户访问。
chown -R 777 /mnt/
chmod 777 /usr/lib64/liblstack.so
还需要确保编写的lstack.conf文件也具备用户访问权限。
数据库测试
必要信息准备
首先数据库测试需要至少一块NVME硬盘用于数据存储。
本地测试为HINIC网卡。
一些信息可以下面这些命令查询,假设网卡名为:enp8s0。
# PCI查询:
ethtool -i enp8s0 | grep bus-info
切换用户态网卡
该操作会导致该网卡无法使用。请使用BMC机器操作,或者具备双网口的环境操作。否则环境会不可用。 使用root用户切换网卡为用户态网卡。该操作会停止该网卡并用dpdk接管。如果使用该网卡建立ssh连接,会直接断开连接。
#PCI=0000:08:00.0
#NET_DEVICE=enp8s0
ifconfig enp8s0 down
sudo modprobe vfio enable_unsafe_noiommu_mode=1
sudo echo 1 > /sys/module/vfio/parameters/enable_unsafe_noiommu_mode
sudo dpdk-devbind -b vfio-pci 0000:08:00.0
启动数据库
openGauss 配置文件修改:
在openGauss数据库的配置文件‘postgresql.conf’ 追加参数:追加参数文件
数据库配置 postgresql.conf文件修改,需要需根据实际情况修改线程池相关参数,以及增加数据配置文件中性能参数。
# 此参数为 openGauss 绑定cpu 个数, 如 openGauss 绑定 1-29 32-61 64-93 96-125 共计 4 numa 分区,119 个 cpu, 线程数为 cpu 的整数倍,以4倍为例,为 476
thread_pool_attr = '476,4,(cpubind:1-29,32-61,64-93,96-125)'
# 此参数在使用 gazelle 加速时打开此选项
enable_gazelle_performance_mode=on
环境清理: 为避免后台缓存和后台信号量对测试有影响,需要清理下对应的数据。
ipcs -m | awk '$2 ~/[0-9]+/ {print $2}' | while read s; do ipcrm -m $s; done
ipcs -s | awk '$2 ~/[0-9]+/ {print $2}' | while read s; do ipcrm -s $s; done
echo 3 > /proc/sys/vm/drop_caches
启动数据库:
# 设置Gazelle 配置文件路径
LSTACK_CONF_PATH=/usr1/gazelle/gazelle_conf/lstack.conf
# 启动 Gazelle 加速 gaussdb, 已启动 openGauss 下dn1 数据库节点为例
LD_PRELOAD=liblstack.so GAZELLE_BIND_PROCNAME=gaussdb LSTACK_CONF_PATH=$LSTACK_CONF_PATH /home/opengauss/software/openGauss/bin/gaussdb -D /home/opengauss/software/openGauss/data/dn1
启动TPCC测试
客户端需要根据实际情况配置网络中断,此处以配置20个中断为例,对应的bind_irq.sh文件:
intf=enp4s0
ethtool -G ${intf} rx 1024 tx 1024
ethtool -K ${intf} lro on
ethtool -L ${intf} combined ${combined}
irq_list=`cat /proc/interrupts | grep $intf | awk {'print $1'} | tr -d ":"`
irq_array_net=($irq_list)
cpu_array_irq=(27 28 29 30 31 59 60 61 62 63 91 92 93 94 95 123 124 125 126 127)
for (( i=0;i<20;i++))
do
echo "${cpu_array_irq[$i]}" > /proc/irq/${irq_array_net[$i]}/smp_affinity_list
done
for j in ${irq_array_net[@]}
do
cat /proc/irq/$j/smp_affinity_list
done
benchmark客户端需要根据实际情况修改并发数。 通常修改为postgresql.conf配置文件中cpubind参数,核数量的倍数如1-29,32-61,64-93,96-125核数为119,取4倍得714,则将并发数修改为714:
terminals=714
恢复
- 停止数据库。
- 使用root切换回内核态网卡。 将用户态网卡切换为内核态网卡:
#PCI=0000:08:00.0
#NET_DEVICE=enp8s0
#IP=20.20.20.119
sudo dpdk-devbind -u 0000:08:00.0
sudo dpdk-devbind -b hinic 0000:08:00.0
sudo ifconfig enp8s0 20.20.20.119 netmask 255.255.255.0
测试结论
在单机测试中,实测TPCC性能大致提升15%左右。
openGauss文件配置参考
postgresql.conf配置文件:打开postgresql.conf文件后,在文件末尾追加如下内容(IP需根据实际ip更改):
max_connections = 4096
allow_concurrent_tuple_update = true
audit_enabled = off
checkpoint_segments = 1024
checkpoint_timeout = 15min
cstore_buffers = 16MB
enable_alarm = off
enable_codegen = false
enable_data_replicate = off
full_page_writes = off
max_files_per_process = 100000
max_prepared_transactions = 2048
shared_buffers = 350GB
#max_process_memory = 100GB
use_workload_manager = off
wal_buffers = 1GB
work_mem = 1MB
log_min_messages = FATAL
transaction_isolation = 'read committed'
default_transaction_isolation = 'read committed'
synchronous_commit = on
fsync = on
maintenance_work_mem = 2GB
vacuum_cost_limit = 10000
autovacuum = on
autovacuum_mode = vacuum
autovacuum_max_workers = 20
autovacuum_naptime = 5s
autovacuum_vacuum_cost_delay = 10
#xloginsert_locks = 48
update_lockwait_timeout = 20min
enable_mergejoin = off
enable_nestloop = off
#-----
enable_hashjoin = off
#enable_cbm_tracking = off
enable_bitmapscan = on
enable_material = off
wal_log_hints = off
log_duration = off
checkpoint_timeout = 15min
autovacuum_vacuum_scale_factor = 0.1
autovacuum_analyze_scale_factor = 0.02
enable_save_datachanged_timestamp = false
# enable_stat_send = off
# enable_commandid_send = off
log_timezone = 'PRC'
timezone = 'PRC'
lc_messages = 'C'
lc_monetary = 'C'
lc_numeric = 'C'
lc_time = 'C'
enable_thread_pool = on
enable_double_write = on
enable_incremental_checkpoint = on
enable_opfusion = on
instr_unique_sql_count=0
advance_xlog_file_num = 100
numa_distribute_mode = 'all'
track_activities = off
enable_instr_track_wait = off
enable_instr_rt_percentile = off
track_counts = off
track_sql_count = off
enable_instr_cpu_timer = off
plog_merge_age = 0
# numa_excluded_cpus = '29,30,31,61,62,63,93,94,95,125,126,127'
# numa_excluded_cpus = '28,29,30,31,60,61,62,63,92,93,94,95,124,125,126,127'
#enable_crc_check = off
session_timeout = 0
enable_instance_metric_persistent = off
enable_logical_io_statistics = off
enable_page_lsn_check = off
enable_user_metric_persistent = off
enable_xlog_prune = off
enable_resource_track = off
instr_unique_sql_count=0
remote_read_mode = non_authentication
client_min_messages = ERROR
log_min_messages = FATAL
enable_asp = off
enable_bbox_dump = off
bgwriter_flush_after = 32
#gs_clean_timeout = '300s'
#minimum_pool_size = 200
wal_keep_segments = 1025
#scan_fusion
enable_bitmapscan = off
enable_seqscan = off
track_activities='off'
enable_resource_track='off'
enable_instr_rt_percentile='off'
enable_instr_cpu_timer='off'
# bypass_workload_manager='off'
enable_asp='off'
enable_thread_pool = on
xloginsert_locks=16
checkpoint_segments=8000
enable_stmt_track=false
data_replicate_buffer_size=128MB
#bgwriter_thread_num = 1
bgwriter_delay = 5s
incremental_checkpoint_timeout = 5min
pagewriter_thread_num = 2
candidate_buf_percent_target = 0.3
pagewriter_sleep = 100ms
standby_shared_buffers_fraction = 0.9
#replconninfo1 = 'localhost=20.20.20.58 localport=21131 localheartbeatport=21135 localservice=21134 remotehost=20.20.20.64 remoteport=21131 remoteheartbeatport=21135 remoteservice=21134'
# 2020-12-20
enable_incremental_checkpoint = on
checkpoint_segments = '4096'
checkpoint_timeout = 50min
#enable_thread_pool = off
max_process_memory = 240GB
shared_buffers = 180GB
wal_level = archive
hot_standby = off
wal_receiver_buffer_size = 256MB
walsender_max_send_size = 32MB
# 2021-03-16
xloginsert_locks = 8
wal_file_init_num = 30
#xlog_idle_flushes_before_sleep = 500000000
walwriter_sleep_threshold = 50000
wal_writer_delay = 150
undo_zone_count = 0
walwriter_cpu_bind = 0
checkpoint_segments = 32768
local_syscache_threshold = 16MB
enable_cachedplan_mgr = off
enable_global_syscache = off
time_record_level = 1
enable_beta_opfusion = on
#wal_file_init_num = 10000
#advance_xlog_file_num = 50000
light_comm = on
enable_indexscan_optimization = on
hot_standby = off
checkpoint_segments = 3000
advance_xlog_file_num = 100000
thread_pool_attr = '476,4,(cpubind:1-29,32-61,64-93,96-125)'
enable_gazelle_performance_mode=on
#------------------------------------------------------------------------------
wal_file_init_num = 40000
advance_xlog_file_num = 100000