竊取:誰從虛擬機竊取 CPU 時間

竊取:誰從虛擬機竊取 CPU 時間

你好! 我想簡單地告訴您有關虛擬機內部竊取的機制以及我們在研究過程中設法發現的一些不明顯的工件,這是我作為雲平台的技術總監必須深入研究的 Mail.ru 雲解決方案。 該平台運行在KVM上。

CPU 竊取時間是虛擬機不接收用於其執行的處理器資源的時間。 該時間僅在虛擬化環境中的來賓操作系統中計算。 就像在生活中一樣,這些分配最多的資源去向何處的原因非常模糊。 但我們決定弄清楚它,甚至進行了一些實驗。 並不是說我們現在知道有關偷竊的一切,但我們現在會告訴您一些有趣的事情。

1.什麼是偷竊

因此,竊取是一個指標,表明虛擬機內的進程缺乏處理器時間。 如上所述 在KVM內核補丁中隱形是指虛擬機管理程序在主機操作系統上執行其他進程的時間,即使它已將虛擬機進程排隊等待執行。 也就是說,steal 計算為進程準備執行的時間與進程被分配處理器時間的時間之間的差值。

虛擬機內核從管理程序接收竊取指標。 同時,虛擬機管理程序並沒有具體指定它正在運行哪些其他進程,它只是說“當我很忙時,我不能給你時間”。 在KVM上,添加了對竊取計算的支持 補丁。 這裡有兩個關鍵點:

  • 虛擬機從管理程序中學習竊取信息。 也就是說,從損失的角度來看,對於虛擬機本身上的進程來說,這是一種間接測量,可能會受到各種扭曲的影響。
  • 虛擬機管理程序不會與虛擬機共享有關其正在執行的其他操作的信息 - 最主要的是它不會投入時間。 因此,虛擬機本身無法檢測到竊取指示器中的失真,這可以通過競爭進程的性質來評估。

2.什麼影響偷竊

2.1. 偷竊計算

本質上,steal 的計算方式與正常 CPU 使用時間大致相同。 關於如何考慮回收的信息並不多。 可能是因為大多數人認為這個問題是顯而易見的。 但這裡也存在陷阱。 要熟悉此過程,您可以閱讀 布倫丹·格雷格的文章:您將了解計算利用率時的許多細微差別,以及由於以下原因導致計算錯誤的情況:

  • 處理器過熱,導致周期跳過。
  • 啟用/禁用睿頻加速,這會改變處理器時鐘速度。
  • 使用 SpeedStep 等處理器節能技術時發生的時間片長度變化。
  • 計算平均值的問題是:估計一分鐘利用率為 80% 可能會隱藏短期的 100% 爆發。
  • 自旋鎖導致處理器被回收,但用戶進程在其執行過程中看不到任何進展。 因此,該進程計算出的處理器利用率將為 XNUMX%,儘管該進程不會實際消耗處理器時間。

我還沒有找到一篇描述類似竊取計算的文章(如果你知道,請在評論中分享)。 但是從源碼來看,計算機制和回收是一樣的。 簡單來說,就是在內核中再增加一個計數器,直接針對KVM進程(虛擬機進程),統計KVM進程等待CPU時間的時長。 計數器從其規格中獲取有關處理器的信息,並檢查虛擬機進程是否使用了其所有滴答聲。 如果僅此而已,那麼我們假設處理器僅被虛擬機進程佔用。 否則,我們會通知處理器正在做其他事情,出現了竊取。

偷竊計數過程會遇到與常規回收計數相同的問題。 並不是說此類問題經常出現,但它們看起來令人沮喪。

2.2. KVM 上的虛擬化類型

廣義上講,虛擬化有三種類型,KVM 都支持這三種類型。 竊取發生的機制可能取決於虛擬化的類型。

翻譯。 在這種情況下,虛擬機操作系統與物理管理程序設備的操作會發生如下情況:

  1. 客戶操作系統向其客戶設備發送命令。
  2. 來賓設備驅動程序接收命令,生成對設備 BIOS 的請求並將其發送到管理程序。
  3. 虛擬機管理程序進程將物理設備的命令轉換為命令,從而使其更加安全。
  4. 物理設備驅動程序接受修改後的命令並將其發送到物理設備本身。
  5. 執行命令的結果沿著相同的路徑返回。

