Kubernetes(簡(jiǎn)稱K8s)是業(yè)界主流的開(kāi)源容器編排平臺(tái)之一。kubelet作為管理K8s中Pod及其相關(guān)容器的核心組件,與容器運(yùn)行時(shí)對(duì)接。其原生的static policy綁核機(jī)制旨在避免線程在不同die之間輪轉(zhuǎn),從而減少跨die仿存的性能開(kāi)銷。由于飛騰S2500 L2緩存設(shè)計(jì)特殊,在銀河麒麟操作系統(tǒng)下,kubelet原有的綁核機(jī)制難以發(fā)揮預(yù)期效果,影響CPU性能的發(fā)揮。麒麟軟件技術(shù)團(tuán)隊(duì)對(duì)此進(jìn)行了優(yōu)化,使K8s的容器在飛騰S2500平臺(tái)上性能更佳。
CPU綁核
CPU綁核是借助Cgroup cpuset子系統(tǒng)將線程綁定到指定CPU core上執(zhí)行。合理的CPU綁核避免了內(nèi)核CPU調(diào)度線程帶來(lái)的性能開(kāi)銷。
本文主要關(guān)注L2緩存Miss產(chǎn)生的時(shí)間開(kāi)銷。如圖1所示:
圖1
圖中展示了線程在CPU core之間調(diào)度的場(chǎng)景。在階段1,線程A和B的數(shù)據(jù)加載到各自核心的L2緩存。若未進(jìn)行綁核,在階段2,線程A和B可能交換運(yùn)行的CPU core,導(dǎo)致L2緩存數(shù)據(jù)更新,造成cache miss,帶來(lái)性能開(kāi)銷。而進(jìn)行綁核操作則始終維持在階段1狀態(tài),避免L2緩存數(shù)據(jù)更新,提升性能。
飛騰S2500的硬件特點(diǎn)
通常CPU core與L2緩存是一對(duì)一的關(guān)系(見(jiàn)圖1),而S2500每4個(gè)CPU core共享一個(gè)L2緩存。引發(fā)了新的問(wèn)題:若同一個(gè)L2緩存中的4個(gè)CPU core綁定不同任務(wù)線程,這些線程在運(yùn)行過(guò)程中會(huì)爭(zhēng)搶L2緩存,造成性能波動(dòng),使得綁核效果無(wú)法完全發(fā)揮。
在典型x86 CPU環(huán)境下,假設(shè)有8個(gè)CPU core,兩個(gè)任務(wù),每個(gè)任務(wù)有兩個(gè)線程,一種可能的綁核情況如下圖所示,每個(gè)core有獨(dú)立的L2緩存,因此不同任務(wù)的線程不會(huì)發(fā)生L2緩存搶占,CPU綁核完全發(fā)揮效果。
圖2
在飛騰S2500服務(wù)器中,在與圖2相同的CPU綁核情況下,任務(wù)1和任務(wù)2仍會(huì)出現(xiàn)L2緩存爭(zhēng)搶,觸發(fā)L2 Cache Miss,導(dǎo)致某個(gè)任務(wù)性能波動(dòng),綁核的優(yōu)化效果未能充分發(fā)揮。
圖3
一種理想的綁核情況如下圖,任務(wù)1和任務(wù)2的線程各自綁核到共享同一個(gè)L2緩存的CPU core上。由于同一個(gè)任務(wù)的線程用的數(shù)據(jù)相近,L2緩存完全為該任務(wù)服務(wù),減少Cache Miss,降低性能波動(dòng)。此時(shí)能夠達(dá)到和圖2相同的綁核效果。
圖4
基于飛騰S2500的K8s綁核調(diào)度
優(yōu)化方案(L2親和性優(yōu)化)
原生kubelet代碼中,在綁核過(guò)程中默認(rèn)執(zhí)行takeByTopologyNUMAPacked()函數(shù)。該函數(shù)按照CPU層次結(jié)構(gòu)從高到低,先嘗試分配整個(gè)NUMA節(jié)點(diǎn)或者socket的CPU core,然后嘗試分配整個(gè)CPU core中的計(jì)算資源(考慮超線程,一個(gè)CPU核提供兩個(gè)超線程),最后分配剩余的CPU core(超線程)。該分配邏輯未涉及L2層面的分配算法,因此原生k8s會(huì)如前文所示,在飛騰S2500上無(wú)法完全發(fā)揮綁核的效果。
基于飛騰S2500的L2緩存特殊性,麒麟軟件技術(shù)團(tuán)隊(duì)對(duì)kubelet綁核調(diào)度代碼增加L2親和性優(yōu)化:
? 1)在原生kubelet代碼分配整個(gè)NUMA節(jié)點(diǎn)或Socket和分配整個(gè)CPU core的算力間,插入L2層級(jí)分配邏輯;
? 2)綁核時(shí)優(yōu)先選擇空閑的L2緩存;
? 3)同一任務(wù)線程盡可能綁核在共享同一個(gè)L2緩存的CPU core上。
其中,1)繼承了kubelet原生代碼的特性;2)和3)保證了同一任務(wù)線程能夠盡可能獨(dú)占L2緩存,在綁核時(shí)盡可能避免不同任務(wù)線程爭(zhēng)搶L2緩存導(dǎo)致的性能波動(dòng)。
修改后的takeByTopologyNUMAPacked()函數(shù)邏輯如圖5所示:
圖5
例如,分配8個(gè)CPU core用來(lái)綁核。原生kubelet在飛騰S2500平臺(tái)上的綁核結(jié)果可能如圖6所示:先將NUMA1中空閑的CPU core分配完,再?gòu)腘UMA2中選擇一個(gè)CPU core進(jìn)行分配。
圖6
優(yōu)化后的kubelet分配結(jié)果如圖7所示:待分配的CPU core盡可能獨(dú)占L2緩存。
圖7
經(jīng)過(guò)測(cè)試,優(yōu)化后的kubelet代碼能夠滿足要求,綁核后提升線程運(yùn)行效率和穩(wěn)定性。以4C4G為例,在已有CPU資源被其他Pod占用的情況下部署新Pod,測(cè)試Unixbench指標(biāo)性能對(duì)比,如圖8所示:
圖8
總結(jié)
由于飛騰 S2500 的L2緩存的特殊性,原生kubelet代碼的綁核功能因多容器線程爭(zhēng)搶L2緩存而導(dǎo)致性能波動(dòng),無(wú)法發(fā)揮良好的性能效果。針對(duì)該問(wèn)題,通過(guò)修改kubelet綁核代碼,使容器在綁核時(shí)優(yōu)先選擇同一個(gè)L2緩存下空閑的CPU core,避免L2 Cache Miss導(dǎo)致的性能波動(dòng),提升容器應(yīng)用性能表現(xiàn)。
近年來(lái),隨著網(wǎng)信事業(yè)的快速發(fā)展,國(guó)產(chǎn)軟硬件產(chǎn)品在技術(shù)和品質(zhì)上都取得了顯著的進(jìn)步,以飛騰、鯤鵬、龍芯、兆芯、海光、申威等為代表的國(guó)產(chǎn)CPU性能也得到大幅提升。麒麟操作系統(tǒng)已全面支持國(guó)產(chǎn)主流CPU,在系統(tǒng)安全、穩(wěn)定可靠、好用易用和整體性能等方面具有領(lǐng)先優(yōu)勢(shì)。未來(lái),麒麟軟件將與產(chǎn)業(yè)鏈伙伴共同攜手,為我國(guó)行業(yè)信息化及國(guó)家重大工程建設(shè)提供安全可信的操作系統(tǒng)支撐。
通訊員 | 魏玉成
來(lái) 源 | 服務(wù)器研發(fā)部、產(chǎn)品管理部
審 核 | 市場(chǎng)與政府事務(wù)部