Noisy Neighbor(共用資源的鄰居干擾)
Noisy Neighbor(共用資源的鄰居干擾)
Noisy neighbor 是多個工作負載共用同一份硬體資源時,其中一個用掉的資源從其他工作負載能用的那一份裡扣掉,使那些工作負載變慢或失敗的現象;被影響的一方沒有做錯任何事。本卡管的是硬體資源這一層,共用發生在幾個層:同一台主機上的多個容器(應用程式、資料庫、批次工作、監控)、同一台實體機上的多台虛擬機(雲端的其他租戶),以及開發用筆電上 Docker 的虛擬機與其他程式。它是 Blast Radius 在資源層的來源之一:放在一起的工作負載會一起變慢、一起停;把資源分開的做法見 Bulkhead 與 Resource Limit。同一個服務裡的多個租戶搶連線池、快取或佇列,是同一個現象在應用層的形態,隔離的做法見 Bulkhead。
概念位置
| 共用的層 | 被搶走的資源 | 從哪裡看得到 |
|---|---|---|
| 同一台主機的容器 | CPU、記憶體、磁碟讀寫、網路 | 主機與每個容器的用量(node_exporter、cAdvisor),哪個容器在尖峰時用得最多 |
| 同一台實體機的虛擬機 | CPU 時間、磁碟與網路頻寬 | Linux 虛擬機的 steal 時間(node_cpu_seconds_total{mode="steal"}) |
| 開發用筆電上的虛擬機 | 筆電的 CPU 與磁碟 | CPU 負載只有筆電本身看得到(uptime),筆電忙的時候虛擬機裡的 load 仍然很低;磁碟要看虛擬機有沒有掛進筆電的那一顆(OrbStack 以 virtiofs 掛入,node_exporter 看得到,剩餘比例正確而位元組數放大 256 倍) |
被干擾的服務自己的監控通常看不到成因:它的 CPU 用量低、錯誤少,只有延遲高,成因在它與其他工作負載共用的那一份資源上,而且常在監控所在層之外。隔離由淺到深是同機設上限與權重(Resource Limit)、同機保留資源與優先權、分到不同主機、專用實體機,各層級隔離得了與隔離不了什麼,見 共用主機的資源競爭〈隔離的層級與代價〉。
可觀察訊號與例子
- 全部服務同時變慢,各自的用量都不高:成因在它們共用的那一份資源上,而且可能落在監控所在層之外(虛擬機外的實體機或筆電),各層的監控看得到什麼見 4.26 單機容器服務的流量與資源監控。一台 8 核心的 Mac 被其他程式吃到 load average 55 以上時,Docker 虛擬機裡的 load 除以核心數在 0.33 到 1.28 之間,而容器裡的服務全面變慢,資料庫一個平常一百多毫秒的查詢要 4 秒。這時各服務的延遲告警會一起發出,以主機飽和的告警收斂它們、以及這條規則在虛擬機裡判斷不到外部原因的條件,見 4.27 主機過載時的監控告警。
- 只在某些時段變慢:與同一台主機上的批次工作、備份或另一個租戶的尖峰重疊。
- 受影響的程度因服務而異:同一次過載,同樣的探測條件下(回應碼 200 且 500 ms 以內),Go 後端達標的比例是 92.5%、Laravel 後端是 49%,未達標的全是慢、沒有錯誤;對 CPU 被搶比較敏感的服務先變慢。
設計責任
部署時寫下哪些工作負載共用同一份資源、它們的尖峰會不會重疊,延遲敏感的服務與吃資源的批次工作至少用限制與權重分開,同一台主機上的容器之間用 Resource Limit 把各自能用的量分開。壓測與效能比較的數字要附上當時共用資源的負載,否則不同時間量到的數字不能互相比較。
#backend #capacity-planning #isolation #noisy-neighbor #knowledge-card