通过ECS控制台新购买的Alibaba Cloud Linux 3实例已经默认启用了XPS机制。如果发现您的存量ECS实例尚未启用XPS,您可以通过本文的操作方法来配置XPS。
XPS概述
XPS(Transmit Packet Steering)是一种在多队列网卡上发送数据报文时,自动选择发送队列的机制。它通过建立发送队列和CPU集合之间的映射关系,使得内核能够根据这一映射关系,在某个CPU发送数据报文时,自动选择与该CPU相关联的发送队列来完成报文传输。内核会记录数据流的首个报文选择的发送队列,并将该队列用于后续报文的传输,从而减少为每个报文计算发送队列的开销。
XPS的优势体现如下:
缓解不同CPU对同一个发送队列的竞争,进而降低网卡队列发送数据时的锁冲突,提升数据报文发送效率。
XPS配置的发送队列与CPU之间的映射关系与virtio网卡绑定的发送队列的亲和性一致,这降低了报文发送过程中缓存失效(cache miss)的可能性和锁竞争导致的缓存失效的可能性,从而提高了网络发送性能。
配置XPS
远程连接目标ECS实例。
具体操作,请参见通过密码或密钥认证登录Linux实例。
运行以下命令,检查目标ECS实例是否配置了XPS(确保内核使能了CONFIG_XPS)。
以网卡eth0为例:
cat /sys/class/net/eth0/queues/tx-*/xps_cpus
如下图所示,如果命令输出结果全部为0,则表示ECS实例没有启用XPS,请继续执行后续步骤配置XPS。
为具有不同CPU和发送队列数目的所有virtio网卡设置和内核策略相同的XPS配置。
运行以下命令,在当前目录下新建文件,例如
xps_config.py
,用于设置XPS配置。vim xps_config.py
按
i
键进入编辑模式,并拷贝以下内容至xps_config.py
文件。# encoding: utf-8 # This implements the default configuration of kernel XPS. # Note: The configuration of this script only applies to virtio-net nics. import os import multiprocessing def setup_xps(dev): cpu_count = multiprocessing.cpu_count() txq_dir = "/sys/class/net/{0}/queues/".format(dev) queue_count = len([f for f in os.listdir(txq_dir) if f.startswith("tx-")]) if queue_count <= 1: print("The number of txq: {0} <= 1, exit...".format(queue_count)) return group, stragglers = divmod(cpu_count, queue_count) stragglers = 0 if group == 0 else stragglers group = max(group, 1) cpu = 0 queue_final_bitmap = "" # We do not need to care about numa node information # So we must pay attention to the perfermance in multiple numa node scene!! for i in range(queue_count): group_size = (group + 1) if i < stragglers else group queue_per_bitmap = 0 for j in range(group_size): cpu_bitmap = 1 << cpu cpu += 1 queue_per_bitmap |= cpu_bitmap cpu = 0 if cpu >= cpu_count else cpu queue_final_bitmap = hex(queue_per_bitmap)[2:] if "L" in queue_final_bitmap: queue_final_bitmap = queue_final_bitmap.replace("L", "") result_bitmap = output_seg(queue_final_bitmap) eth_txq_path = "/sys/class/net/{0}/queues/tx-{1}/xps_cpus".format(dev, i) with open(eth_txq_path, "w") as fxps: fxps.write(result_bitmap) print("{0}'s XPS configuration done.".format(dev)) def output_seg(bitmap): result = "" count = 0 for char in reversed(bitmap): if count % 8 == 0 and count != 0: result = "," + result result = char + result count += 1 return result def process_devs(): eth_dir = "/sys/class/net/" eth_folders = [f for f in os.listdir(eth_dir) if os.path.isdir(os.path.join(eth_dir, f)) and f.startswith("eth")] for eth_folder in eth_folders: eth = eth_folder.split("/")[-1] setup_xps(eth) if __name__ == '__main__': process_devs()
按
Esc
键,输入:wq
保存并退出文件。
运行以下命令,配置XPS。
sudo python3 xps_config.py
(可选)运行以下命令,检查XPS是否配置完成。
以目标ECS实例32个CPU、8个发送队列的网卡eth0为例:
cat /sys/class/net/eth0/queues/tx-*/xps_cpus
如下图所示(CPU数目不同或者队列数目不同,显示结果不同),说明XPS已经配置成功。
影响说明
尽管配置XPS的目的是为了提升网络性能,但可能会出现配置XPS后网络性能受到影响。如果您遇到这种情况,可以运行以下命令来清除XPS配置。以网卡eth0为例:
sudo sh -c 'for txq in /sys/class/net/eth0/queues/tx-*; do echo 0 > $txq/xps_cpus; done'