問題描述:
最近做的項目用redis訂閱了一個消息,消息的每秒都會發,在我程序運行了一晚上之后,第二天發現消息丟失了,看了日志發現平均2秒丟26條消息。
解決辦法:
在網上找到了這個描述:來自https://blog.csdn.net/luyaoying001/article/details/80264347
使用Redis緩存行情數據,發現程序運行一段時間后,出現subscribe線程不再能夠接收到訂閱的行情數據,發現是由Redis的輸出緩沖機制導致的。
Redis為了解決輸出緩沖區消息大量堆積的隱患,設置了一些保護機制,主要采用兩種限制措施:
- 大小限制,當某一客戶端緩沖區超過設定值后直接關閉連接;
- 持續性限制,當某一客戶端緩沖區持續一段時間占用過大空間時關閉連接。
對於Pub/Sub客戶端(也就是發布/訂閱模式),大小限制是8M,當輸出緩沖區超過8M時,會關閉連接。持續性限制是,當客戶端緩沖區大小持續60秒超過2M,則關閉客戶端連接;
然后發現Redis的發布訂閱是不可靠的,會存在數據丟失的問題。驗證一下是不是上面這個原因,我去查看了日志,看了日志之后發現這個問題是在系統運行了7、8個小時后出現的,經查找發現做的定時刪除沒啟動,從而造成數據量過大,在訂閱事件的處理中,因為數據量過大,拖慢了處理訂閱的消息時間,消息的處理時間超過了1秒。從而導致了消息的延遲,越推時間越長,導致緩沖區過大,最后數據丟失。
個人建議:如果訂閱的消息接收時間間隔短並且數據量過大的情況下,還是不要用這種方式了,如果發布者發送消息過快,而且在這一時刻數據量很大,那么會存在數據丟失問題。
網上給了一種設置緩沖區大小的設置,可以參考一下。
- client-output-buffer-limit pubsub 32mb 8mb 60 #當緩沖區數據達到硬限制32M時,連接會關閉;當緩沖區數據達到軟限制每60秒8M時,連接也會關閉。
- client-output-buffer-limit pubsub 0 0 0 #可將hard limit和soft limit同時置0,關閉該限制。該操作官方不推薦。