操作系统优化
若要在具有增强联网的实例上实现最高网络性能,您可能需要修改默认操作系统配置。我们建议对于需要高网络性能的应用程序进行以下配置更改。
除了这些操作系统优化之外,您还应考虑网络流量的最大传输单位 (MTU),并根据您的工作负载和网络架构相应调整。有关更多信息,请参阅 EC2 实例的网络最大传输单位 (MTU)。
AWS 定期测量在集群置放群组中启动的实例之间的平均往返延迟,在 99.9% 的情况下该值为 50us,尾延迟为 200us。如果您的应用程序需要稳定的低延迟,建议在基于 Nitro 系统的固定性能实例上,使用最新版本的 ENA 驱动程序。
这些过程针对 Amazon Linux 2 和 Amazon Linux AMI 编写。不过,它们也适用于搭载内核版本 3.9 及更高版本的其他 Linux 发行版。有关更多信息,请参阅系统特定的文档。
针对增强联网优化 Amazon Linux 实例
-
检查实例的时钟源:
cat /sys/devices/system/clocksource/clocksource0/current_clocksource
-
如果时钟源为
xen
,请完成以下子步骤。否则,请跳至步骤 3。-
编辑 GRUB 配置并将
xen_nopvspin=1
和clocksource=tsc
添加到内核引导选项。-
对于 Amazon Linux 2,编辑
/etc/default/grub
文件并将这些选项添加到GRUB_CMDLINE_LINUX_DEFAULT
行,如下所示:GRUB_CMDLINE_LINUX_DEFAULT="console=tty0 console=ttyS0,115200n8 net.ifnames=0 biosdevname=0 nvme_core.io_timeout=4294967295
xen_nopvspin=1 clocksource=tsc
" GRUB_TIMEOUT=0 -
对于 Amazon Linux AMI,编辑
/boot/grub/grub.conf
文件并将这些选项添加到kernel
行,如下所示:kernel /boot/vmlinuz-4.14.62-65.117.amzn1.x86_64 root=LABEL=/ console=tty1 console=ttyS0 selinux=0 nvme_core.io_timeout=4294967295
xen_nopvspin=1 clocksource=tsc
-
-
(仅限 Amazon Linux 2)重新生成 GRUB 配置文件以应用这些更改:
sudo grub2-mkconfig -o /boot/grub2/grub.cfg
-
-
如果 您的 EC2 实例的处理器状态控制上将您的实例类型列出为支持的实例类型,请防止系统使用深层 C 状态,以确保低延迟的系统性能。有关更多信息,请参阅通过限制深层 C 状态实现高性能和低延迟。
-
编辑 GRUB 配置并将
intel_idle.max_cstate=1
添加到内核引导选项。-
对于 Amazon Linux 2,编辑
/etc/default/grub
文件并将此选项添加到GRUB_CMDLINE_LINUX_DEFAULT
行,如下所示:GRUB_CMDLINE_LINUX_DEFAULT="console=tty0 console=ttyS0,115200n8 net.ifnames=0 biosdevname=0 nvme_core.io_timeout=4294967295 xen_nopvspin=1 clocksource=tsc
intel_idle.max_cstate=1
" GRUB_TIMEOUT=0 -
对于 Amazon Linux AMI,编辑
/boot/grub/grub.conf
文件并将此选项添加到kernel
行,如下所示:kernel /boot/vmlinuz-4.14.62-65.117.amzn1.x86_64 root=LABEL=/ console=tty1 console=ttyS0 selinux=0 nvme_core.io_timeout=4294967295 xen_nopvspin=1 clocksource=tsc
intel_idle.max_cstate=1
-
-
(仅限 Amazon Linux 2)重新生成 GRUB 配置文件以应用这些更改:
sudo grub2-mkconfig -o /boot/grub2/grub.cfg
-
-
确保您预留的内核内存充足,可以保持高速率的数据包缓冲区分配(默认值可能会太小)。
-
使用您选择的编辑器(以
root
身份或者使用 sudo)打开/etc/sysctl.conf
文件。 -
将具有适合您实例类型的预留内核内存值(以 KB 为单位)的
vm.min_free_kbytes
行添加到文件。根据经验,您应将此值设置为可用系统内存的 1-3% 之间,并上调或下调此值以满足应用程序需求。vm.min_free_kbytes =
1048576
-
使用下面的命令应用此配置:
sudo sysctl -p
-
通过以下命令验证设置已应用:
sudo sysctl -a 2>&1 | grep min_free_kbytes
-
-
重启实例以加载新配置:
sudo reboot
-
(可选)手动分发数据包接收中断,使其与属于相同 NUMA 节点的不同 CPU 关联。但是,请谨慎使用此项,因为全局禁用了 irqbalancer。
注意 此步骤中的配置更改在重启之后不保留。
-
创建一个名为
smp_affinity.sh
的文件,并将以下代码块粘贴到该文件中:#/bin/sh service irqbalance stop affinity_values=(00000001 00000002 00000004 00000008 00000010 00000020 00000040 00000080) irqs=($(grep eth /proc/interrupts|awk '{print $1}'|cut -d : -f 1)) irqLen=${#irqs[@]} for (( i=0; i<${irqLen}; i++ )); do echo $(printf "0000,00000000,00000000,00000000,${affinity_values[$i]}") > /proc/irq/${irqs[$i]}/smp_affinity; echo "IRQ ${irqs[$i]} =" $(cat /proc/irq/${irqs[$i]}/smp_affinity); done
-
使用以下命令运行脚本:
sudo bash ./smp_affinity.sh
-
-
(可选)如果处理接收 IRQ 的 vCPU 过载,或者您的应用程序网络处理需要较高的 CPU 能力,您可以通过接收数据包转向 (RPS),将部分网络处理分载到其他核心。确保用于 RPS 的核心属于同一个 NUMA 节点,以避免 NUMA 节点间锁定。例如,要将核心 8-15 用于数据包处理,请使用以下命令。
注意 此步骤中的配置更改在重启之后不保留。
for i in `seq 0 7`; do echo $(printf "0000,00000000,00000000,00000000,0000ff00") | sudo tee /sys/class/net/eth0/queues/rx-$i/rps_cpus; done
-
(可选)如果可能,请在相同 NUMA 节点上执行所有处理。
-
安装 numactl:
sudo yum install -y numactl
-
当您运行网络处理程序时,请将其绑定到单个 NUMA 节点。例如,以下命令将 shell 脚本
run.sh
绑定到 NUMA 节点 0:numactl --cpunodebind=0 --membind=0 run.sh
-
如果您启用了超线程,则可以配置应用程序在每个 CPU 核心中仅使用单个硬件线程。
-
使用 lscpu 命令可以查看映射到 NUMA 节点的 CPU 核心:
lscpu | grep NUMA
输出:
NUMA node(s): 2 NUMA node0 CPU(s): 0-15,32-47 NUMA node1 CPU(s): 16-31,48-63
-
您可以使用以下命令,查看哪些硬件线程属于某个物理 CPU:
cat /sys/devices/system/cpu/cpu
0
/topology/thread_siblings_list输出:
0,32
在此示例中,线程 0 和 32 映射到 CPU 0。
-
若要避免在线程 32-47(实际上是与线程 0-15 在同一个 CPU 上的硬件线程)上运行,请使用以下命令:
numactl --physcpubind=+0-15 --membind=0 ./run.sh
-
-
-
为不同流量类使用多个弹性网络接口。例如,如果您运行使用后端数据库的 Web 服务器,请为 Web 服务器前端使用一个弹性网络接口,为数据库连接使用另一个弹性网络接口。