NetACC(Network Accelerator)是一个用户态网络加速库,利用eRDMA的低时延、高吞吐等优势,通过兼容socket接口,实现对现有TCP应用的加速。对于对网络通信性能要求高、需要低延迟和高吞吐量的TCP应用,可以通过NetACC,无需修改应用代码即可适配eRDMA,实现网络加速。
NetACC当前处于公测阶段。
NetACC适用场景
NetACC适用于网络开销较大的场景:
高PPS(Packets per Second)场景:尤其是大量收发小包的场景。使用NetACC可以降低CPU开销,提升系统吞吐能力,例如在Redis处理请求的场景中。
对网络时延敏感的场景:eRDMA的网络时延比TCP更低,可以提升网络响应速度。
反复创建短连接的场景:NetACC可以优化二次连接的速度,加快连接速度,提升系统性能。
安装NetACC
安装方式
通过eRDMA驱动安装
安装eRDMA驱动的时候,NetACC也会一并安装。关于eRDMA驱动的安装,请参见步骤二:为ECS实例安装eRDMA驱动。
单独安装
如果您需要使用特定版本的NetACC或者您需要临时使用NetACC等,您可以在ECS实例上执行以下命令,单独安装NetACC:
sudo curl -fsSL https://netacc-release.oss-cn-hangzhou.aliyuncs.com/release/netacc_download_install.sh | sudo sh
配置文件及参数优化
安装NetACC后默认配置文件是
/etc/netacc.conf,允许用户根据需要调整参数,如消息大小NACC_SOR_MSG_SIZE、RDMA内存注册大小NACC_RDMA_MR_MIN_INC_SIZE和NACC_RDMA_MR_MAX_INC_SIZE、QP承载链接数NACC_SOR_CONN_PER_QP、IO线程数NACC_SOR_IO_THREADS等,以优化性能。配置文件示例如下:
使用NetACC
您可以通过netacc_run命令或者设置环境变量LD_PRELOAD的方式在应用中集成NetACC。使用之前,请您仔细阅读NetACC使用注意事项。
netacc_run命令
netacc_run是一个工具,用于启动应用程序时加载NetACC库,通过在应用程序命令之前增加netacc_run,用户可以比较方便地启动应用程序并应用NetACC加速。
netacc_run提供了很多配置选项,比如IO线程数(-t)、QP复用数(-p)等,这些参数可以帮助优化NetACC的性能。通过netacc_run命令设置的参数会覆盖配置文件中的参数。
使用示例:
以本文中Redis应用为例,在Redis命令之前增加
netacc_run即可实现应用NetACC。启动Redis服务
netacc_run redis-server启动Redis基准测试
netacc_run redis-benchmark
设置LD_PRELOAD环境变量
LD_PRELOAD是一个环境变量,用于指定在程序启动时预先加载的共享库。如果您需要在脚本中自动化NetACC的加载,您可以通过LD_PRELOAD指定NetACC加速库。
执行以下命令,查看NetACC动态库的位置:
ldconfig -p | grep netacc返回信息如下所示:
[ecs-user@i ~]$ ldconfig -p | grep netacc libnetacc-preload.so (libc6,x86-64) => /lib64/libnetacc-preload.so libnetacc_cx.so (libc6,x86-64) => /lib64/libnetacc_cx.so [ecs-user@i ~]$执行以下命令,设置
LD_PRELOAD环境变量来指定预加载库:LD_PRELOAD=/lib64/libnetacc-preload.so your_application此处
your_application是您想要加速的应用程序。使用示例:以本文中Redis应用常用命令为例:
启动Redis服务
LD_PRELOAD=/lib64/libnetacc-preload.so redis-server启动Redis基准测试
LD_PRELOAD=/lib64/libnetacc-preload.so redis-benchmark
NetACC监控
netacc_ss是NetACC中自带的监控工具,您可以执行netacc_ss命令监控使用了NetACC加速的TCP应用进程收发数据的状态。在Server端和Client端均可以执行该命令进行监测。netacc_ss命令详细说明如下:
执行如下命令,查看使用了NetACC加速的TCP应用进程收发数据的状态:
netacc_ss -s all -p <进程ID>您可以通过执行ps -ef | grep <进程名称>命令查询进程ID。
NetACC使用注意事项
使用NetACC时,只有使用支持eRDMA的网卡(IP地址)创建的连接才会被转换为RDMA连接,其他连接还是会使用TCP。
说明如果网络通信的任一端的网卡不支持弹性RDMA接口,那么NetACC将无法创建RDMA连接,而是会回退到使用TCP连接。
使用NetACC时,如果您需要在多个进程之间进行网络通信,您不能将RDMA的socket文件描述符(fd)通过内核的进程间通信(IPC)机制发送给其他进程。
说明RDMA连接是基于特定的队列对(Queue Pair,QP)建立的,而这些QP不支持在不同进程之间直接共享,因此RDMA连接不能在进程间共享。
NetACC框架目前不支持IPv6协议,为了确保在使用NetACC时不出现IPv6相关的冲突或错误,建议通过执行
sysctl net.ipv6.conf.all.disable_ipv6=1命令来禁用系统中的IPv6功能。NetACC动态库不支持热更新,热更新可能造成不可预期的错误,更新前请先停止应用进程。
NetACC目前不支持TCP协议中的部分套接字选项,包括SO_REUSEPORT,SO_ZEROCOPY和TCP_INQ。
NetACC依赖于glibc,无法在非glibc环境下工作,比如Golang。
使用NetACC前,建议您通过执行
ulimit -l unlimited命令来设置进程可以锁定的物理内存的最大量为无限制。说明如果ulimit -l参数设置得过小,那么在RDMA注册内存时可能会因为超出了系统允许的内存锁定限制而失败。
在NetACC中,当应用程序监听一个TCP端口以进行通信时,NetACC会为这个TCP端口额外监听一个RDMA端口(TCP端口加20000),以便在RDMA网络环境中进行高效的数据传输。
说明如果RDMA端口被占用或者超过了有效端口范围,会导致无法正常建立连接。请您合理分配,以避免端口冲突。
在NetACC中,当一个父进程使用
fork()系统调用创建子进程后,子进程默认情况下不会继承父进程已经建立的socket连接。说明fork()后无法继承父进程创建的socket连接,可能会导致无法正常通信,需要重新建立socket连接。
在NetACC中,QP复用功能默认是关闭的。
您可以在NetACC的配置文件中通过
NACC_SOR_CONN_PER_QP或者在运行netacc_run时候指定QP复用数(-p),配置单个QP承载的连接数大于1,即允许多个连接复用1个QP,从而开启QP复用功能。如果开启QP复用功能,因为减少了QP的数量,从而减少了管理开销和资源消耗,特别是在高并发连接的场景下,可以提升整体的通信效率。
当QP复用功能开启时,多个RDMA连接可能会共享同一个本地端口号。这是因为在RDMA中,端口号是用来标识QP的,而不是用来区分连接的。如果多个连接共享同一个QP,它们也会共享同一个本地端口号。
说明如果应用程序需要区分不同的本地端口号(例如,为了实现不同的服务或监听不同的端口),那么不应该开启QP复用功能。因为一旦开启,多个连接将无法通过本地端口号来区分,这可能会导致端口冲突。
Redis应用中使用NetACC
NetACC在Redis应用中的作用
提升系统吞吐能力
NetACC适用于处理每秒需要处理大量数据包的场景,在Redis处理大量请求时,可以降低CPU开销并提升系统吞吐量。
提升网络响应速度
对于需要快速网络响应的Redis应用,NetACC利用eRDMA提供的低时延特性,可以显著提升网络响应速度。
Redis性能基准测试中使用NetACC
redis-benchmark是Redis自带的一个性能测试工具,它可以模拟多个客户端同时对Redis发送请求,以此来评估Redis服务器在不同负载下的性能表现。
测试场景
在redis-benchmark中使用NetACC,模拟100个clients,4个threads,循环5000000次set操作。
准备工作
购买两台支持eRDMA的实例,勾选自动安装eRDMA驱动,并且在主网卡开启eRDMA网络接口。两台ECS实例分别作为Redis的服务端和客户端。
本示例参数如下所示:
镜像:均为Alibaba Cloud Linux 3
实例规格:均为ecs.g8ae.4xlarge
实例主网卡的私网IP地址:Server端(172.17.0.90)、Client端(172.17.0.91)。在以下测试中,您需要根据实际情况替换IP地址。
说明本文以在实例的主网卡上开启eRDMA网络接口为例进行测试,那么这里的172.17.0.90即Redis服务端所在ECS实例的主网卡的私网IP地址。
如果您是通过辅助弹性网卡上开启eRDMA网络接口进行测试,那么这里的IP地址,需要改为您实际的辅助弹性网卡的私网IP地址。更多信息,请参见步骤三:为ECS实例绑定ERI。
具体操作
分别远程连接Server端和Client端的ECS实例。
具体操作,请参见使用Workbench登录Linux实例。
确认两台ECS实例的eRDMA驱动安装完成。
在实例启动后,您可以通过
ibv_devinfo命令确认已安装完毕:如果正确安装完成后,命令返回如下所示:
[root@redis-server ~]# ibv_devinfo hca_id: erdma_0 transport: eRDMA (1) fw_ver: 0.2.0 node_guid: 0216:3eff:fe10:d924 sys_image_guid: 0216:3eff:fe10:d924 vendor_id: 0x1ded vendor_part_id: 4223 hw_ver: 0x0 phys_port_cnt: 1 port: 1 state: PORT_ACTIVE (4) max_mtu: 1024 (3) active_mtu: 1024 (3) sm_lid: 0 port_lid: 0 port_lmc: 0x00 link_layer: Ethernet [root@redis-server ~]#如果尚未完成安装,命令返回如下所示(eRDMA相关驱动程序的安装可能需要几分钟,您可以稍后再尝试):
[root@ixxxxxxxxxxxxx Z ~]# ibv_deninfo -bash: ibv_deninfo: command not found
在两台ECS实例上分别执行以下命令安装Redis。
sudo yum install -y redis安装完成后,返回信息如下所示:
[root@redis-server ~]# sudo yum install -y redis Last metadata expiration check: 0:06:35 ago on Tue 03 Sep 2024 10:50:07 AM CST. Dependencies resolved. ================================================================================ Package Architecture Version Repository Size ================================================================================ Installing: redis x86_64 6.2.7-1.0.2.al8 alinux3-updates 1.2 M Transaction Summary ================================================================================ Install 1 Package Total download size: 1.2 M Installed size: 4.3 M Downloading Packages: redis-6.2.7-1.0.2.al8.x86_64.rpm 15 MB/s | 1.2 MB 00:00 -------------------------------------------------------------------------------- Total 15 MB/s | 1.2 MB 00:00 Running transaction check Transaction check succeeded. Running transaction test Transaction test succeeded. Running transaction Preparing : 1/1 Running scriptlet: redis-6.2.7-1.0.2.al8.x86_64 1/1 Installing : redis-6.2.7-1.0.2.al8.x86_64 1/1 Running scriptlet: redis-6.2.7-1.0.2.al8.x86_64 1/1 Verifying : redis-6.2.7-1.0.2.al8.x86_64 1/1 Installed: redis-6.2.7-1.0.2.al8.x86_64 Complete! [root@redis-server ~]#通过
redis-benchmark进行Redis性能的基准测试。使用NetACC加速测试
在Server端的ECS实例上,执行以下命令,以NetACC加速的方式启动Redis服务:
netacc_run redis-server --port 6379 --protected-mode no说明您需要替换对应的6379为您实际启动Redis服务的端口号,详见redis-server常用命令参数说明。
本测试以
netacc_run命令方式加速,关于更多使用NetACC方式,请参见使用NetACC。
正确启动后,返回如下所示:
[root@redis-server ~]# netacc_run redis-server --port 6379 --protected-mode no 114379:C 03 Sep 2024 10:59:24.477 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo 114379:C 03 Sep 2024 10:59:24.477 # Redis version=6.2.7, bits=64, commit=00000000, modified=0, pid=114379, just started 114379:C 03 Sep 2024 10:59:24.477 # Configuration loaded 114379:M 03 Sep 2024 10:59:24.478 * monotonic clock: POSIX clock_gettime 114379:M 03 Sep 2024 10:59:24.479 # A key '__redis__compare_helper' was added to Lua globals which is not on the globals allow list nor listed on the deny list. Redis 6.2.7 (00000000/0) 64 bit Running in standalone mode Port: 6379 PID: 114379 https://redis.io 114379:M 03 Sep 2024 10:59:24.479 # Server initialized 114379:M 03 Sep 2024 10:59:24.479 # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect. 114379:M 03 Sep 2024 10:59:24.479 * Ready to accept connections在Client端的ECS实例上,执行以下命令,开启Redis基准测试:
netacc_run redis-benchmark -h 172.17.0.90 -p 6379 -c 100 -n 5000000 -r 10000 --threads 4 -d 512 -t set说明您需要替换对应的172.17.0.90和6379为您实际启动Redis服务的服务器的IP地址和端口号,详见redis-benchmark常用命令参数说明。
不同的网络环境下测试结果不同,本文测试数据仅供参考,具体执行结果以您的实际环境为准。
可以看到最下面的Summary信息,最后打印的是77万左右的rps。关于指标详细说明,详见redis-benchmark常用测试结果指标说明。
未使用NetACC加速测试
在Server端的ECS实例上,执行以下命令,启动Redis服务:
redis-server --port 6379 --protected-mode no --save说明您需要替换对应的6379为您实际启动Redis服务的端口号,详见redis-server常用命令参数说明。
正确启动后,返回如下所示:
[root@redis-server ~]# redis-server --port 6379 --protected-mode no --save 114198:C 03 Sep 2024 10:57:28.957 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo 114198:C 03 Sep 2024 10:57:28.957 # Redis version=6.2.7, bits=64, commit=00000000, modified=0, pid=114198, just started 114198:C 03 Sep 2024 10:57:28.957 # Configuration loaded 114198:M 03 Sep 2024 10:57:28.958 * monotonic clock: POSIX clock_gettime 114198:M 03 Sep 2024 10:57:28.958 # A key '__redis__compare_helper' was added to Lua globals which is not on the globals allow list nor listed on the deny list. Redis 6.2.7 (00000000/0) 64 bit Running in standalone mode Port: 6379 PID: 114198 https://redis.io 114198:M 03 Sep 2024 10:57:28.958 # Server initialized 114198:M 03 Sep 2024 10:57:28.958 # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect. 114198:M 03 Sep 2024 10:57:28.958 * Ready to accept connections在Client端的ECS实例上,执行以下命令,开启Redis基准测试:
redis-benchmark -h 172.17.0.90 -c 100 -n 5000000 -r 10000 --threads 4 -d 512 -t set说明您需要替换对应的172.17.0.90和6379为您实际启动Redis服务的服务器的IP地址和端口号, 详见redis-benchmark常用命令参数说明。
不同的网络环境下测试结果不同,本文测试数据仅供参考,具体执行结果以您的实际环境为准。
可以看到最下面的Summary信息,最后打印的是33万左右的rps。关于指标详细说明,详见redis-benchmark常用测试结果指标说明。

