linux 出错 “INFO: task xxxxxx: 634 blocked for more than 120 seconds.”的3种解决方案(转)

linux 出错 “INFO: task xxxxxx: 634 blocked for more than 120 seconds.”的3种解决方案

1 问题描述

服务器内存满了,ssh登陆失败 ,查看日志有如下报错。 html

 

仔细阅读打印信息发现关键信息是“hung_task_timeout_secs”,第一次遇到这样的问题,首先百度… linux

经过翻看多个网友的博客,发现这是linux kernel的一个bug。你们对这个问题的解释也都比较一致,摘抄一段:shell

By default Linux uses up to 40% of the available memory for file system caching.
After this mark has been reached the file system flushes all outstanding data to disk causing all following IOs going synchronous.
For flushing out this data to disk this there is a time limit of 120 seconds by default.
In the case here the IO subsystem is not fast enough to flush the data withing 120 seconds.
This especially happens on systems with a lot of memory.
The problem is solved in later kernels。
缓存

翻译过来就是:通常状况下,linux会把可用内存的40%的空间做为文件系统的缓存。当缓存快满时,文件系统将缓存中的数据总体同步到磁盘中。可是系统对同步时间有最大120秒的限制。若是文件系统不能在时间限制以内完成数据同步,则会发生上述的错误。这一般发生在内存很大的系统上。系统内存大,则缓冲区大,同步数据所须要的时间就越长,超时的几率就越大。ruby

2 解决办法

网友们提供的解决方案大体有3种,分别对3种方案的效果进行验证测试。bash

2.1 缩小文件系统缓存大小服务器

此种方案是下降缓存占内存的比例,好比由40%降到10%,这样的话须要同步到磁盘上的数据量会变小,IO写时间缩短,会相对比较平稳。markdown

文件系统缓存的大小是由内核参数vm.dirty_ratiovm.dirty_backgroud_ratio控制决定的。app

vm.dirty_background_ratio指定当文件系统缓存脏页数量达到系统内存百分之多少时(如5%)就会触发pdflush/flush/kdmflush等后台回写进程运行,将必定缓存的脏页异步地刷入外存。ssh

vm.dirty_ratio则指定了当文件系统缓存脏页数量达到系统内存百分之多少时(如10%),系统不得不开始处理缓存脏页(由于此时脏页数量已经比较多,为了不数据丢失须要将必定脏页刷入外存),在此过程当中不少应用进程可能会由于系统转而处理文件IO而阻塞。

一般状况下,vm.dirty_ratio的值要大于vm.dirty_background_ratio的值。

下面说一下修改这两个参数的流程及效果。

(1)首先查看系统当前的vm.dirty_ratio 和 vm.dirty_ background_ratio的值。

在shell命令行中输入以下指令:

sysctl -a | grep dirty
  • 1

这里写图片描述
由上图可知,当前环境下,vm.dirty_ratio=20 ,vm.dirty_ background_ratio=10。在此状况下,会出现上述问题。

(2)修改vm.dirty_ratio和vm.dirty_ background_ratio的值。
把vm.dirty_ratio修改成10 ,vm.dirty_background_ratio修改成5。在命令行输入以下命令:

./sbin/sysctl -w vm.dirty_ratio=10 ./sbin/sysctl -w vm.dirty_background_ratio=5
  • 1
  • 2

这里写图片描述
(3)查看修改是否成功。

在命令行输入(1)中的指令便可。
这里写图片描述
由上图可知,参数修改为功。

(4)使参数修改当即生效。

在命令行输入以下指令便可。

sysctl  -p
  • 1

(5)观察测试结果。

通过以上操做,缩减文件系统缓存以后,上述问题成功解决。

2.2 修改系统IO调度策略

Linux的IO共有三种调度器:CFQnoopdeadline。每一个调度器都有其优势。

CFQ (Completely Fair Scheduler(彻底公平调度器))(cfq):它是许多Linux 发行版的默认调度器;它将由进程提交的同步请求放到多个进程队列中,而后为每一个队列分配时间片以访问磁盘。

Noop调度器(noop):基于先入先出(FIFO)队列概念的Linux内核里最简单的I/O调度器。此调度程序最适合于SSD。

截止时间调度器(deadline):尝试保证请求的开始服务时间。

Linux发行版的默认采用的是cfq调度器。此方案就是把cfq调度器修改成最简单的noop调度器

下面说一下修改调度器的流程。

(1)查看当前采用的调度器。

在命令行中输入以下指令:

cat /sys/block/sda/queue/scheduler
  • 1

这里写图片描述
由内核返回信息可知,当前采用的是cfq调度器。

(2)修改调度器。

在命令行中输入以下指令:

echo noop >/sys/block/sda/queue/scheduler
  • 1

这里写图片描述
(3)查看修改是否成功。

在命令行中输入如(1)的指令。
这里写图片描述
由内核返回信息可知,调度器修改为功。

调度器的修改是当即生效的,没必要重启内核。

(4)观察测试结果。

