服务器卡死,报:task kworker/u256:0:5 blocked for more than 120 seconds
具体报错
问题分析
默认情况下, Linux会最多使用40%的可用内存作为文件系统缓存。当超过这个阈值后,文件系统会把将缓存中的内存全部写入磁盘, 导致后续的IO请求都是同步的。
将缓存写入磁盘时,有一个默认120秒的超时时间。 出现上面的问题的原因是IO不能在120秒将缓存中的数据全部写入磁盘。IO系统响应缓慢,导致越来越多的请求堆积,最终系统内存全部被占用,导致系统失去响应。
解决思路
调整文件系统缓存中脏数据占用内存的比例,调整参数,降低脏数据开始处理的百分比,提高脏数据最高容量。使得文件系统缓存不会那么快写入 硬盘,而系统有时间去处理脏数据。主要是如下两项参数:
vm.dirty_background_ratio
指定当文件系统缓存脏页数量达到系统内存百分之多少时(如5%)就会触发pdflush/flush/kdmflush等后台回写进程运行,将一定缓存的脏页异步地刷入外存。vm.dirty_ratio
则指定了当文件系统缓存脏页数量达到系统内存百分之多少时(如10%),系统不得不开始处理缓存脏页(因为此时脏页数量已经比较多,为了避免数据丢失需要将一定脏页刷入外存),在此过程中很多应用进程可能会因为系统转而处理文件IO而阻塞。
解决方案
-
缩小文件系统缓存大小
- 首先查看系统当前的vm.dirty_ratio 和 vm.dirty_ background_ratio的值
# 查看目前参数,我将触发值减少一倍,而容限调整到60% sysctl -a | grep dirty
- 临时修改内核
# 原来是10 sysctl -w vm.dirty_ratio=5 # 原来是20 sysctl -w vm.dirty_background_ratio=20
- 查看修改是否成功
sysctl -a | grep dirty
- 使参数修改立即生效
sysctl -p
- 永久修改内核
vim /etc/sysctl.conf
- 永久修改内核参数
# 原来是10 vm.dirty_background_ratio = 5 # 原来是20 vm.dirty_ratio = 60
-
修改系统IO调度策略
- 查看当前采用的调度器
cat /sys/block/sda/queue/scheduler
- 修改调度器
echo noop >/sys/block/sda/queue/scheduler
- 查看修改是否成功
cat /sys/block/sda/queue/scheduler [noop] deadline cfq
- 观察测试结果 修改完成后,让系统继续运行一段时间
-
取消120秒时间限制
此方案就是不让系统有那个120秒的时间限制。文件系统把数据从缓存转到外存慢点就慢点,应用程序对此延时不敏感。就是慢点就慢点,我等着。实际上操作系统是将这个变量设为长整形的最大值。
- 查看当前hung_task_timeout_secs值
sysctl -a | grep hung_task_timeout_secs
- 修改hung_task_timeout_secs值
./sbin/sysctl -w kernel.hung_task_timeout_secs=0
- 查看修改是否成功
sysctl -a | grep hung_task_timeout_secs
- 使参数修改立即生效
sysctl -p
本文是原创文章,采用 CC BY-NC-ND 4.0 协议,完整转载请注明来自 Nuri Alfred - Deertech
评论
匿名评论
隐私政策
你无需删除空行,直接评论以获取最佳展示效果