14 Redis如何處理客戶端連線

2021-08-13 05:54:04 字數 2712 閱讀 8989

redis通過在tcp埠上進行監聽,或者unix socket(如果啟用)的方式來接受客戶端的連線。當乙個新的客戶端連線被接受執行以下操作:

如果它因為當前已經接受了最大數量的客戶端,無法接受當前的客戶端,redis將嘗試傳送乙個錯誤給客戶端以便讓其意識到這種情況,並且立即關閉連線。即使連線被redis立即關閉,錯誤資訊也會返回給客戶端,因為新的socket輸出緩衝區一般情況下都足夠放下錯誤資訊,因而客戶端核心將處理連線錯誤。

該順序是由客戶端socket檔案描述符的數字大小及核心報告客戶端事件的順序決定的,因此順序可以看成不確定的。 不過redis給客戶端提供服務時會做以下兩件事:

在redis 2.4中,同時處理的最大客戶端數量的限制是硬編碼的。

在redis 2.6中這個限制是動態的:預設情況下為10000個客戶端,除非在redis.conf中配置了maxclients配置項。

redis通過檢查核心中我們可以開啟的最多的檔案描述符數量,(soft limit被檢查),如果限制小於最大連線客戶端連線數,則加上32(這是redis儲備給內部使用的檔案描述符數量), 接著這個最大連線客戶端的數量將被redis修改為系統要求的值,以便符合在當前作業系統限制下的真正能夠處理的客戶端數量

當配置的最大客戶端數目不起作用時,則日誌將在啟動時顯示,如下面這個例子:

$ ./redis-server --maxclients 100000

[41422] 23 jan 11:28:33.179 # unable to set the max

number

of files limit to

100032 (invalid argument), setting the max clients configuration to

10112.

當redis配置處理客戶的具體數量時,確認作業系統中每個程序檔案描述符的限制也相應地設定成最大值是個好主意。 在linux下這些限制可以在當前的會話設定,用下面的命令在系統範圍內進行設定:

redis需要為每個客戶端處理可變長度的輸出,因為簡單的命令也可能產生乙個需要傳送給客戶端的巨大的資料量。

也可能只是客戶端以較快的速度傳送多個的命令產生的更多的輸出,當客戶端處理新訊息的速度比服務端發給給它的速度還慢時,特別是pub/sub客戶端更是如此。

這兩個原因將導致客戶端輸出緩衝增長及記憶體消耗增多。因為這個原因在預設情況下redis為不同型別的客戶端設定了輸出緩衝限制。當限制到達後客戶端的連線將被關閉,同時事件日誌記錄在redis的日誌檔案中。

redis使用兩種型別的限制:

每乙個客戶端也受到搜尋緩衝限制。這是個不可配置的硬限制,當客戶端搜尋緩衝(這是個我們用來積累客戶端的命令的緩衝)達到1gb的時候它將關閉連線,這只是個極限限制,用來避免當客戶端或者服務端軟體出錯導致伺服器崩潰的情況。

你可以在redis.conf中配置這個限制或者簡單的使用config set timeout 。 記住這個超時時間只適用於多個客戶端並且它不支援pub/sub客戶端, pub/sub連線是推送型別的連線,因而客戶端空閒是正常的。

即使在預設情況下連線是不受超時時間限制的,但是有兩種情況設定超時是有意義的:

關鍵任務應用,客戶端軟體可能因為redis連線飽和而造成出錯,造成服務中斷。

如果乙個客戶端出錯使得伺服器因為空閒連線而飽和,使得無法與伺服器互動,此時可以作為乙個檢錯機制去連線伺服器。

超時並非非常準確:redis避免設定計時器或者執行o(n) 演算法去輪詢檢測客戶端是否超時, 所以檢查是漸近的一部分一部分完成的。這意味著有可能當超時時間設定為10秒,客戶端的連線將在稍晚的時候被關閉,例如當很多客戶端在同一時間連線的話,可能12秒才被關閉。

redis客戶端命令允許檢查所有連線的客戶端的狀態、關掉指定的客戶端的連線、設定連線的名稱。假如你使用一定規模的redis的話這是個很強大的排錯工具

client list命令用來獲得連線的客戶端列表及它們的狀態:

redis 127.0

.0.1:6379> client list

addr=127.0

.0.1:52555 fd=5 name= age=855 idle=0 flags=n db=0

sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=32768 obl=0 oll=0 omem=0 events=r cmd=client

addr=127.0

.0.1:52787 fd=6 name= age=6 idle=5 flags=n db=0

sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=0 obl=0 oll=0 omem=0 events=r cmd=ping

在上面的示例中兩台客戶端都連線到了redis伺服器。一部分有趣的字段的含義如下表所示:

fd:客戶端socket檔案描述符數目。

name:客戶端名稱,由client setname命令設定。

age:連線已經存在了多少秒。

idle:連線已經空閒了幾秒。

flags:客戶端的型別(n代表普通客戶端, 檢視字段完整列表)。

omem:客戶端輸出緩衝占用的記憶體量。

cmd:最後執行的命令。

參考client list文件,檢視完整的字段列表及它們的說明。

當你有了客戶端的列表, 你可以很簡單的使用client kill命令帶上客戶端ip作為引數來關掉連線。

命令client setname和client getname可以用於設定和取得連線的名稱。

客戶端意外掛程式掉,Server如何處理?

這個問題是最近棘手的問題。昨晚查了一下,竟然網上很多人問這個問題的解決方法。tcp通訊中伺服器處理客戶端意外斷開!長期使人困惑的問題 tcp連線中斷的實時檢測 看起來像一篇 感覺比較靠譜 tcp 服務端如何判斷客戶端斷開連線 心跳機制tcp keepalive的討論 應用及 斷網 斷電 檢測的c 實...

如何增大Redis的客戶端連線數?

1 其實你是受到了redis的file descriptor數目限制,這個需要更改redis的原始碼,在ae.h的36行 2.2.4版本 define ae setsize 1024 10 max number of fd supported 2 另外需要注意的是,如果你需要支援更高的連線數,還需要...

如何增大Redis的客戶端連線數?

1 其實你是受到了redis的file descriptor數目限制,這個需要更改redis的原始碼,在ae.h的36行 2.2.4版本 define ae setsize 1024 10 max number of fd supported 2 另外需要注意的是,如果你需要支援更高的連線數,還需要...