翻譯的優點是它允許您模擬任何設備並且不需要特殊準備操作系統內核。 但你必須為此付出代價,首先是速度。

硬件虛擬化。 在這種情況下,硬件級別的設備可以理解來自操作系統的命令。 這是最快、最好的方法。 但不幸的是,並非所有物理設備、虛擬機管理程序和來賓操作系統都支持它。 目前支持硬件虛擬化的主要設備是處理器。

半虛擬化。 KVM 上設備虛擬化的最常見選項,通常也是來賓操作系統最常見的虛擬化模式。 其特點是使用虛擬機管理程序 API 來處理某些虛擬機管理程序子系統(例如,網絡或磁盤堆棧)或分配內存頁面,而無需轉換低級命令。 這種虛擬化方法的缺點是必須修改來賓操作系統內核,以便它可以使用此 API 與虛擬機管理程序進行通信。 但這通常可以通過在來賓操作系統上安裝特殊驅動程序來解決。 在 KVM 中這個 API 被稱為 virtio API.

與廣播相比,使用半虛擬化,通過直接從虛擬機向主機上的虛擬機管理程序進程發送命令,可以顯著減少到物理設備的路徑。 這使您可以加快虛擬機內所有指令的執行速度。 在 KVM 中,這是通過 virtio API 完成的,它僅適用於某些設備,例如網絡或磁盤適配器。 這就是 virtio 驅動程序安裝在虛擬機內的原因。

這種加速的缺點是,並非所有在虛擬機內運行的進程都保留在虛擬機內。 這會產生一些特殊效果,可能導致偷竊時生成。 我建議開始詳細研究這個問題 虛擬 I/O 的 API:virtio.

2.3. “公平”調度

Hypervisor上的虛擬機實際上是一個普通的進程,遵守Linux內核中的調度(進程之間的資源分配)規律,所以讓我們仔細看看它。

Linux使用所謂的CFS,Completely Fair Scheduler,從內核2.6.23開始它已經成為默認的調度器。 要理解這個算法,可以閱讀Linux內核架構或者源代碼。 CFS 的本質是根據進程的執行持續時間在進程之間分配處理器時間。 進程需要的 CPU 時間越多,它獲得的 CPU 時間就越少。 這確保了所有進程都“公平”地執行——這樣一個進程就不會一直佔用所有處理器,而其他進程也可以執行。

有時,這種範例會產生有趣的工件。 Linux 的長期用戶可能還記得,在運行編譯器等資源密集型應用程序時,桌面上的常規文本編輯器會凍結。 發生這種情況是因為桌面應用程序中的非資源密集型任務與資源密集型任務(例如編譯器)競爭。 CFS 認為這是不公平的,因此它定期停止文本編輯器並讓處理器處理編譯器的任務。 這是使用一種機制糾正的 sched_autogroup,但任務之間處理器時間分配的許多其他特徵仍然存在。 實際上,這並不是一個關於 CFS 中一切有多糟糕的故事,而是試圖引起人們注意這樣一個事實:“公平”分配處理器時間並不是最微不足道的任務。

調度程序中的另一個重要點是搶占。 這是從處理器中踢出竊笑進程並讓其他進程正常工作所必需的。 彈出過程稱為上下文切換。 在這種情況下,任務的整個上下文都被保留:堆棧、寄存器等的狀態,之後進程被發送等待,另一個進程取代它的位置。 對於操作系統來說,這是一項昂貴的操作,並且很少使用,但它本身並沒有什麼問題。 頻繁的上下文切換可能表明操作系統存在問題,但通常它是連續的並且並不表明任何具體情況。

需要這麼長的故事來解釋一個事實:一個進程在誠實的 Linux 調度程序中嘗試消耗的處理器資源越多,它就會越快停止,以便其他進程也可以工作。 這是否正確是一個複雜的問題,可以在不同的負載下以不同的方式解決。 在 Windows 中,直到最近,調度程序都專注於桌面應用程序的優先級處理,這可能會導致後台進程凍結。 Sun Solaris 有五種不同類別的調度程序。 當我們推出虛擬化時,我們添加了第六個, 公平份額調度程序,因為前五個無法與 Solaris Zones 虛擬化充分配合。 我建議通過以下書籍開始詳細研究這個問題 Solaris 內部結構:Solaris 10 和 OpenSolaris 內核體系結構了解 Linux 內核.

