通常我們使用mongodb的時候,客戶端(driver)和mongodb之間都是使用長連線,但是在某些場景下、某些driver仍然只能使用短連線進行連線,比如php。就在我們阿里雲資料庫mongodb版商業化後沒多久,我們就遇到了乙個使用者短連線過多導致的效能問題。
這個問題的症狀是mongod的cpu使用率居高不下,16個核都跑滿了,影響到了使用者的正常使用。
首先想到的當然是看看有沒有很多慢查詢,針對存在的慢查詢都建議使用者建了索引後,情況還是沒有好轉。這時我們觀察到使用者的driver不斷有短連線上來,基本上身份認證完執行個操作後很快就斷開。會不會是短連線的問題導致呢?因為阿里雲資料庫mongodb版出於安全考慮,強制開啟了身份認證,我們知道mongodb3.0後使用的身份認證機制是scram-sha1,這是需要進行一些cpu密集型操作比如雜湊計算計算等的。通過profile工具進行診斷後,我們發現cpu熱點非常集中,主要消耗在讀取『/dev/urandom』來生成隨機數,這需要通過系統呼叫進入核心態。再結合監控,確實cpu都消耗在sys而不是user。以下為profile工具診斷圖:
對照一下原始碼就知道了,這是因為在認證過程中需要生成一串叫做server-nonce的隨機字串(具體的認證過程及這個隨機字串的作用可參照mongodb中使用的scram-sha1認證機制。在linux平台下,是通過這個『/dev/urandom』(linux上提供了兩個隨機數生成的特殊裝置檔案,還有乙個是『/dev/random』,這兩個的區別是從『/dev/urandom』中讀取是非阻塞的,具體可再自行google或看man手冊。)來生成隨機數的。其原理是利用當前系統的熵池來計算出一定數量的隨機位元,然後將這些位元作為位元組流返回。熵池就是當前系統的環境噪音,因此其隨機效果還是比較好的。不過有利必有弊,這個『/dev/urandom』的效能就不怎麼好了。要使用這個來生成隨機數,首先要進行系統呼叫,這涉及使用者態到核心態的切換。其次,為了避免兩個併發讀返回同樣的結果,在核心中使用了spinlock,因此在多執行緒併發從『/dev/urandom』中讀時,效能會急劇下降。這個東東設計之初是為了安全,而不是效能。因此建議的做法是使用『/dev/urandom』來初始化使用者態的隨機數,而不是每個請求都從這裡取。
既然知道了問題,那麼解決也就好辦了,當然是想辦法使用乙個效能較好,隨機性又不差的方案來替換這個『/dev/urandom』。我們使用了乙個使用者態的隨機數生成器,效果非常明顯,cpu使用率從100%降到10%。
以下為優化前後cpu使用率對比圖:
其中紅色、藍色、綠色分別為關閉auth、開啟auth(優化前)和開啟auth(優化後)。
目前阿里雲資料庫mongodb版已經全面使用了效能優化版,所以各位使用短連線(如php driver)的客官們可以放心使用了。
長連線 短連線
長連線在web中的運用 如果沒有客戶端大量的訪問,可以採用html5的serversocket長連線 例如hudson 執行時會實時的返回當前執行的結果 vmstat 監控 b 長連線 資料庫連線 短連線 http連線 b b 一 長連線與短連線 b 長連線 client方與server方先建立連線...
長連線 短連線
http協議的長連線和短連線,實質上是tcp協議的長連線和短連線。http屬於應用層協議,在傳輸層使用tcp協議,在網路層使用ip協議。ip協議主要解決網路路由和定址問題,tcp協議主要解決如何在ip層之上可靠的傳遞資料報。http是乙個無狀態的面向連線的協議,無狀態不代表http不能保持tcp連線...
長連線 短連線
參考鏈結 怎麼理解tcp的面向連線和udp的無連線 不面向連線 長連線的幾種實現方式 關於長連線和短連線的理解及使用場景 連線其實只是雙方都維護了乙個狀態,通過每一次通訊來維護狀態的變更 在 http 1.0 中 在 http 1.1 中則 可以在一次連線中處理多個請求,並且多個請求可以重疊進行,不...