溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

容器化 RDS:借助火焰圖定位Kubernetes性能問(wèn)題

發(fā)布時(shí)間:2020-08-08 21:38:32 來(lái)源:ITPUB博客 閱讀:191 作者:沃趣科技 欄目:云計(jì)算

容器化 RDS:借助火焰圖定位Kubernetes性能問(wèn)題

容器化RDS系列文章:


  • 容器化RDS:計(jì)算存儲(chǔ)分離架構(gòu)下的“Split-Brain”

  • 容器化RDS:計(jì)算存儲(chǔ)分離還是本地存儲(chǔ)?

  • 容器化RDS:你需要了解數(shù)據(jù)是如何被寫(xiě)"壞"的

  • 容器化RDS:借助 CSI 擴(kuò)展 Kubernetes 存儲(chǔ)能力


借助 CSI(Container Storage Interface),加上對(duì) Kubenetes 核心代碼的少量修改,可以 out-tree 的方式高效且低耦合的方式擴(kuò)展 Kubenetes 存儲(chǔ)管理子模塊。

如《 容器化 RDS:借助 CSI 擴(kuò)展 Kubernetes 存儲(chǔ)能力 》介紹,以 out-tree 方式添加 PVC 擴(kuò)容(Resize)特性。

從可執(zhí)行程序到可用編程產(chǎn)品,還需要設(shè)計(jì)結(jié)合業(yè)務(wù)需求的性能基準(zhǔn)測(cè)試,并對(duì)發(fā)現(xiàn)的性能瓶頸進(jìn)行優(yōu)化。

經(jīng)驗(yàn)數(shù)據(jù)表明,相同功能的編程產(chǎn)品的成本,至少是已經(jīng)過(guò)測(cè)試的程序的三倍。     ——人月神話

本文將分享性能基準(zhǔn)測(cè)試的優(yōu)化案例:

  • 發(fā)現(xiàn)性能瓶頸

  • 確定問(wèn)題組件

  • 借助 CPU Profile 和 Flame Graph,快速縮小范圍,定位到問(wèn)題 code-path

  • 有針對(duì)的優(yōu)化


| 發(fā)現(xiàn)性能瓶頸

測(cè)試用例:


批量創(chuàng)建100個(gè)讀寫(xiě)模式為RWO,容量為1GiB 的 PVC

期望測(cè)試結(jié)果:

180秒內(nèi)全部創(chuàng)建成功并無(wú)報(bào)錯(cuò)

所有的編程人員都是樂(lè)觀主義者,畢竟在可能出現(xiàn)問(wèn)題的地方,一定都會(huì)遇到問(wèn)題,在耗時(shí) 3600 秒后,95% 的 PVC 處于 Pending 狀態(tài),嚴(yán)格的說(shuō),在批量創(chuàng)建的場(chǎng)景,該功能不可用。


容器化 RDS:借助火焰圖定位Kubernetes性能問(wèn)題

大量 PVC 處于 Pending 狀態(tài)


| 定位問(wèn)題組件

由于涉及組件眾多:


  • kube-apiserver

  • kube-controller-manager

  • kubelet

  • external-provisioner

  • external-attacher

  • csi-driver

  • qcfs-csi-plugin


組件之間調(diào)用復(fù)雜,再加上無(wú)處不在的協(xié)程(goroutine),如果直接查看日志或是 debug code 定位問(wèn)題,猶如大海撈針,更不要說(shuō)定位性能瓶頸。所以,首要工作是先定位到問(wèn)題組件。

在測(cè)試過(guò)程中,我們記錄了所有組件和系統(tǒng)的資源使用情況,運(yùn)氣不佳,從 CPU 使用情況,內(nèi)存使用情況,網(wǎng)絡(luò) I/O 和磁盤(pán) I/O 來(lái)看都沒(méi)有異常數(shù)據(jù)。

通過(guò)梳理存儲(chǔ)管理相關(guān)組件的架構(gòu)圖:

容器化 RDS:借助火焰圖定位Kubernetes性能問(wèn)題

架構(gòu)圖


以及業(yè)務(wù)流程的梳理,kube-controller-manager、external-provisioner 和 csi-driver 嫌疑較大。

