如何处理Page Cache难以回收产生的load飙高问题

本文探讨了系统load飙升的三大原因:内存回收问题、脏页积累以及NUMA配置不当。通过监控pgscank/s和pgscand/s,调整vm.min_free_kbytes和脏页限制,以及合理配置zone_reclaim_mode来解决这些问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

引发系统load飙高原因有以下几点:

  • 直接内存回收引起的 load 飙高;
  • 系统中脏页积压过多引起的 load 飙高;
  • 系统 NUMA 策略配置不当引起的 load 飙高。

1、直接内存回收:

观察:sar -B中pgscank/s、pgscand/s表示扫描的页面数量,前者表示kswapd扫描结果,后者表示直接扫描。需要让直接扫描越小越好。
解决:设置vm.min_free_kbytes,尽早开始后台回收。

2、脏页积压:

观察:sar -r中kbdirty即是脏页大小。
解决:设置vm/dirtyxxx控制脏页个数在合理范围内。

3、NUMA设置不合理:

观察:numactl --hardware查看是否还有一半内存空闲,但是还是频频发生direct reclaim。
解决:vm.zone_reclaim_mode = 0

# echo 0 > /proc/sys/vm/zone_reclaim_mode
# # 意味着关闭zone_reclaim模式,可以从其他zone或NUMA节点回收内存
# echo 1 > /proc/sys/vm/zone_reclaim_mode
# # 表示打开zone_reclaim模式,这样内存回收只会发生在本地节点内
# echo 2 > /proc/sys/vm/zone_reclaim_mode
# # 在本地回收内存时,可以将cache中的脏数据写回硬盘,以回收内存。
# echo 4 > /proc/sys/vm/zone_reclaim_mode
# # 可以用swap方式回收内存。
KSwap是Linux内核中用于动态内存管理的一部分,主要用于解决虚拟地址空间和物理内存之间映射的问题。它通过将不再活跃的部分进程的内存页交换到磁盘上,腾出物理内存供其他需要的进程使用。下面是一个简化的伪代码描述了KSwap的基本流程: ```c // 定义KSwap数据结构 struct kswapd_entry { struct list_head list; // 存储在列表中 unsigned long address; // 内存页地址 pgoff_t index; // 磁盘索引位置 }; // KSwap初始化函数 void init_kswapd(void) { init_list_head(&kswap_list); // 初始化KSwap列表 } // 内存不足时的KSwap操作 void handle_memory_pressure(struct mm_struct *mm) { struct page *page = find_freed_page(mm); if (page) { // 如果找到空闲页面 kswap_to_disk(page, /* 一系列参数如缓存、磁盘I/O队列等 */); add_to_kswapd_list(page); // 将页添加到KSwap列表 } } // 将页面交换到磁盘的函数 void kswap_to_disk(struct page *page, ...) { write_to_disk(page_address(page), page->index); // 实现磁盘I/O update_swap_state(page); // 更新内存状态 } // 将页面添加到KSwap列表的函数 void add_to_kswapd_list(struct page *page) { list_add(&page->ks_list, &kswap_list); wake_up_page_cache_lists(); // 触发页面缓存唤醒机制 } // 主动扫描并从磁盘加载回内存 void scan_and_load_from_disk(void) { struct kswapd_entry *entry; while ((entry = list_first_entry(&kswap_list, struct kswapd_entry, list))) { load_from_disk(entry->address, entry->index); // 从磁盘读取数据并更新内存 remove_from_kswapd_list(entry); // 从列表移除 } } // 移除函数,用于清理列表 void remove_from_kswapd_list(struct kswapd_entry *entry) { list_del_init(&entry->list); } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值