linux報錯INFO:task?xxxxxx:634?blocked?for?more?than?120?seconds.三種解決方式
1.問題描述
最近搭建的一個linux最小系統(tǒng)在運行到241秒時在控制臺自動打印如下圖信息,并且以后每隔120秒打印一次。
仔細閱讀打印信息發(fā)現(xiàn)關鍵信息是“hung_task_timeout_secs”,第一次遇到這樣的問題,首先百度…
通過翻看多個網(wǎng)友的博客,發(fā)現(xiàn)這是linux kernel的一個bug。大家對這個問題的解釋也都比較一致,摘抄一段:
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會把可用內(nèi)存的40%的空間作為文件系統(tǒng)的緩存。當緩存快滿時,文件系統(tǒng)將緩存中的數(shù)據(jù)整體同步到磁盤中。但是系統(tǒng)對同步時間有最大120秒的限制。如果文件系統(tǒng)不能在時間限制之內(nèi)完成數(shù)據(jù)同步,則會發(fā)生上述的錯誤。這通常發(fā)生在內(nèi)存很大的系統(tǒng)上。系統(tǒng)內(nèi)存大,則緩沖區(qū)大,同步數(shù)據(jù)所需要的時間就越長,超時的概率就越大。
2.解決辦法
網(wǎng)友們提供的解決方案大致有3種,分別對3種方案的效果進行驗證測試。
2.1 縮小文件系統(tǒng)緩存大小
此種方案是降低緩存占內(nèi)存的比例,比如由40%降到10%,這樣的話需要同步到磁盤上的數(shù)據(jù)量會變小,IO寫時間縮短,會相對比較平穩(wěn)。
文件系統(tǒng)緩存的大小是由內(nèi)核參數(shù)vm.dirty_ratio 和 vm.dirty_backgroud_ratio控制決定的。
- vm.dirty_background_ratio指定當文件系統(tǒng)緩存臟頁數(shù)量達到系統(tǒng)內(nèi)存百分之多少時(如5%)就會觸發(fā)pdflush/flush/kdmflush等后臺回寫進程運行,將一定緩存的臟頁異步地刷入外存。
- vm.dirty_ratio則指定了當文件系統(tǒng)緩存臟頁數(shù)量達到系統(tǒng)內(nèi)存百分之多少時(如10%),系統(tǒng)不得不開始處理緩存臟頁(因為此時臟頁數(shù)量已經(jīng)比較多,為了避免數(shù)據(jù)丟失需要將一定臟頁刷入外存),在此過程中很多應用進程可能會因為系統(tǒng)轉(zhuǎn)而處理文件IO而阻塞。
通常情況下,vm.dirty_ratio的值要大于vm.dirty_background_ratio的值。
下面說一下修改這兩個參數(shù)的流程及效果。
(1)首先查看系統(tǒng)當前的vm.dirty_ratio 和 vm.dirty_ background_ratio的值。
在shell命令行中輸入如下指令:
sysctl -a | grep dirty
由上圖可知,當前環(huán)境下,vm.dirty_ratio=20 ,vm.dirty_ background_ratio=10。在此情況下,會出現(xiàn)上述問題。
(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
(3)查看修改是否成功。
在命令行輸入(1)中的指令即可。
由上圖可知,參數(shù)修改成功。
(4)使參數(shù)修改立即生效。
在命令行輸入如下指令即可。
sysctl -p
(5)觀察測試結果。
經(jīng)過以上操作,縮減文件系統(tǒng)緩存之后,上述問題成功解決。
2.2 修改系統(tǒng)IO調(diào)度策略
Linux的IO共有三種調(diào)度器:CFQ、noop、deadline。每個調(diào)度器都有其優(yōu)點。
- CFQ (Completely Fair Scheduler(完全公平調(diào)度器))(cfq):它是許多Linux 發(fā)行版的默認調(diào)度器;它將由進程提交的同步請求放到多個進程隊列中,然后為每個隊列分配時間片以訪問磁盤。
- Noop調(diào)度器(noop):基于先入先出(FIFO)隊列概念的Linux內(nèi)核里最簡單的I/O調(diào)度器。此調(diào)度程序最適合于SSD。
- 截止時間調(diào)度器(deadline):嘗試保證請求的開始服務時間。
Linux發(fā)行版的默認采用的是cfq調(diào)度器。此方案就是把cfq調(diào)度器修改為最簡單的noop調(diào)度器。
下面說一下修改調(diào)度器的流程。
(1)查看當前采用的調(diào)度器。
在命令行中輸入如下指令:
cat /sys/block/sda/queue/scheduler
由內(nèi)核返回信息可知,當前采用的是cfq調(diào)度器。
(2)修改調(diào)度器。
在命令行中輸入如下指令:
echo noop >/sys/block/sda/queue/scheduler
(3)查看修改是否成功。
在命令行中輸入如(1)的指令。
由內(nèi)核返回信息可知,調(diào)度器修改成功。
調(diào)度器的修改是立即生效的,不必重啟內(nèi)核。
(4)觀察測試結果。
修改完成后,讓系統(tǒng)繼續(xù)運行一段時間。上述問題依然存在。所以此方案對本文的案例不起作用。對于其他案例是否起作用需要自己按照上述方式測試才能得知。
2.3 取消120秒時間限制
此方案就是不讓系統(tǒng)有那個120秒的時間限制。文件系統(tǒng)把數(shù)據(jù)從緩存轉(zhuǎn)到外存慢點就慢點,應用程序?qū)Υ搜訒r不敏感。就是慢點就慢點,我等著。實際上操作系統(tǒng)是將這個變量設為長整形的最大值。
下面說一下內(nèi)核hung task檢測機制由來。我們知道進程等待IO時,經(jīng)常處于D狀態(tài),即TASK_UNINTERRUPTIBLE狀態(tài),處于這種狀態(tài)的進程不處理信號,所以kill不掉,如果進程長期處于D狀態(tài),那么肯定不正常,原因可能有二:
1)IO路徑上的硬件出問題了,比如硬盤壞了(只有少數(shù)情況會導致長期D,通常會返回錯誤);
2)內(nèi)核自己出問題了。
這種問題不好定位,而且一旦出現(xiàn)就通常不可恢復,kill不掉,通常只能重啟恢復了。
內(nèi)核針對此種情況開發(fā)了一種hung task的檢測機制,基本原理是:定時檢測系統(tǒng)中處于D狀態(tài)的進程,如果其處于D狀態(tài)的時間超過了指定時間(默認120s,可以配置),則打印相關堆棧信息,也可以通過proc參數(shù)配置使其直接panic。
如何修改或者取消120秒的時間限值呢。120秒的時間限值由內(nèi)存參數(shù)kernel.hung_task_timeout_secs決定的。直接像方案一那樣修改此內(nèi)核參數(shù)的值就可。如果kernel.hung_task_timeout_secs的值設置為0,那就是把此種設置為長整型的最大值。
下面說一下修改調(diào)度器的流程。
(1)查看當前hung_task_timeout_secs值。
在命令行中輸入如下指令:
sysctl -a | grep hung_task_timeout_secs
有內(nèi)核返回信息,可知當前設置的hung_task超時時間為120秒。
(2)修改hung_task_timeout_secs值。
把hung_task_timeout_secs的值修改為0,在命令行中輸入如下指令:
./sbin/sysctl -w kernel.hung_task_timeout_secs=0
(3)查看修改是否成功。
在命令行輸入(1)中的指令即可。
(4)使參數(shù)修改立即生效。
在命令行輸入如下指令即可。
sysctl -p
(5)觀察測試結果。
經(jīng)過以上操作,取消120秒時間限值之后,上述問題成功解決。
心得:
經(jīng)過上邊的測試,可知對與本案例縮減文件系統(tǒng)緩沖大小和取消120秒時間限值均可以解決問題。但是取消120秒的時間限值會允許系統(tǒng)不可切換任務的出現(xiàn)。綜合考慮決定采用方案1,即縮減文件系統(tǒng)的緩沖區(qū)大小。
3.永久修改內(nèi)核參數(shù)
在上述方案中采用sysctl可以修改內(nèi)核參數(shù),但是這只是臨時修改,上電重啟后又會恢復回之前的參數(shù)。那么如何才能夠永久修改內(nèi)核參數(shù)呢?
可以修改系統(tǒng)信息配置文件sysctl.conf,此配置文件在/etc目錄下。打開配置文件在最后添加如下兩行代碼:
vm.dirty_background_ratio=5vm.dirty_ratio=10
保存后重啟系統(tǒng),查看配置是否成功。
如果系統(tǒng)沒有sysctl.conf文件,就像我的最小linux系統(tǒng)一樣,則可以自己創(chuàng)建sysctl.conf。
在/etc目錄下,采用vi指令:vi sysctl.conf新建sysctl.conf文件,然后輸入如下代碼后保存退出。
重啟之后查看vm.dirty_ratio和vm.dirty_background_ratio的值,發(fā)現(xiàn)又恢復成之前的了。
這是因為開機啟動時系統(tǒng)沒有讀取sysctl.conf文件進行配置。可以通過修改啟動文件來解決。
以我使用的linux系統(tǒng)為例,啟動文件是/etc/init.d/rcS。采用指令vi /etc/init.d/rcS打開rcS文件,在最末尾添加如下代碼:./sbin/sysctl -p
保存后退出。
reboot重啟可以看到內(nèi)核打印信息中有如下信息:
進入控制臺后,查看vm.dirty_ratio和vm.dirty_background_ratio的值,可知內(nèi)核參數(shù)永久修改成功。
總結
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
如何關閉http Methods中的Trace 提高安全意識
在配置文件http.conf 添加 TraceEnable off 即可關閉2013-02-02centos8使用Docker部署Django項目的詳細教程
這篇文章主要介紹了在centos8使用Docker部署Django項目的教程,本文通過圖文并茂的形式給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-05-05