著名線上資源存儲網站 Box.com 近日釋出了 memsniff——一個開源的 memcached 流量分析工具。該工具的推出是為了在不影響 memcached 伺服器的情況下診斷熱鍵(hot key)問題。
背景
Box 經曆了從少數幾台伺服器和資料庫到大規模、高性能平台的轉變,與其他大型的網絡公司一樣,Box 也使用了分布式緩存層來緩存經常被通路的資料。不過他們有時候會碰到熱鍵問題,也就是說,某些資料對象的通路頻率突然變得很高,導緻資料伺服器帶寬負載過重,也會影響緩存伺服器提供高性能的服務。
下圖展示了出現熱鍵問題的 memcached 伺服器的網絡帶寬走勢,其中棕色曲線部分表示出現了熱鍵問題。

導緻熱鍵問題的原因有很多,有可能是因為背景任務造成的,也有可能是因為應用程式處理不當,又或者是因為使用者頻繁的活動。大部分緩存系統出于性能方面的考慮,幾乎不提供日志,是以很難确定是哪些資料導緻了這個問題。
而 Box 推出的 memsniff 另辟蹊徑,它通過檢查 memcached 伺服器的網絡資料包來分析資料鍵并提供實時的統計資訊,包括資料的大小、請求速率和占用的帶寬。這樣就可以在不影響伺服器的情況下找出有問題的資料鍵。
memsniff 的靈感來自于 Etsy 的 mctop 和 Tumblr 的 memkeys,它在高負載的情況下仍然可以處理幾乎所有的網絡包(超過 99.99%)。它使用了 golang 的多線程原語,并不會占用太多的 CPU 或記憶體,如下圖所示。
安裝 memsniff
memsniff 使用了标準的 golang toolchain,如果已經安裝了 golang toolchain,并設定了 GOPATH 環境變量,那麼可以通過如下的指令來建構 memsniff。
使用 memsniff
memsniff 需要超級使用者權限來捕捉網絡資料包,通過 -i 參數來指定網卡接口。
memsniff 也可以從 tcpdump 的資料包轉儲檔案中讀取資料。
memsniff 的 GitHub 首頁上提供了更多的參數說明。
memsniff 的原理
使用 GoPacket 從 libpcap 主線程抓取原始資料包。
解碼工作線程解析原始資料包中的 memcached 協定部分,找出 GET 請求的響應消息,從中抽取資料鍵和資料項大小。
抽取出來的概要資訊被發送給分析工具,并根據資料鍵進行分區,每一個工作線程持有一個分區。
分析工具合并各個工作線程的報告,将其展示給 UI 使用者。
memsniff 的性能
在一台配備了英特爾 Xeon E5-2470 處理器的伺服器上運作 memcached,每秒鐘處理 35 萬個左右的請求,得出如下的資料。
使用了 4-5 個核(20 個左右的線程,每個 20% 左右的 CPU 使用率)
處理 100% 資料包
展示了 99.99% 的資料包,說明一直有一小部分資料包在啟動時被丢棄。
在發生熱鍵問題的時候,網絡接口出現飽和,仍然可以處理 99.9% 的資料包。
使用 40MB 左右的堆記憶體
100MB 左右的 RSS(可以通過 GOGC 進行調整)
平均 GC 停頓 0.6 毫秒
最大 GC 停頓 2.0 毫秒
memsniff 路線圖
更多的功能
TCP stream 重組:get-miss 跟蹤、支援二進制協定,支援 redis
觸發器(例如在發生熱鍵問題時發出告警)
在達到某些條件時自動記錄日志(例如某個資料鍵的流量達到設定的門檻值)
通過過濾器限制資料集
跟蹤單個請求和響應
根據用戶端 IP 限制流量
功能改進
支援指定 memcached 伺服器端口
支援更多的排序方式
支援同時監聽多個伺服器
支援 GET 以外的操作
視圖過濾
支援建立穩定的報告,并輸出到磁盤
提供工具用于建構其他格式的包(如 deb、rpm 等)