目录
现象回顾
问题剖析
现场分析
解决方案
总结与反思
1.调整中断亲和性(IRQ Affinity):
2.RPS(Receive Packet Steering)和 RFS(Receive Flow Steering):
近期,我们的一位客户在生产环境中遭遇了广告业务访问超时的问题,尤其是在晚间高峰时段,这严重影响了业务运行。尽管客户经过一整天的努力,仍未能定位问题的根本原因,因此向我们寻求协助。通过我们的共同努力和深入分析,我们最终锁定了性能瓶颈——网卡软中断。现在,让我们一同回顾这次解决性能挑战的全过程。
现象回顾
在晚高峰期间,广告业务相关接口大量超时,服务日志中频繁出现访问Codis超时的错误记录。服务访问Codis的超时时间设定为200毫秒,但在问题时段,这一时间限制被频频突破。
问题剖析
通过监控数据,发现出问题时Codis的QPS(每秒请求数)明显降低,而连接数却显著上升。连接数增加可能有两方面原因:一是访问Codis的时延增大,导致业务连接池中的连接不够用,需要新建连接;二是业务流量突增,导致访问Codis的量变大,连接数不足,同样需要新建连接。然而,从QPS的监控数据来看,并没有出现QPS增长的趋势,因此可以排除业务流量突增的原因。
进一步分析发现,问题主要集中在IP为192.168.16.77的服务器上。这台服务器上的Codis-server(Redis)响应时间明显增加,达到了十几到二十毫秒,并且该服务器的内存使用也有明显上升。猜测此次事故可能与该服务器或网络层面有关。
然而,在检查服务器和网络层面的监控后,并未发现明显异常。同时,查看了该服务器上的Codis日志和系统日志,也均未发现异常记录。由于Codis的slowlog已被冲掉,无法确定问题发生时是否存在慢查询。此外,虽然业务服务日志中记录的超时Key都不是大Key,但仍然不能排除大Key对性能的影响
现场分析
在第二天晚高峰时段,问题再次出现。我们立即登录到服务器上执行top命令,发现软中断分布极不均衡,个别CPU上的软中断占用率已高达80%以上。这导致与Codis发生CPU争抢,使得Codis CPU使用率打满,响应时间大幅增加。
解决方案
迅速执行了均衡网卡软中断的脚本,将软中断均匀分布到各个CPU上,执行后,业务响应时间迅速恢复正常。
总结与反思
1.正常情况下,客户Redis和Codis服务器都会执行均衡网卡软中断的脚本。但在此次事件中,客户生产环境遗漏了对该服务器的操作。同时,由于之前业务量较小,即使存在软中断问题,也未达到性能瓶颈。因此,这个问题在之前并未暴露出来。
2.为了避免类似问题的再次发生,客户在监控系统中增加了软中断相关指标,并设置了阈值告警通知。
3.总结影响Redis性能的关键因素,为后续性能问题分析提供思路:
4.网卡软中断:
软中断是Linux内核处理网络数据包的重要机制。与硬中断相比,其优先级较低,主要用于处理耗时的网络数据包接收和发送任务。在网络硬件接收到数据包后,会先通过硬件中断将数据放入队列,随后由软中断进行处理。
在Redis服务器上,若遇到高网络负载,某个CPU的软中断占用率过高可能会影响系统整体性能。因此,均衡网卡软中断的负载对系统性能至关重要。软中断允许Linux内核在非抢占式环境中处理异步事件,如网络数据包的收发。当网卡接收到数据包,它会通过软中断信号通知CPU进行处理,包括数据复制、网络统计信息更新等操作。若网络流量大或处理效率不高,软中断可能会大量占用CPU资源,导致使用率显著上升。
因此,合理地均衡网卡软中断的负载是非常重要的,以下是两种常用均衡网卡软中断的方法,客户这里是采用了irqbalance
服务自动调整中断亲和性,并使用第二种方式进行软中断均衡优化:
1.调整中断亲和性(IRQ Affinity):
可以通过调整中断亲和性,将中断处理分配到多个CPU上。可以使用irqbalance服务自动调整中断亲和性,或者手动设置/proc/irq/<irq号 /smp_affinity文件来指定中断处理的CPU。
/proc/interrupts文件在Linux系统中提供了有关中断(IRQ)的详细信息。这个文件的内容通常包括以下信息:
-
中断编号:每一行的开头是中断的编号(或名称),例如 0, 1, 2,或 LOC(本地中断),NMI(非屏蔽中断)等。
-
CPU列:接下来的几列显示每个CPU核处理该中断的次数。每个列对应一个CPU核,显示该核处理该中断的计数。这些计数器可以帮助你了解中断在不同CPU核之间的分布情况。
-
中断类型:有时会有一个标识符来表示中断类型,比如 IR-IO-APIC 或 PCI-MSI,这表示中断的来源或类型。
-
中断名称或设备:最后一列通常显示与中断相关的设备或驱动程序名称。这可以帮助你识别哪个设备或驱动程序正在使用该中断。
例如,以下是一个典型的 /proc/interrupts 文件的输出示例:
CPU0 CPU1 CPU2 CPU3
0: 66 0 0 0 IO-APIC-edge timer
1: 2 0 0 0 IO-APIC-edge i8042
8: 1 0 0 0 IO-APIC-edge rtc0
9: 0 0 0 0 IO-APIC-fasteoi acpi
16: 123 0 0 0 IO-APIC-fasteoi ehci_hcd:usb1
23: 4567 0 0 0 IO-APIC-fasteoi eth0
此codis服务器16.77信息如下,网卡对应的中断号为86,87,88,89;采用irqbalance
服务自动调整亲和性,分别使用CPU8,CPU10,CPU12,CPU14。
2.RPS(Receive Packet Steering)和 RFS(Receive Flow Steering):
RPS和RFS是Linux内核提供的机制,用于将网络数据包的处理分配到多个CPU上。可以在/proc/sys/net/core/rps_sock_flow_entries
和/sys/class/net//queues/rx-/rps_cpus以及/sys/class/net//queues/rx-/rps_flow_cnt
中进行配置。
比如40核服务器设置如下:
echo ff,ffffffff > /sys/class/net/<interface>/queues/rx-<n>/rps_cpus
echo 4096 > /sys/class/net/<interface>/queues/rx-<n>/rps_flow_cnt
echo 131072 > /proc/sys/net/core/rps_sock_flow_entries
其中:
rps_cpus是一个位掩码,表示允许使用的CPU核,ff,ffffffff则表示40核全部允许使用
rps_flow_cnt表示当前网络设备rps队列的流表数,需要设置为2的整数次幂,建议设置为4096,数值越大,同时所能处理的rps流越多。
131072为4096*接收队列的数量
****************************************************************************************************
点开看看就知道了:DBdoctor-数据库性能诊断