性能调优
操作系统
处理器——动态节能技术
cpufreq 是一个动态调整 CPU 频率的模块,可支持五种模式。为保证服务性能应选用 performance 模式,将 CPU 频率固定工作在其支持的最高运行频率上,不进行动态调节,操作命令为 cpupower frequency-set --governor performance
。
处理器——中断亲和性
- 自动平衡:可通过
irqbalance
服务实现。 - 手动平衡:
- 确定需要平衡中断的设备,从 CentOS 7.5 开始,系统会自动为某些设备及其驱动程序配置最佳的中断关联性。不能再手动配置其亲和性。目前已知的有使用
be2iscsi
驱动的设备,以及 NVMe 设置; - 对于其他设备,可查询其芯片手册,是否支持分发中断,若不支持,则该设备的所有中断会路由到同一个 CPU 上,无法对其进行修改。若支持,则计算
smp_affinity
掩码并设置对应的配置文件。
- 确定需要平衡中断的设备,从 CentOS 7.5 开始,系统会自动为某些设备及其驱动程序配置最佳的中断关联性。不能再手动配置其亲和性。目前已知的有使用
NUMA 绑核
为尽可能的避免跨 NUMA 访问内存,可以通过设置线程的 CPU 亲和性来实现 NUMA 绑核。对于普通程序,可使用 numactl
命令来绑定。
内存——透明大页
对于数据库应用,不推荐使用 THP,因为数据库往往具有稀疏而不是连续的内存访问模式,且当高阶内存碎片化比较严重时,分配 THP 页面会出现较大的延迟。若开启针对 THP 的直接内存规整功能,也会出现系统 CPU 使用率激增的现象,因此建议关闭 THP。
echo never > /sys/kernel/mm/transparent_hugepage/enabledecho never > /sys/kernel/mm/transparent_hugepage/defrag
内存——虚拟内存参数
dirty_ratio
百分比值。当脏的 page cache 总量达到系统内存总量的这一百分比后,系统将开始使用 pdflush 操作将脏的 page cache 写入磁盘。默认值为 20%,通常不需调整。对于高性能 SSD,比如 NVMe 设备来说,降低其值有利于提高内存回收时的效率。dirty_background_ratio
百分比值。当脏的 page cache 总量达到系统内存总量的这一百分比后,系统开始在后台将脏的 page cache 写入磁盘。默认值为 10%,通常不需调整。对于高性能 SSD,比如 NVMe 设备来说,设置较低的值有利于提高内存回收时的效率。
存储及文件系统
内核 I/O 栈链路较长,包含了文件系统层、块设备层和驱动层。
I/O 调度器:
I/O 调度程序确定 I/O 操作何时在存储设备上运行以及持续多长时间。也称为 I/O 升降机。对于 SSD 设备,宜设置为 noop。
echo noop > /sys/block/${SSD_DEV_NAME}/queue/scheduler
格式化参数——块大小:
块是文件系统的工作单元。块大小决定了单个块中可以存储多少数据,因此决定了一次写入或读取的最小数据量。
默认块大小适用于大多数使用情况。但是,如果块大小(或多个块的大小)与通常一次读取或写入的数据量相同或稍大,则文件系统将性能更好,数据存储效率更高。小文件仍将使用整个块。文件可以分布在多个块中,但这会增加运行时开销。
使用 mkfs 命令格式化设备时,将块大小指定为文件系统选项的一部分。指定块大小的参数随文件系统的不同而不同。
网络配置
尽管网络堆栈在很大程度上是自我优化的。但是在网络数据包处理过程中,以下方面可能会成为瓶颈并降低性能:
- 网卡硬件缓存:正确观察硬件层面的丢包方法是使用
ethtool -S ${NIC_DEV_NAME}
命令观察 drops 字段。当出现丢包现象时,主要考虑是硬/软中断的处理速度跟不上网卡接收速度。若接收缓存小于最大限制时,也可尝试增加 RX 缓存来防止丢包。查询命令为:ethtool -g ${NIC_DEV_NAME}
,修改命令为ethtool -G ${NIC_DEV_NAME}
。 - 硬中断:若网卡支持 Receive-Side Scaling(RSS 也称为多网卡接收)功能,则观察
/proc/interrputs
网卡中断,如果出现了中断不均衡的情况,请参考操作系统性能参数调优-处理器调优。若不支持 RSS 或 RSS 数量远小于物理 CPU 核数,则可配置 Receive Packet Steering(RPS,可以看作 RSS 的软件实现),及 RPS 的扩展 Receive Flow Steering (RFS)。 - 软中断:观察
/proc/net/softnet\_stat
监控。如果除第三列的其他列的数值在增长,则应适度调大net.core.netdev\_budget
或net.core.dev\_weight
值,使 softirq 可以获得更多的 CPU 时间。除此之外,也需要检查 CPU 使用情况,确定哪些任务在频繁占用 CPU,能否优化。 - 应用的套接字接收队列:监控
ss -nmp
的Recv-q
列,若队列已满,则应考虑增大应用程序套接字的缓存大小或使用自动调整缓存的方式。除此之外,也要考虑能否优化应用层的架构,降低读取套接字的间隔。 - 以太网流控:若网卡和交换机支持流控功能,可通过使能此功能,给内核一些时间来处理网卡队列中的数据,来规避网卡缓存溢出的问题。对于网卡测,可通过
ethtool -a ${NIC_DEV_NAME}
命令检查是否支持/使能,并通过ethtool -A ${NIC_DEV_NAME}
命令开启。 - 中断合并:过于频繁的硬件中断会降低系统性能,而过晚的硬件中断会导致丢包。对于较新的网卡支持中断合并功能,并允许驱动自动调节硬件中断数。可通过
ethtool -c ${NIC_DEV_NAME}
命令检查,ethtool -C ${NIC_DEV_NAME}
命令开启。自适应模式使网卡可以自动调节中断合并。在自适应模式下,驱动程序将检查流量模式和内核接收模式,并实时评估合并设置,以防止数据包丢失。 - 适配器队列:在协议栈处理之前,内核利用此队列缓存网卡接收的数据,每个 CPU 都有各自的 backlog 队列。此队列可缓存的最大 packets 数量为
netdev\_max\_backlog
。观察/proc/net/softnet\_stat
第二列,当某行的第二列持续增加,则意味着 CPU [行-1] 队列已满,数据包被丢失,可通过持续加倍net.core.netdev\_max\_backlog
值来解决。 - 发送队列:发送队列长度值确定在发送之前可以排队的数据包数量。默认值是 1000,对于 10 Gbps 足够。但若从
ip -s link
的输出中观察到TX errors
值时,可尝试加倍该数据包数量:ip link set dev ${NIC_DEV_NAME} txqueuelen 2000
。