修改完成后,让系统继续运行一段时间。上述问题依然存在。因此此方案对本文的案例不起做用。对于其余案例是否起做用须要本身按照上述方式测试才能得知。

2.3 取消120秒时间限制

此方案就是不让系统有那个120秒的时间限制。文件系统把数据从缓存转到外存慢点就慢点,应用程序对此延时不敏感。就是慢点就慢点,我等着。实际上操做系统是将这个变量设为长整形的最大值。

下面说一下内核hung task检测机制由来。咱们知道进程等待IO时,常常处于D状态,即TASK_UNINTERRUPTIBLE状态,处于这种状态的进程不处理信号,因此kill不掉,若是进程长期处于D状态,那么确定不正常,缘由可能有二:

1)IO路径上的硬件出问题了,好比硬盘坏了(只有少数状况会致使长期D,一般会返回错误);

2)内核本身出问题了。

这种问题很差定位,并且一旦出现就一般不可恢复,kill不掉,一般只能重启恢复了。
内核针对此种状况开发了一种hung task的检测机制,基本原理是:定时检测系统中处于D状态的进程,若是其处于D状态的时间超过了指定时间(默认120s,能够配置),则打印相关堆栈信息,也能够经过proc参数配置使其直接panic。

如何修改或者取消120秒的时间限值呢。120秒的时间限值由内存参数kernel.hung_task_timeout_secs决定的。直接像方案一那样修改此内核参数的值就可。若是kernel.hung_task_timeout_secs的值设置为0,那就是把此种设置为长整型的最大值。

下面说一下修改调度器的流程。

(1)查看当前hung_task_timeout_secs值。

在命令行中输入以下指令:

sysctl -a | grep hung_task_timeout_secs
  • 1

这里写图片描述

有内核返回信息,可知当前设置的hung_task超时时间为120秒。

(2)修改hung_task_timeout_secs值。

把hung_task_timeout_secs的值修改成0,在命令行中输入以下指令:

 ./sbin/sysctl -w kernel.hung_task_timeout_secs=0
  • 1
  • 2

这里写图片描述

(3)查看修改是否成功。

在命令行输入(1)中的指令便可。
这里写图片描述

(4)使参数修改当即生效。

在命令行输入以下指令便可。

sysctl  -p
  • 1

(5)观察测试结果。
通过以上操做,取消120秒时间限值以后,上述问题成功解决。

2.4 总结
通过上边的测试,可知对与本案例缩减文件系统缓冲大小和取消120秒时间限值都可以解决问题。可是取消120秒的时间限值会容许系统不可切换任务的出现。综合考虑决定采用方案1,即缩减文件系统的缓冲区大小。

3 永久修改内核参数

在上述方案中采用sysctl能够修改内核参数,可是这只是临时修改,上电重启后又会恢复回以前的参数。那么如何才可以永久修改内核参数呢?

能够修改系统信息配置文件sysctl.conf,此配置文件在/etc目录下。打开配置文件在最后添加以下两行代码:

vm.dirty_background_ratio=5 vm.dirty_ratio=10
  • 1
  • 2

这里写图片描述
保存后重启系统,查看配置是否成功。

若是系统没有sysctl.conf文件,就像个人最小linux系统同样,则能够本身建立sysctl.conf。

在/etc目录下,采用vi指令:vi sysctl.conf新建sysctl.conf文件,而后输入以下代码后保存退出。

重启以后查看vm.dirty_ratio和vm.dirty_background_ratio的值,发现又恢复成以前的了。

这是由于开机启动时系统没有读取sysctl.conf文件进行配置。能够经过修改启动文件来解决。

以我使用的linux系统为例,启动文件是/etc/init.d/rcS。采用指令vi /etc/init.d/rcS打开rcS文件,在最末尾添加以下代码:./sbin/sysctl -p
这里写图片描述

保存后退出。reboot重启能够看到内核打印信息中有以下信息:
这里写图片描述
进入控制台后,查看vm.dirty_ratio和vm.dirty_background_ratio的值,可知内核参数永久修改为功。

【参考】
一、Linux Kernel Crash–hung_task_timeout_secs 做者:李子无为
http://blog.csdn.net/napolunyishi/article/details/17576739
二、How to fix hung_task_timeout_secs and blocked for more than 120 seconds problem 做者:skate
http://blog.csdn.net/wyzxg/article/details/44236263
三、关于修改 sysctl.conf,如何使该文件在系统重启以后生效 做者:dagebudagegeda
http://blog.csdn.net/u010616985/article/details/44563931
四、文件系统缓存dirty_ratio与dirty_background_ratio两个参数区别 做者:vincent
http://blog.sina.com.cn/s/blog_448574810101k1va.html
五、一次内核hung task分析 做者:humjb_1983
http://blog.chinaunix.net/uid-14528823-id-4406510.html

6,博主原创文章转载地址:
http://blog.csdn.net/electrocrazy
https://blog.csdn.net/electrocrazy/article/details/79377214
相关文章
相关标签/搜索