您好,登錄后才能下訂單哦!
這期內(nèi)容當(dāng)中小編將會給大家?guī)碛嘘P(guān)使用THP的配置建議及關(guān)閉方法是什么,文章內(nèi)容豐富且以專業(yè)的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。
我們之前在生產(chǎn)環(huán)境上遇到過很多起由操作系統(tǒng)的某些特征引起的性能抖動案例,其中 THP 作案次數(shù)較多,因此下面將和大家分享 THP 引起性能抖動的原因、典型的現(xiàn)象,分析方法等,在最后給出使用THP 時的配置建議及關(guān)閉方法。
世界并不是非黑即白的,THP 也是內(nèi)核的一個重要特征,且持續(xù)在演進(jìn),其目的是通過將頁表項映射更大的內(nèi)存,來減少 Page Fault,從而提升 TLB (Translation Lookaside Buffer,由存儲器管理單元用于改進(jìn)虛擬地址到物理地址的轉(zhuǎn)譯速度)的命中率。結(jié)合存儲器層次結(jié)構(gòu)設(shè)計原理可知,當(dāng)程序的訪存局部性較好時,THP 將帶來性能提升,反之 THP 的優(yōu)勢不僅喪失,還有可能化身為惡魔,引起系統(tǒng)的不穩(wěn)定。遺憾的是數(shù)據(jù)庫的負(fù)載訪問特征通常是離散的。
在陳述 THP 引起的負(fù)面現(xiàn)象前,先來和大家一起回憶下,Linux 操作系統(tǒng)是如何管理物理內(nèi)存的。對于不同的體系結(jié)構(gòu),內(nèi)核對應(yīng)不同的內(nèi)存布局圖。其中用戶空間通過多級頁表進(jìn)行映射來節(jié)約映射管理所需的空間,而內(nèi)核空間為了簡單高效采用線性映射。在內(nèi)核啟動時,物理頁面將加入到伙伴系統(tǒng) (Buddy System)中,用戶申請內(nèi)存時分配,釋放時回收。為了照顧慢速設(shè)備及兼顧多種 workload,Linux 將頁面類型分為匿名頁(Anon Page)和文件頁 (Page Cache),及 swapness,使用 Page Cache 緩存文件 (慢速設(shè)備),通過 swap cache 和 swapness 交由用戶根據(jù)負(fù)載特征決定內(nèi)存不足時回收二者的比例。為了盡可能快的響應(yīng)用戶的內(nèi)存申請需求并保證系統(tǒng)在內(nèi)存資源緊張時運行,Linux 定義了三條水位線 (high,low,min),當(dāng)剩余物理內(nèi)存低于 low 高于 min 水位線時,在用戶申請內(nèi)存時通過 kswapd 內(nèi)核線程異步回收內(nèi)存,直到水位線恢復(fù)到 high 以上,若異步回收的速度跟不上線程內(nèi)存申請的速度時,將觸發(fā)同步的直接內(nèi)存回收,也就是所有申請內(nèi)存的線程都同步的參與內(nèi)存回收,一起將水位線抬上去后再獲得內(nèi)存。這時,若需要回收的頁面是干凈的,則同步引起的阻塞時間就比較短,反之則很大(比如幾十、幾百ms 甚至 s 級,取決于后端設(shè)備速度)。除水位線外,當(dāng)申請大的連續(xù)內(nèi)存時,若剩余物理內(nèi)存充足,但碎片化比較嚴(yán)重時,內(nèi)核在做內(nèi)存規(guī)整的時候,也有可能觸發(fā)直接內(nèi)存回收(取決于碎片化指數(shù),后面會介紹)。因此內(nèi)存直接回收和內(nèi)存規(guī)整是進(jìn)程申請內(nèi)存路徑上的可能遇到的主要延遲。而在訪存局部性差的負(fù)載下,THP 將成為觸發(fā)這兩個事件的幕后黑手。
我們在多個用戶現(xiàn)場發(fā)現(xiàn)當(dāng)分配 THP 引發(fā)性能波動時,其最典型的特征就是 Sys CPU 使用率飆升,這種特征的分析比較簡單,通過 perf 抓取 on-cpu火焰圖,我們就可以看到我們服務(wù)所有處于 R 狀態(tài)的線程都在做內(nèi)存規(guī)整,且缺頁異常處理函數(shù)為 do_huge_pmd_anonymous_page,說明當(dāng)前系統(tǒng)沒有連續(xù) 2M 的物理內(nèi)存,因此觸發(fā)了直接內(nèi)存規(guī)整,直接內(nèi)存規(guī)整的邏輯是很耗時的,是導(dǎo)致 sys 利用率升高的原因。
真實的系統(tǒng)往往是復(fù)雜的,當(dāng)分配 THP 或分配其它高階內(nèi)存時,系統(tǒng)并不會做直接內(nèi)存規(guī)整,留下上述那么典型的犯罪特征,而是混合其他行為,比如直接內(nèi)存回收。直接內(nèi)存回收的參與讓事情變的稍微有些復(fù)雜和令人疑惑,比如我們最初從客戶現(xiàn)場看到 normal zone 的剩余物理內(nèi)存高于 high 水位線,可系統(tǒng)為啥不停的在做直接內(nèi)存回收呢?我們深入到慢速內(nèi)存分配的處理邏輯中可知,慢速內(nèi)存分配路徑主要有幾個步驟:1. 異步內(nèi)存規(guī)整;2. 直接內(nèi)存回收;3. 直接內(nèi)存規(guī)整;4. oom 回收,每個步驟處理完成后,都會嘗試分配內(nèi)存,如果可分配了,則直接返回頁面,略過后面的部分。其中內(nèi)核為伙伴系統(tǒng)的每個 order 提供了碎片指數(shù)來表示內(nèi)存分配失敗是由于內(nèi)存不足還是碎片化引起的。和其關(guān)聯(lián)的是 /proc/sys/vm/extfrag_threshold, 當(dāng)接近 1000 時,表示分配失敗主要和碎片化相關(guān),此時內(nèi)核會傾向于做內(nèi)存規(guī)整,當(dāng)接近 0 時,表示分配失敗和內(nèi)存不足關(guān)聯(lián)更大,則內(nèi)核會傾向于做內(nèi)存回收。因此產(chǎn)生了在高于 high 水位線的時候,頻繁進(jìn)行直接內(nèi)存回收的現(xiàn)象 。而由于 THP 的開啟和使用占據(jù)了高階內(nèi)存,因此加速了內(nèi)存碎片化引起的性能抖動問題。
對此特征,判定方法如下:
運行 sar -B 觀察 pgscand/s ,其含義為每秒發(fā)生的直接內(nèi)存回收次數(shù),當(dāng)在一段時間內(nèi)持續(xù)大于0時,則應(yīng)繼續(xù)執(zhí)行后續(xù)步驟進(jìn)行排查;
運行 cat /sys/lernel/debug/extfrag/extfrag_index
觀察內(nèi)存碎片指數(shù),重點關(guān)注 order >= 3 的碎片指數(shù),當(dāng)接近 1.000 時,表示碎片化嚴(yán)重,當(dāng)接近 0 時表示內(nèi)存不足;
運行 cat /proc/buddyinfo, cat /proc/pagetypeinfo
查看內(nèi)存碎片情況, 指標(biāo)含義參考 (https://man7.org/linux/man-pages/man5/proc.5.html),同樣關(guān)注 order >= 3 的剩余頁面數(shù)量,pagetypeinfo 相比 buddyinfo 展示的信息更詳細(xì)一些,根據(jù)遷移類型 (伙伴系統(tǒng)通過遷移類型實現(xiàn)反碎片化)進(jìn)行分組,需要注意的是,當(dāng)遷移類型為 Unmovable 的頁面都聚集在 order < 3 時,說明內(nèi)核 slab 碎片化嚴(yán)重,我們需要結(jié)合其他工具來排查具體原因,在本文就不做過多介紹了;
對于 CentOS 7.6 等支持 BPF 的 kernel 也可以運行我們研發(fā)的 drsnoop,compactsnoop 工具對延遲進(jìn)行定量分析,使用方法和解讀方式請參考對應(yīng)文檔;
(Opt) 使用 ftrace 抓取 mm_page_alloc_extfrag 事件,觀察因內(nèi)存碎片從備用遷移類型“盜取”頁面的信息;
我們在 AARCH64 服務(wù)器上,遇到過服務(wù)剛啟動就占用幾十個 G 物理內(nèi)存的場景,通過觀察 /proc/pid/smaps 文件可以看到內(nèi)存大部分用于 THP, 且 AARCH64 的 CentOS 7內(nèi)核編譯時選用的 PAGE SIZE 為 64K,因此相比 X86_64 平臺的內(nèi)存用量差出很多倍。在定位的過程中我們也順便修復(fù)了 jemalloc 未完全關(guān)閉 THP 的bug: fix opt.thp:never still use THP with base_map。
對于未對訪存局部性進(jìn)行優(yōu)化的程序或負(fù)載本身就是離散的訪存程序而言,將 THP 以及 THP defrag 設(shè)置為始終開啟,對長時間運行的服務(wù)而言有害無益,且內(nèi)核從 4.6 版本內(nèi)核版本起才對 THP 的 defrag 提供了 defer,defer + madvise 等優(yōu)化。因此對于我們常用的 CentOS 7 3.10 版本的內(nèi)核來說,若程序需要使用 THP,則建議將 THP 的開關(guān)設(shè)置為 madvise,在程序中通過 madvise 系統(tǒng)調(diào)用來分配 THP, 否則設(shè)置成 never 禁用掉是最佳選擇:
查看當(dāng)前的 THP 模式:
cat /sys/kernel/mm/transparent_hugepage/enabled
若值是 always 時,執(zhí)行:
echo never > /sys/kernel/mm/transparent_hugepage/enabled echo never > /sys/kernel/mm/transparent_hugepage/defrag
完成關(guān)閉操作。 需要注意的是為防止服務(wù)器重啟失效,應(yīng)將這兩個命令寫入到 .sevice 文件中,交給 systemd 進(jìn)行管理。
上述就是小編為大家分享的使用THP的配置建議及關(guān)閉方法是什么了,如果剛好有類似的疑惑,不妨參照上述分析進(jìn)行理解。如果想知道更多相關(guān)知識,歡迎關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。