通過(guò) kubelet logs 查看日志,可以在 external-provisioner 中發(fā)現(xiàn)可疑日志:


I0728 19:19:50.504069    1 request.go:480] Throttling request took 192.714335ms, request: POST:https://10.96.0.1:443/api/v1/namespaces/default/events
I0728 19:19:50.704033    1 request.go:480] Throttling request took 190.667675ms, request: POST:https://10.96.0.1:443/api/v1/namespaces/default/events

external-provisioner 訪問(wèn) kube-apiserver 觸發(fā)限流


external-provisioner 有重大嫌疑。


| 定位問(wèn)題 code-path

我們可以立馬進(jìn)入調(diào)試環(huán)節(jié):


  1. 閱讀 external-provisioner 代碼,加入調(diào)試日志,理解邏輯

  2. 不斷縮小 code-path


步驟 1、2持續(xù)迭代,直到最終定位到問(wèn)題函數(shù),這是非常有效的辦法。

或者采用 CPU profile:

  1. 采集堆棧樣本

  2. 找到在采樣手氣內(nèi)消耗 CPU 時(shí)間比率最高的函數(shù),把該函數(shù)作為調(diào)試的起點(diǎn)


相比上一種,更高效的縮小問(wèn)題的范圍,節(jié)省更多的時(shí)間。

借助模塊“net/http/pprof”,對(duì) external-provisioner 進(jìn)行 60 秒的 CPU 采樣,可以獲得如下信息:

生成堆棧使用百分比排序:

容器化 RDS:借助火焰圖定位Kubernetes性能問(wèn)題


函數(shù)的調(diào)用關(guān)系以及采樣周期內(nèi) CPU 耗時(shí)百分比:



容器化 RDS:借助火焰圖定位Kubernetes性能問(wèn)題



針對(duì)“net/http/pprof”稍微啰嗦幾句:


  • 提供 CPU profile 和 Heap profile;

  • 在采樣時(shí)獲得堆棧(幾乎所有)信息, 以此為依據(jù)估算整個(gè)采樣周期內(nèi)堆棧的CPU占用百分比, 并不是 100% 準(zhǔn)確;

  • 采樣成本并不低,100赫茲既可以采樣夠用的堆棧信息,又不會(huì)給應(yīng)用程序帶來(lái)過(guò)大開(kāi)銷(xiāo);

  • CPU 采樣頻率默認(rèn)為 100 赫茲,并硬編碼到模塊中, 不建議調(diào)到 500 赫茲以上。


網(wǎng)上已經(jīng)有大量的相關(guān)文章,這里不贅述。

配合獲取的 CPU profile 信息生成火焰圖(Flame Graph):


容器化 RDS:借助火焰圖定位Kubernetes性能問(wèn)題


這里針對(duì)火焰圖再啰嗦下:


  • 借助第三方工具 go-torch 繪制

  • 每個(gè)矩形代表一個(gè)堆棧,采樣時(shí)間內(nèi),CPU 占用百分比越高 Y 軸越長(zhǎng),X 軸表明了堆棧之間的調(diào)用關(guān)系

  • 從左到右按照字母表排序

  • 顏色隨機(jī)選擇,無(wú)具體含義


網(wǎng)上已經(jīng)有大量的相關(guān)文章,這里不贅述。

可以發(fā)現(xiàn)函數(shù) addClaim 和 lockProvisionClaimOperation 的 CPU 占用比率達(dá)到 36.23%。


容器化 RDS:借助火焰圖定位Kubernetes性能問(wèn)題

來(lái)自于 external-provisioner 調(diào)用的第三方模塊 kubenetes-incubator/external-storage


所以,只要引用例如了模塊 Kubenetes-incubator/external-storage 實(shí)現(xiàn)卷創(chuàng)建功能,都可以復(fù)現(xiàn) api throttling。


再針對(duì)性的加入調(diào)試日志到 code-path 中,理解邏輯,很快可以確定問(wèn)題:

在創(chuàng)建卷時(shí),external-storage 需要訪問(wèn) API 資源(譬如 configmap、pvc、pv、event、secrets、storageclass 等),為減少 kube-apiserver 工作負(fù)荷,不建議直接訪問(wèn) kube-apiserver,而應(yīng)該利用本地緩存(由 informer cache 構(gòu)建)。但 external-storage 恰好直接訪問(wèn) kube-apiserver。通過(guò)下圖可以看到,有18.84%的采樣時(shí)間在 list event,這是導(dǎo)致 api throttling 的原因。