2.4. 如何監控盜竊行為?

與任何其他處理器指標一樣,監控虛擬機內部的竊取情況很簡單:您可以使用任何處理器指標工具。 最主要的是虛擬機是在Linux上的。 由於某種原因,Windows 不向其用戶提供此信息。 🙁

竊取:誰從虛擬機竊取 CPU 時間
top 命令的輸出:處理器負載的詳細信息,在最右邊的列中 - 竊取

當嘗試從虛擬機管理程序獲取此信息時會出現困難。 您可以嘗試預測主機上的竊取,例如,使用平均負載 (LA) 參數 - 在執行隊列中等待的進程數的平均值。 計算這個參數的方法並不簡單,但一般來說,如果按處理器線程數歸一化的LA大於1,則表明Linux服務器過載。

所有這些進程都在等待什麼? 顯而易見的答案是處理器。 但答案並不完全正確,因為有時處理器是免費的,但 LA 卻超出了規模。 記住 NFS 如何衰落以及 LA 如何發展。 磁盤和其他輸入/輸出設備也會發生同樣的情況。 但事實上,進程可以等待任何鎖的結束,無論是物理鎖(與 I/O 設備關聯)還是邏輯鎖(例如互斥鎖)。 這還包括硬件級別的鎖定(與磁盤的響應相同)或邏輯級別(所謂的鎖定原語,其中包括一堆實體、互斥自適應和自旋、信號量、條件變量、rw 鎖、ipc 鎖) ...)。

LA 的另一個特點是它被視為操作系統的平均值。 例如,100個進程競爭一個文件,那麼LA=50。 如此大的值似乎表明操作系統很糟糕。 但對於其他歪曲編寫的代碼來說,這可能是一種正常狀態,儘管事實上只有它是壞的,操作系統中的其他進程不會受到影響。

由於這種平均(並且不少於一分鐘),通過 LA 指標確定任何內容都不是最有價值的任務,在特定情況下結果非常不確定。 如果您嘗試弄清楚,您會發現維基百科和其他可用資源上的文章僅描述了最簡單的情況,而沒有對該過程進行深入的解釋。 我再次向所有感興趣的人發送, 布倫丹·格雷格  - 請點擊下面的鏈接。 誰懶得說英語—— 他關於洛杉磯的熱門文章的翻譯.

3.特效

現在我們來看看我們遇到的主要盜竊案例。 我將告訴您它們是如何從上述所有內容中得出的,以及它們與虛擬機管理程序上的指標有何關係。

回收。 最簡單也是最常見的:hypervisor已經被復用了。 事實上,有很多正在運行的虛擬機,它們內部的處理器消耗很高,競爭很多,LA利用率大於1(通過處理器線程標準化)。 所有虛擬機內的所有內容都會變慢。 從管理程序傳輸的竊取也在增長,有必要重新分配負載或關閉某人。 一般來說,一切都是合乎邏輯且可以理解的。

半虛擬化與單實例。 虛擬機管理程序上只有一個虛擬機;它消耗其中的一小部分,但會產生大量 I/O 負載,例如在磁盤上。 並且從某個地方出現了一小部分偷竊,最多可達 10%(如多個實驗所示)。

這個案子很有趣。 Steal 出現在這裡正是因為半虛擬化驅動程序級別的阻塞。 中斷在虛擬機內部創建,由驅動程序處理並發送到管理程序。 由於虛擬機管理程序上的中斷處理,對於虛擬機來說,它看起來像是一個已發送的請求,它已準備好執行並正在等待處理器,但沒有給予它處理器時間。 虛擬女孩認為這次被偷了。

這發生在緩衝區被發送的那一刻,它進入虛擬機管理程序的內核空間,我們開始等待它。 雖然,從虛擬機的角度來看,他應該立即返回。 因此,根據竊取計算算法,這次就被認為是被竊取了。 最有可能的是,在這種情況下可能存在其他機制(例如,處理一些其他系統調用),但它們應該沒有太大不同。

