直播回顾:如何对付臭名昭著的 IO 夯?诊断利器来了 | 龙蜥技术
簡介:聽到IO夯總是讓人頭疼,那有沒有可以分析IO夯問題的利器?
編者按:sysAK(system analyse kit),是龍蜥社區(OpenAnolis)系統運維 SIG 下面的一個開源項目,聚集阿里百萬服務器的多年運維經驗,針對不同的運維需求提供了一系列工具,形成統一的產品進行服務。作者總結了實際工作中處理的 IO 夯問題的經驗,將它梳理成一套理論分析方法并形成 iosdiag 工具,集成到了sysAK 工具集里。本文將由作者帶大家一道領略一下 iosdiag 在 IO 夯領域叱咤風云的魅力。本文整理自龍蜥大講堂第三期技術解讀,直播回顧可在龍蜥社區官網查看。
作者:李光水(君然)系統運維SIG核心成員、 毛文安(品文)系統運維SIG負責人。
一、引言
這是作者第二次備戰雙十一,懷著激動的心情迎接雙十一的到來,不曾想迎來的是一枚深水炸彈:趕緊處理一下業務那邊出現的 Load 高問題。
“為什么 Load 高呢?”
“因為有 500 多個進程變成了 D 狀態。”
“那為什么會有這個多進程 D 狀態呢?”
“因為出現了 IO 夯問題...”
曾幾何時,聽到 IO 夯,作者會有點頭皮發麻,為啥呢?因為沒有有效手段去定位這個問題,或者就算是有手段,也得經歷山路十八彎,成不成還的看運氣,若是幸運,還能分析點啥出來,若是不幸運,把機器整掛掉,得不償失。時至今日,遇到 IO 夯問題再也不虛了,因為作者現在手里有可以分析 IO 夯問題的利器——sysak iosdiag。
先來看看這個棧,500 多個進程是因為在內核下等待某個磁盤的塊設備互斥鎖而進入 D 狀態,如圖 1-1 所示:
圖 1-1
互斥鎖正被執行讀 IO 請求的內核進程 kworker 持有,如圖 1-2 所示,只有讀 IO 流程完成之后才能釋放鎖。但是因為 IO 夯住了,讀 IO 流程無法順利完成,所以就沒法正常釋放鎖了。所以接下來就需要找到是訪問哪塊磁盤出現了 IO 夯?IO 究竟夯在哪里?
圖1-2
之后作者使用 sysak iosdiag 工具找到了出現 IO 夯問題的磁盤,同時也定位出來這個 IO 是夯在了磁盤側,如圖 1-3 所示:
圖1-3
作者通過查詢 virtio 的后端磁盤的硬件隊列的 IO 信息,發現 IO 實際已經處理完了,進一步查詢 vring 信息,發現后端沒有更新 used ring,最終將問題原因鎖定到了 virtio 后端。最后此問題的具體修復方法我們在此不再一一表述,總之,該工具可以方便的定界到問題出自前端驅動還是后端設備側,節省了不少人力。
經過此問題,作者也簡單做了下總結,聊一下 IO 夯的那些事。
二、史詩級的IO架構
在聊 IO 夯之前,了解一個 IO 會經過哪些路徑還是很有必要的。網上有各式各樣的 IO 架構圖,足以讓人看到眼花撩亂;作者從一個 IO 的生命周期的角度畫了一幅圖,然后描述一個 IO 在不同階段的那些事兒(下圖中去掉了部分軟件層次,如 dm、lvm 等),流程有點長,請耐心看完~
圖 2-1
三、臭名昭著的IO夯
3.1 何為IO夯
IO 夯,可簡單理解為 IO 路徑在一定程度上堵住了,輕則經過特定路徑的 IO 不可訪問,重則整條 IO 路徑堵住不可用,任你多少 IO 丟下來,我就是沒反應。為什么 IO 路徑會堵住呢,無外乎是在等待資源。
等待資源一般涉及的是 IO 路徑上不可重入的臨界區,要求進程持有資源進入、釋放資源退出,又或者是事物處理型,允許接受有限個進程的事物,但要等待這些進程的事物全部被處理完之后,才能接收新的進程事物,開始處理新一輪的流程。而當處于臨界區內的進程,由于內核 bug 或存儲介質原因,導致無法順利完成 IO 后正常退出,最終造成臨界區外的進程因為拿不到資源而處于阻塞狀態,導致無 IO 可用。由此可見,只要臨界區內的進程不退出這種尷尬的狀態,整條 IO 路徑就不可用。
圖 3-1
內核下有條 io complete 的關鍵路徑,這條路徑屬于可重入路徑,其主要職責為對 IO 結束后的收尾工作,一般地,會先執行一個 IO 回調流程,而后更新一些 IO 的stat信息,最后結束生命周期。內核中也有一些特殊類的 IO,在 IO 子系統中的處理方式與一般的 IO 有所差異,如 flush/fua io,而作者曾經碰到過一起 flush/fua io 夯的問題。flush/fua io 在使用日志型的文件系統場景下可能會比較常見,如 ext4 文件系統,為了保證文件系統元數據能夠真正的持久化存儲到磁盤的日志區域,jbd 線程在提交 commit record 的時候會發起這種 IO,而flush/fua io的處理流程也是比較繁瑣的:
圖 3-2
如上圖所示,IO 子系統在處理這個 IO 時,會先發起一個 flush io 到磁盤(在內核中喚作pre-flush),等這個 IO 結束之后,再發起真正的數據 IO,當磁盤執行完數據 IO 之后,再此發起一個flush io(在內核中也喚作 post-flush),終于 flush io 結束之后,數據 IO 進入complete 路徑。在這個數據 IO 里面,一般會存在比較關鍵的 IO 回調,其涉及到釋放 buffer head 的 lock bit 或者 page cache 的 lock bit,而且往往等待這個 lock bit 的是 jbd 線程本身;作者曾經就遇到 pre-flush io 因為 race 問題被直接釋放掉了,導致后續的 IO 流程沒有走到,data io 沒有得到處理,buffer lock 得不到釋放,造成 jbd 夯住,最終引起這個分區的 IO 都得不到響應。
經過本小節的介紹,結合章節 2 的 IO 結構圖(圖 2-1),可以發現 IO 夯是可以發生 IO 路徑上的任何地方。
3.2 IO夯的危害
從 3.1 可知,IO 夯會造成有 IO 需求的進程無 IO 可用;從業務穩定性角度來看,對于那些有 IO 訪問需求的業務進程,IO 夯可能會引起進程長期阻塞,且在 IO 路徑恢復之前,都無法對外提供服務。從系統穩定性角度來看,IO 夯可能會引起大量的進程進入 D 狀態,導致系統高負載,甚至系統夯住,shell 命令無法執行,機器無法登陸,最終不得不重啟系統去解決。
3.3 IO夯問題分析方法現狀
當遇到 IO 夯問題時,我們通常會分析 dmesg 中 hungtask 調用棧、或者是 iosta 信息、sysfs/debugfs 中的統計信息,再結合以往經驗去推測問題可能出在哪。當我們碰到如下圖 3-3 所示的 iostat 信息時,根據經驗,會懷疑是磁盤側有 IO 沒回,因此懷疑io夯在磁盤上,讓存儲的同學去排查磁盤側。但這種經驗卻不一定靠譜,如果是在磁盤返回到 io complete 之間有內核 bug,iostat 也會出現下圖中的信息。
圖 3-3
那如何分析 IO 夯問題是最有效的呢?答案肯定是要找出來夯住的 IO 請求,然后根據請求里面的信息去分析當前這個請求是處于什么狀態、已經走到哪個路徑了。但遺憾的是,目前沒有實現這個功能的通用工具,唯一能快速實現這一需求的,就只有對問題現場做 crash 分析了,找到夯住的 IO 請求,根據 IO 請求中的信息,再結合代碼流程,一步步深入最終找到問題原因,但前提是業務可以容忍這么操作。
3.4 利器簡介——sysak iosdiag
sysAK iosdiag,是 sysAK 工具平臺中的 IO 診斷工具,已具備 IO 時延探測、IO 夯診斷兩大功能,其中 IO 夯診斷可用于檢測當前系統中 IO 夯事件并確定問題邊界。工具的大體架構圖 3-4 所示:
圖 3-4
首先通過 sysAK 的 iosdiag 功能去使能 IO 夯診斷,這里診斷到 IO 夯之后,會對 IO 進行數據分析,然后形成診斷結論,診斷結論是以 json 的數據格式保存在一個日志文件里面,同時也支持將數據上傳到指定的地方,目前支持 oss 的上傳方式,不上傳的話,數據也會存在機器本地,供調用者去查看。
圖 3-5
工具的性能開銷情況:單核 cpu 低于 1%、內存消耗低于 10MB、消耗少許磁盤空間保存診斷結果。
工具支持的內核版本種類:3.10/4.9/4.19多種版本。
iosdiag 診斷結果輸出,力求信息準確、結果直觀,期望即便不具備內核IO子系統知識的同學也能快速上手。工具會輸出一些結論性的信息,如什么時間點,檢測到了 IO 事件,這是一個什么樣的 IO,從哪個 cpu 發出來的,從哪個磁盤的哪個位置訪問多大的數據量,然后這個 IO 夯在哪個路徑上,夯住了多久。
圖 3-6
四、TODO
工具目前只能覆蓋到進入內核 block 層的 IO,在 block 之上的覆蓋不到,因此作者目前也在研究如何擴大工具的覆蓋面;其次,工具在結果輸出上還不夠直觀,使用者還無法簡單明了地從輸出信息上看到問題,針對這一點,作者也一直在優化。
原文鏈接
本文為阿里云原創內容,未經允許不得轉載。?
總結
以上是生活随笔為你收集整理的直播回顾:如何对付臭名昭著的 IO 夯?诊断利器来了 | 龙蜥技术的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python 生成xml文件
- 下一篇: 启动、内存、卡顿三大分析,用户体验就用它