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