Load高,CPUidle很高,這情況太詭異了

rui__發表於2017-06-12

Load很高,CPU使用率很低的詭異情況

第一次碰到這種Case:物理機的Load很高,CPU使用率很低

先看CPU、Load情況

如圖一:
vmstat顯示很有多工等待排隊執行(r)top都能看到Load很高,但是CPU idle 95%以上
image.png
image.png

這個現象不太合乎常規,也許是在等磁碟IO、也許在等網路返回會導致CPU利用率很低而Load很高

貼個vmstat 說明文件(圖片來源於網路N年了,找不到出處)
image.png

檢查磁碟狀態,很正常(vmstat 第二列也一直為0)

image.png

再看Load是在5號下午15:50突然飆起來的:

image.png

同一時間段的網路流量、TCP連線相關資料很平穩:

image.png

所以分析到此,可以得出:Load高跟磁碟、網路、壓力都沒啥關係

物理機上是跑的Docker,分析了一下CPUSet情況:

image.png

發現基本上所有容器都繫結在CPU1上(感謝 @辺客 發現這個問題)

進而檢查top每個核的狀態,果然CPU1 的idle一直為0

image.png

看到這裡大致明白了,雖然CPU整體很閒但是因為很多程式都繫結在CPU1上,導致CPU1上排隊很長,看前面tsar的–load負載截圖的 等待執行程式排隊長度(runq)確實也很長。

物理機有32個核,如果100個任務同時進來,Load大概是3,這是正常的。如果這100個任務都跑在CPU1上,Load還是3(因為Load是所有核的平均值)。但是如果有源源不斷的100個任務進來,前面100個還沒完後面又來了100個,這個時候CPU1前面佇列很長,其它31個核沒事做,這個時候整體Load就是6了,時間一長很快Load就能到幾百。

這是典型的瓶頸導致積壓進而高Load。

為什麼會出現這種情況

檢查Docker系統日誌,發現同一時間點所有物理機同時批量執行docker update 把幾百個容器都繫結到CPU1上,導致這個核忙死了,其它核閒得要死(所以看到整體CPU不忙,最忙的那個核被平均掩蓋掉了),但是Load高(CPU1上排隊太長,即使平均到32個核,這個佇列還是長,這就是瓶頸啊)。

如下Docker日誌,Load飆升的那個時間點有人批量調docker update 把所有容器都繫結到CPU1上:
image.png

檢查Docker叢集Swarm的日誌,發現Swarm沒有發起這樣的update操作,似乎是每個Docker Daemon自己的行為,誰觸發了這個CPU的繫結過程的原因還沒找到,求指點。

手動執行docker update, 把容器打散到不同的cpu核上,恢復正常:

image.png

總結

  • 技術擴充商業邊界,同樣技能、熟練能力能擴充解決問題的能力。 開始我注意到了Swarm叢集顯示的CPU繫結過多,同時也發現有些容器繫結在CPU1上。所以我嘗試通過API: GET /containers/json 拿到了所有容器的引數,然後搜尋裡面的CPUSet,結果這個API返回來的引數不包含CPUSet,那我只能挨個 GET /containers/id/json, 要寫個迴圈,偷懶沒寫,所以沒發現這個問題。
  • 這種多個程式繫結到同一個核然後導致Load過高的情況確實很少見,也算是個教訓
  • 自己觀察top 單核的時候不夠仔細,只是看到CPU1 的US 60%,沒留意idle,同時以為這個60%就是偶爾一個程式在跑,耐心不夠(主要也是沒意識到這種極端情況,疏忽了)


相關文章