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
相關文章
相關標籤/搜索