對 wrk 延遲分布不準確的分析

對 wrk 延遲分布不準確的分析

來自專欄第二層思考1 人贊了文章

題圖:Photo by Snapwire from Pexels

wrk 是一個非常棒的 HTTP 壓力測試工具,構建在 Redis、NGINX、Node.js 和 LuaJIT 這幾個開源項目的基礎之上,充分利用了他們在事件驅動、HTTP 解析、高性能和靈活性方面的優點,並且可以自己寫 Lua 腳本來生成測試請求。

雖然 wrk 沒有測試案例,並且作者大概一年現身一次來合併代碼,但這些並不妨礙我們把 wrk 作為性能測試和 fuzz 測試的首選工具。如果你還在使用多線程的 ab,那麼非常值得嘗試下 wrk。


下面是 wrk 結果中的延時分布統計部分:

Latency Distribution 50% 1.20ms 75% 595.78ms 90% 899.11ms 99% 1.00s

這個示例是指,50% 的請求在 1.2ms 內完成,90% 的請求在 899 ms 內完成,99% 的請求在 1s 內完成。

我們在使用 wrk 壓力測試自己產品的時候,發現 wrk 統計的延時結果中,大部分請求都是幾毫秒內完成,但有一小部分請求的延時會超過 100 毫秒。 對於用 OpenResty 構建的系統,出現這麼大的延時是不太科學的事情。

雖然這個問題最終解決方法非常簡單,但具體的分析和定位有些曲折,花了好幾天的時間。最終的解決方法並不重要,過程和思考問題的方式才是值得關注的。


遇到延遲問題,我們的第一反應是代碼或者系統某個地方有阻塞。 由於系統比較複雜,所以我們祭出了火焰圖

沒有現成的 systemtap 腳本來分析這類問題,所以花了點時間寫腳本。但調整了幾次 systemtap 腳本,都沒有捕獲到明顯的延時,這個和 wrk 的結果明顯不符。我們猜測這個腳本可能不夠完善,可能遺漏了某些函數沒有 hook 住。但同時也對 wrk 的結果是否正確產生了懷疑。

我們調轉方向,先來定位到底是 wrk 統計錯了,還是確實是 server 的問題。我們在 wrk 所在的伺服器上,把壓測期間的包都 dump 出來,按照耗時進行排序,驚奇的發現結果和 wrk 的延時統計大相徑庭,沒有發現超過 100 毫秒的請求。重複了幾次以上測試,結果都一致。


這下目標就很明確了,只要把 wrk 關於延遲統計的代碼捋順就可以了。最擔心的就是 wrk 內部統計時候有 bug,這就不好修復了,畢竟是一個沒有任何測試案例的項目:(

我們仔細過了一遍 wrk 的統計邏輯,並在開始和結束的地方加了日誌,發現關於延時的統計都是正確的,這也讓我們鬆了一口氣。但是在列印最終結果之前,有一段統計數據校正的代碼:

if (complete / cfg.connections > 0) { int64_t interval = runtime_us / (complete / cfg.connections); stats_correct(statistics.latency, interval); }

按照這個 if 判斷,只要有壓測數據產生,就會進行校正。有興趣的同學,可以去看看 stats_correct 函數的代碼,只有 10 行,我看了幾遍也沒看懂。

再去查代碼的提交記錄,說不定有什麼收穫,但只有下面這一行,又沒看懂:

remove calibration & improve CO correction

吐槽下,如果提交記錄稍微詳細一點兒,不用縮寫,或者加個代碼注釋,就能省不少事兒。

問題查到這裡,已經可以證實不是產品的問題,而且解決方法已經有了,就是注釋掉上面這段校正的代碼。但 wrk 作者特意加上肯定是有原因的,不明白這個原因始終是個隱患。自然的,要開一個 issue 來請教下作者,一年現身一次的 wg 在 15 天后給了答覆,原來上面 commit info 裡面的縮寫 CO 是指 Coordinated Omission,並且給了一篇專門講這個問題的文章,感興趣的同學可以用這個關鍵字自行搜索。

簡單的說,Coordinated Omission 是指在做壓力測試的時候,只統計發送和收到回復之間的時間是不夠的,這個是指服務時間,會遺漏掉很多潛在的問題,還需要把測試請求的等待時間也計算在內,才算是用戶關心的響應時間

提出 CO 這個問題的 Gil Tene,還對 wrk 做了修改,專門解決 CO 的問題: github.com/giltene/wrk2,在這個項目的 README 裡面也有一些對此的解釋,有興趣的可以看看,這裡就不多提及了。


對於我們自己的產品來說,代碼中肯定不會有任何阻塞,在做壓力測試的時候,是會把 CPU 跑滿。即使出現阻塞,也是有火焰圖來採樣分析的。所以 wrk 這裡針對 Coordinated Omission 做的簡單粗暴的校正,反而會產生誤導。

歷史文章推薦:

如何構建自己的投資體系?(上)

一個黑客的自述:我曾吹響進攻的號角


推薦閱讀:

如何評價 OpenResty 2016 大會?

TAG:OpenResty | 性能測試 |