You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Linux系统缓存占满引发ConnectX-5 100G网卡丢包的DPDK 19应用优化方案问询

问题根源与解决方案

嘿,我仔细看了你的部署架构和问题现象,核心问题其实是磁盘页缓存占满后,写线程处理速度跟不上收包进程的生产节奏,进而触发了连锁反应:当磁盘缓存饱和时,WriteToDisk会变慢甚至阻塞,无锁队列很快被塞满;收包进程没法把满的local_buf推出去,就没法创建新的缓冲区接收后续数据包,导致mbuf一直被占用没法释放;最后DPDK的mbuf内存池耗尽,rte_eth_rx_burst拿不到空闲缓冲区,网卡RX队列直接溢出丢包。虽然系统显示还有available内存,但页缓存占满后内核的内存回收操作也会偷偷占用资源,间接影响收包效率。

下面是我结合DPDK和Linux存储优化的实践经验,整理的具体解决办法:

1. 从根源切断页缓存累积:用直接I/O或限制缓存大小

既然页缓存满是触发点,先从磁盘写入逻辑下手:

  • 开启直接I/O绕过页缓存:在WriteToDisk打开文件时加上O_DIRECT标志,让数据直接写入磁盘,完全绕开Linux的页缓存。这样就不会出现缓存越攒越多的情况了。不过要注意,直接I/O要求缓冲区地址和写入大小必须对齐到磁盘扇区(一般是512字节或4KB),所以你得把local_buf的分配改成posix_memalign这种支持对齐的方式,别用普通的new了。
    // 示例:打开文件时启用直接I/O
    int fd = open("output_file", O_WRONLY | O_CREAT | O_DIRECT, 0644);
    
  • 调小脏页阈值让内核更早写盘:通过vm.dirty_ratiovm.dirty_background_ratio两个内核参数,限制脏页的最大占比。比如把脏页背景阈值设为总内存的4%,当脏页到这个比例时,内核会自动启动线程异步写盘;把强制同步阈值设为8%,超过后就会强制进程同步写盘,避免脏页无限制累积。
    # 临时生效
    sysctl -w vm.dirty_ratio=8
    sysctl -w vm.dirty_background_ratio=4
    # 永久生效的话,把这两行加到/etc/sysctl.conf里,然后执行sysctl -p
    

2. 给收包进程加“安全网”:处理队列满的情况

你的伪代码里没考虑队列满的情况,这是个大隐患。得给收包流程加降级逻辑:

  • 队列满时直接写磁盘:当PushToQueue失败(队列满),别死等,直接把当前的local_buf写入磁盘,然后释放缓冲区继续收包,优先保证mbuf能及时释放,别让内存池耗尽。
  • 调整缓冲区大小:6MB的块可能太大了,写磁盘的粒度太粗,容易导致队列积压。可以试试把块大小调小到1MB或2MB,让写线程更频繁地处理数据,减少队列堵死的概率。
  • 确保mbuf必释放:不管队列能不能push,一定要保证rte_pktmbuf_free(mbuf)被执行,哪怕当前的数据包没来得及处理(如果业务允许的话),先把mbuf还给内存池再说。

3. 给DPDK内存池留足余量

如果mbuf内存池太小,稍微一点队列积压就会耗尽。你可以调大内存池的mbuf数量,比如从默认的2048改成4096甚至8192,给收包流程留足够的缓冲空间。另外,创建内存池时记得加上RTE_MBUF_F_CACHE_ALIGN标志,让mbuf对齐缓存线,提升收包处理的效率。

4. 隔离CPU资源,别让写线程抢收包的资源

你的收包进程绑定了isolcpus的CPU,但写线程如果也跑在这些CPU上,磁盘I/O的开销会干扰收包。把写线程绑定到非隔离的CPU上,比如用taskset命令指定CPU核心,确保收包的CPU完全专注于数据包处理,不受磁盘I/O的影响。

# 比如把写线程绑定到32号CPU(假设这个CPU不在isolcpus列表里)
taskset -c 32 your_writer_process

5. 加监控,提前预警

最后,建议加一些监控:

  • 监控DPDK内存池的空闲mbuf数量,用rte_mempool_stats_get获取数据,当空闲数低于阈值时触发告警,提前处理。
  • 监控无锁队列的长度,当队列超过一定长度时,可以动态调整收包的批量大小(比如把rte_eth_rx_burst的第三个参数从216调小一点),暂时降低收包速率,避免队列堵死。
  • iostatvmstat这些工具看磁盘I/O和内存脏页的状态,确认写盘速度能不能跟上收包的速度。

内容的提问来源于stack exchange,提问作者yaron

火山引擎 最新活动