關於RabbitMQ效能問題的幾點分析
目前對RabbitMQ的使用才剛剛開始,下面提出的問題,也許是由於對伺服器的配置或者對客戶端API還不瞭解導致的。歡迎斧正。
一. 要避免流控機制觸發
服務端預設配置是當記憶體使用達到40%,磁碟空閒空間小於50M,即啟動記憶體報警,磁碟報警;報警後服務端觸發流控(flow control)機制。一般地,當釋出端傳送訊息速度快於訂閱端消費訊息的速度時,佇列中堆積了大量的訊息,導致報警,就會觸發流控機制。
觸發流控機制後,RabbitMQ服務端接收發布來的訊息會變慢,使得進入佇列的訊息減少;與此同時RabbitMQ服務端的訊息推送也會受到極大的影響,測試發現,服務端推送訊息的頻率會大幅下降,等待下一次推送的時間,有時等1分鐘,有時5分鐘,甚至30分鐘。
一旦觸發流控,將導致RabbitMQ服務端效能惡化,推送訊息也會變得非常緩慢;因此要做好資料設計,使得傳送速率和接收速率保持平衡,而不至於引起伺服器堆積大量訊息,進而引發流控。通過增加伺服器叢集節點,增加消費者,來避免流控發生,治標不治本,而且成本高。
第一次修改本節
- 伺服器單節點,單網絡卡全雙工情況下,測試發現釋出速度過快,壓滿釋出PC機頻寬,對於伺服器來說,下行(接收)頻寬也會壓滿,可是上行(轉發遞送)頻寬卻出現了明顯的下降,似乎有一個爭搶。這可能是導致觸發流控的原因。
二. 從底層取資料一定要非常及時
訂閱端每隔500MS呼叫一次amqp_consume_message介面函式從socket上獲取資料,正常情況下,伺服器每次會推送幾百條訊息,而且推送的頻率會比較高;導致訂閱端的本機socket緩衝區會很快存滿,導致很多訊息無法進行快取,而被丟掉。
測試發現(單執行緒訂閱):
用例 | 釋出訊息條數 | 呼叫amqp_comsume_message間隔(MS) | 實際接收條數 |
---|---|---|---|
1 | 630 | 500 | 269 |
2 | 695 | 470 | 269 |
3 | 513 | 460 | 513 |
4 | 503 | 450 | 503 |
三. 訊息大小不要超過4MB
客戶端與RabbitMQ服務端的最大幀是128K,但訊息大小卻可支援數MB,這是可能是因為底層做了拆包組包的,目前我還未檢視底層程式碼。
用執行緒來模擬50個釋出者和50個訂閱者;訊息包大小由1K到10MB,當包大小達到4.5MB時,伺服器的效能出現明顯的異常,傳輸率尤其是每秒訂閱訊息的數量,出現波動,不穩定;同時有一部分訂閱者的TCP連接出現斷開的現象。可能是客戶端底層或者RabbitMQ服務端在進行拆包,組包的時候,出現了明顯的壓力,而導致異常的發生。
- 超過4MB的訊息,最好先進行分包。
第一次修改本節
- 由於用執行緒模擬大量釋出者,且是伺服器單節點,受客戶端主機網絡卡的限制,釋出執行緒沒有速度控制,導致有大量資料傳送,伺服器頻寬下行速率也滿負荷,上行頻寬卻明顯低於下行速率,導致伺服器記憶體有大量訊息堆積,進而觸發RabbitMQ伺服器paging操作,才出現了上述不穩定和訂閱者斷開現象。對釋出端做適當流量控制,斷開連線現象不再出現,但每秒訊息數仍然不穩定。