調度程序與高負載虛擬機。 當一台虛擬機比其他虛擬機遭受更多竊取時,這是由於調度程序造成的。 進程加載處理器的次數越多,調度程序就會越早將其踢出,以便其他進程也可以工作。 如果虛擬機消耗很少,它幾乎不會看到竊取:它的進程誠實地坐著等待,我們需要給它更多的時間。 如果虛擬機在其所有核心上產生最大負載,它通常會被處理器踢出,並且他們會盡量不給它太多時間。

當虛擬機內的進程因為無法處理數據處理而嘗試獲得更多處理器時,情況會更糟。 那麼虛擬機管理程序上的操作系統,由於誠實的優化,將提供越來越少的處理器時間。 這個過程就像雪崩一樣發生,偷跳到天空,儘管其他虛擬機可能很難注意到它。 核心越多,受影響的機器就越糟糕。 簡而言之,具有多個核心的高負載虛擬機受到的影響最大。

低洛杉磯,但有偷竊。 如果 LA 約為 0,7(即虛擬機管理程序似乎負載不足),但在各個虛擬機內部觀察到竊取:

  • 上面已經描述了半虛擬化選項。 儘管虛擬機管理程序沒有問題,但虛擬機可以接收指示竊取的指標。 根據我們的實驗結果,這種竊取選項不會超過 10%,並且不會對虛擬機內部應用程序的性能產生重大影響。
  • LA參數計算錯誤。 更準確地說,在每個特定時刻,它的計算都是正確的,但當平均一分鐘時,它就會被低估。 例如,如果虛擬機管理程序的三分之一的虛擬機消耗其所有處理器正好半分鐘,則虛擬機管理程序上每分鐘的 LA 將為 0,15; 四個這樣的虛擬機同時工作將給出 0,6。 根據 LA 指標,他們每個人在半分鐘內都有 25% 的瘋狂搶斷,這一事實已無法再被撤銷。
  • 再次,因為調度員認為某人吃得太多並讓某人等待。 與此同時,我將切換上下文、處理中斷並處理其他重要的系統事務。 因此,某些虛擬機沒有發現任何問題,而另一些虛擬機則出現嚴重的性能下降。

4.其他扭曲

還有一百萬個原因會扭曲虛擬機上處理器時間的公平返回。 例如,超線程和NUMA給計算帶來了困難。 它們完全混淆了執行進程的內核的選擇,因為調度程序使用係數 - 權重,這使得切換上下文時的計算更加困難。

由於睿頻加速或節能模式等技術而導致失真,在計算利用率時,可以人為地增加或減少服務器上的頻率甚至時間片。 啟用睿頻加速會降低一個處理器線程的性能,因為另一個處理器線程的性能會提高。 此時,有關當前處理器頻率的信息不會傳輸到虛擬機,並且虛擬機認為有人正在竊取其時間(例如,它請求 2 GHz,但收到了一半)。

一般來說,造成失真的原因有很多。 您可能會在特定係統上找到其他東西。 最好從我上面提供鏈接的書籍開始,並使用 perf、sysdig、systemtap 等實用程序從虛擬機管理程序檢索統計信息,其中 幾十個.

5。結論

  1. 由於半虛擬化,可能會出現一定程度的竊取,這可以認為是正常的。 他們在網上寫到這個值可以是5-10%。 取決於虛擬機內的應用程序以及它施加在物理設備上的負載。 這裡重要的是要注意應用程序在虛擬機中的感受。
  2. 虛擬機管理程序上的負載與虛擬機內部的竊取的比率並不總是明顯相關;在不同負載下的特定情況下,兩種竊取的估計都可能是錯誤的。
  3. 調度程序對要求太多的進程態度不好。 他試圖為那些要求更多的人提供更少的東西。 大型虛擬機是邪惡的。
  4. 即使沒有半虛擬化,少量竊取也可能是常態(考慮到虛擬機內部的負載、鄰居負載的特徵、跨線程的負載分配和其他因素)。
  5. 如果你想弄清楚特定係統中的竊取情況,你必須探索各種選項,收集指標,仔細分析它們並考慮如何均勻分配負載。 任何情況下的偏差都是可能的,這必須通過實驗來確認或在內核調試器中查看。

來源: www.habr.com

添加評論