Uncaught RedisException: socket error on read socket

NO IMAGE
1 Star2 Stars3 Stars4 Stars5 Stars 給文章打分!
Loading...

問題描述

最近在使用redis的釋出訂閱系統來做公司專案的訊息佇列。一臺伺服器釋出訊息,多臺伺服器訂閱獲取訊息。在系統使用高峰期上午10點左右偶發性的有些伺服器的Redis連結被斷開並報錯:

Uncaught RedisException: socket error on read socket

檢視redis日誌後發現這麼一條錯誤日誌:

Client id=319669 addr=192.168.1.10:52846 fd=83 name= age=534515 idle=1 flags=N db=0 sub=2 psub=0 multi=-1 qbuf=0 qbuf-free=0 obl=0 oll=882 omem=452122 events=rw cmd=subscribe scheduled to be closed ASAP for overcoming of output buffer limits

解決方式

錯誤日誌很明顯的說明對於即將關閉的這個連結有輸出緩衝區的限制。初步判斷是由於傳送訊息的伺服器產生的訊息過多。訂閱的伺服器來不及消費,並達到了系統輸出緩衝區大小的限制。從而關閉了這個連結。谷歌了一下發現redis.conf有如下的限制。

# The client output buffer limits can be used to force disconnection of clients
# that are not reading data from the server fast enough for some reason (a
# common reason is that a Pub/Sub client can't consume messages as fast as the
# publisher can produce them).
#
# The limit can be set differently for the three different classes of clients:
#
# normal -> normal clients including MONITOR clients
# slave  -> slave clients
# pubsub -> clients subscribed to at least one pubsub channel or pattern
#
# The syntax of every client-output-buffer-limit directive is the following:
#
# client-output-buffer-limit <class> <hard limit> <soft limit> <soft seconds>
#
# A client is immediately disconnected once the hard limit is reached, or if
# the soft limit is reached and remains reached for the specified number of
# seconds (continuously).
# So for instance if the hard limit is 32 megabytes and the soft limit is
# 16 megabytes / 10 seconds, the client will get disconnected immediately
# if the size of the output buffers reach 32 megabytes, but will also get
# disconnected if the client reaches 16 megabytes and continuously overcomes
# the limit for 10 seconds.
#
# By default normal clients are not limited because they don't receive data
# without asking (in a push way), but just after a request, so only
# asynchronous clients may create a scenario where data is requested faster
# than it can read.
#
# Instead there is a default limit for pubsub and slave clients, since
# subscribers and slaves receive data in a push fashion.
#
# Both the hard or the soft limit can be disabled by setting them to zero.
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit slave 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60

翻譯一下redis關於輸出緩衝區限制的註釋

# The client output buffer limits can be used to force disconnection of clients
客戶端輸出緩衝區限制可用於強制斷開客戶端
# that are not reading data from the server fast enough for some reason (a
# common reason is that a Pub/Sub client can't consume messages as fast as the
# publisher can produce them).
由於某些原因,不能很快地從伺服器讀取資料(一個常見的原因是,Pub/Sub 客戶端不能像釋出者那樣快速地消耗訊息。)
# The limit can be set differently for the three different classes of clients:
對於三種不同型別的客戶端,可以設定不同的限制:
# normal -> normal clients including MONITOR clients
普通連線 
# slave  -> slave clients
與slave之間的連線
# pubsub -> clients subscribed to at least one pubsub channel or pattern
客戶端訂閱通過普通訂閱或者模式匹配訂閱了至少一個頻道的連結
# The syntax of every client-output-buffer-limit directive is the following:
每個客戶端輸出緩衝區限制指令的語法如下:
# client-output-buffer-limit <class> <hard limit> <soft limit> <soft seconds>
class:表示連結型別
hard:表示允許該連結型別客戶端的輸出快取區大小
soft:跟seconds配合使用,允許在seconds秒內快取區限制的記憶體大小。
seconds:配合soft使用。同上
# A client is immediately disconnected once the hard limit is reached, or if
# the soft limit is reached and remains reached for the specified number of
# seconds (continuously).
一旦達輸出緩衝區的記憶體大小達到了head limit(硬限制) 或者如果輸出緩衝區的記憶體大小達到了soft limit(軟限制)且持續時間達到了
seconds 客戶端立即斷連結
# By default normal clients are not limited because they don't receive data
# without asking (in a push way), but just after a request, so only
# asynchronous clients may create a scenario where data is requested faster
# than it can read
上面吧啦吧啦的一大堆是在說正常的客戶端不受限制,因為它們沒有在不請求的情況下接受資料
(如get命令:傳送一個請求到伺服器端,然後接收伺服器的資料)。
既然正常的客戶端不受限制那麼來看它的預設配置:client-output-buffer-limit normal 0 0 0。
可以看出通通設定為0是不受緩衝區大小的限制。
# Both the hard or the soft limit can be disabled by setting them to zero.
通過設定為零,硬或軟限制都可以被禁用。

總結

通過調整pubsub的快取區的限制可以解決因為客戶端快取區大小限制導致的redis連結斷開的問題。

相關文章

資料庫 最新文章