故障分析 | 大量短時程式導致 cpu 負載過高案例一則

愛可生雲資料庫發表於2022-05-31

作者:任坤

現居珠海,先後擔任專職 Oracle 和 MySQL DBA,現在主要負責 MySQL、mongoDB 和 Redis 維護工作。

本文來源:原創投稿

*愛可生開源社群出品,原創內容未經授權不得隨意使用,轉載請聯絡小編並註明來源。


1、背景

某專案的開發環境,單臺虛擬機器裝了1套mongo叢集用於測試,1個mongos + 3節點config + 1shard * 3副本,總計7個mongo例項。 mongo版本4.2.19,OS為centos 7.9。

測試結束後cpu負載一直維持在50%左右,而此時mongo的qps已經下降為0。

這臺機器上只安裝了mongo,將所有mongo例項關閉,cpu負載立即恢復正常,再將mongo例項開啟,過了一會cpu負載又開始飆升。場景能復現,且確認是跟mongo例項有關係。

2、診斷

執行top命令,cpu的usr已經達到了40%,但是前幾個程式的%cpu加起來遠遠湊不夠數。

檢視mongos的qps,確實沒有執行使用者命令了。

dstat檢視整體負載(vmstat格式化做的不好,最後幾列總是對不齊整)。

除了cpu負載不正常,其餘指標均正常,中斷和上下文切換也不算高,不太可能是這兩個引發的。
perf record -ag -- sleep 10 && perf report 檢視cpu執行情況。

確實有大量mongo呼叫,但是API命名不直觀,無法猜測對應的執行邏輯。

至此,確認是mongo例項引發的問題,但是mongo的應用連線為0,看呼叫API棧也找不到有用資訊。

回到本文開頭,top程式的cpu利用率加起來遠遠小於cpu總體負載,大概率是有頻繁短時程式偷走了這部分CPU資源,導致top命令來不及捕獲統計。

sar -w 1 檢視每秒生成的程式數,平均每秒新建80多個程式,應該就是它了。

要抓出頻繁建立短時程式的應用,可以採用execsnoop,該工具通過 ftrace 實時監控程式的 exec() 行為,並輸出短時程式的基本資訊, 包括程式 PID/PPID、命令列引數。

#下載execsnoop#
cd /usr/bin
wget https://raw.githubusercontent.com/brendangregg/perf‐tools/master/execsnoop
chmod 755 execsnoop 

以下是輸出內容,全是監控系統在執行,不停的連線mongo並對輸出結果執行grep過濾,每個操作都會衍生一個新執行緒/程式,10s捕獲 了400多條記錄。

將zabixx程式關閉,cpu馬上恢復正常,找到了元凶。

我們其他環境也採用了zabbix監控,但是都沒有遇到類似問題。

該節點部署了7個mongo例項,zabbix預設對每個mongo例項都進行監控,相當於執行損耗放大了7倍,而該機器是一臺只有4核CPU的虛擬機器。

這些因素湊齊了就會爆發問題。 這是個開發環境,暫時關閉了zabbix監控,後續要對監控邏輯進行優化,儘量減少連線db的次數以及grep呼叫鏈的長度。

3、小結

當機器cpu負載持續高漲卻抓取不到top程式時,可以採用execsnoop抓取短時程式,類似工具還有iosnoop、opensnoop。

相關文章