容器化 RDS:借助火焰圖定位Kubernetes性能問(wèn)題


進(jìn)一步分析,之所以有大量的 list event 是因?yàn)?Leader Election 的 Lock 實(shí)現(xiàn)粒度太細(xì)導(dǎo)致鎖搶占嚴(yán)重。生產(chǎn)環(huán)境中,一個(gè)組件會(huì)啟動(dòng)多個(gè)實(shí)例,搶占到 Leader Lock 的實(shí)例即為 Leader 并對(duì)外提供服務(wù),其他實(shí)例以 Slave 模式運(yùn)行,一旦 Leader 出現(xiàn)問(wèn)題,Slave 發(fā)現(xiàn) Leader Lock 在租期內(nèi)沒(méi)有更新即可發(fā)起搶占成為新的 Leader 并接管服務(wù)。這樣不僅提升了組件的可用性也避免了可能帶來(lái)的 data race 問(wèn)題。所以可以理解成是一個(gè)組件實(shí)例一把鎖,并且只在 Leader 和 Slave 角色切換時(shí)才會(huì)重新選主,但 external-storage 原意為了提升并發(fā)度,運(yùn)行多個(gè)實(shí)例同時(shí)為 Leader 提供服務(wù),可以簡(jiǎn)單理解成一個(gè) PVC 一把鎖,100 PVC 就意味著多個(gè)實(shí)例要最少發(fā)生100次的 Lock 搶占。


最終定位到問(wèn)題原因:

Lock 的搶占導(dǎo)致 api throttling,引發(fā) Lock 搶占 timeout,timeout 后搶占重試,進(jìn)一步惡化 api throttling。

從下圖可以進(jìn)一步得到驗(yàn)證,有 8.7% 的采樣時(shí)間在進(jìn)行 Leader Election。

容器化 RDS:借助火焰圖定位Kubernetes性能問(wèn)題


| 解決問(wèn)題

一旦發(fā)現(xiàn)問(wèn)題的根源,解決它反而是件不難的事情。后面針對(duì)該問(wèn)題做了修復(fù):


  • 采用 sharedinformer cache

  • 修改 Leader Lock 粒度


再次生成運(yùn)行,可以發(fā)現(xiàn)函數(shù) addClaim 和 lockProvisionClaimOperation 的 CPU 占用百分比下降到 13.95%。


容器化 RDS:借助火焰圖定位Kubernetes性能問(wèn)題

external-provisioner 日志中的 throttling 關(guān)鍵字消失


100 PVC 的時(shí)間縮短到60秒以內(nèi)全部創(chuàng)建成功,無(wú)任何報(bào)錯(cuò)。


| 結(jié)語(yǔ)

對(duì)于終端用戶而言,交互的界面越來(lái)越簡(jiǎn)單,但對(duì)于開(kāi)發(fā)者而言,組件越來(lái)越多,編譯一次的時(shí)間越來(lái)越久,加上無(wú)處不在的并發(fā),導(dǎo)致定位問(wèn)題的難度越來(lái)越大,尤其是性能問(wèn)題。所以,對(duì)體系架構(gòu)的理解能幫我們快速鎖定問(wèn)題組件,配合 Profile 工具和 Flame Graph 快速定位 code-path,再加上對(duì)業(yè)務(wù)邏輯的理解找到解決方案。


所有的編程人員都是樂(lè)觀主義者,無(wú)論是什么樣的程序,結(jié)果是勿庸置疑的:"這次它肯定會(huì)運(yùn)行。" 或者 "我剛剛找出了最后一個(gè)問(wèn)題。"              ——人月神話



| 作者簡(jiǎn)介

熊中哲·沃趣科技聯(lián)合創(chuàng)始人

曾就職于阿里巴巴和百度,超過(guò)10年關(guān)系型數(shù)據(jù)庫(kù)工作經(jīng)驗(yàn),目前致力于將云原生技術(shù)引入到關(guān)系型數(shù)據(jù)庫(kù)服務(wù)中。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI