天天看點

Redis基礎知識之————如何處理用戶端連接配接redis 連接配接建立 服務端處理順序 redis 最大連接配接數 maxclients 輸出緩沖區大小限制 對于不同用戶端的政策如下 檔案來配置 

      Redis Redis 通過監聽一個 TCP 端口或者 Unix socket 的方式來接收來自用戶端的連接配接,當一個連接配接建立後,Redis 内部會進行以下一些操作: 首先,用戶端 socket 會被設定為非阻塞模式,因為 Redis 在網絡事件處理上采用的是非阻塞多路複用模型。 然後為這個socket 設定 TCP_NODELAY 屬性,禁用 Nagle 算法 然後建立一個 readable 的檔案事件用于監聽這個用戶端 socket 的資料發送 當用戶端連接配接被初始化後,

會檢視目前的連接配接數,然後對比配置好的 maxclients 值,如果目前連接配接數已經達到最大連接配接數 maxclients 了,那麼說明這個連接配接不能再接收,Redis 會直接傳回用戶端一個連接配接錯誤,并馬上關閉掉這個連接配接。

如果有多個用戶端連接配接上 Redis,并且都向 Redis 發送指令,那麼 Redis 服務端會先處理哪個用戶端的請求呢?答案其實并不确定,主要與兩個因素有關,一是用戶端對應的 socket 對應的數字的大小,二是 kernal 報告各個用戶端事件的先後順序。 Redis 處理一個用戶端傳來資料的步驟如下: 它對觸發事件的 socket 調用一次 read(),隻讀一次(而不是把這個 socket 上的消息讀完為止),是為了防止由于某個别用戶端持續發送太多指令,導緻其它用戶端的請求長時間得不到處理的情況。

調用完成後,它裡面無論包含多少個指令,都會被一次性順序地執行。這樣就保證了對各個用戶端指令的公平對待。

在 Redis2.4 中,最大連接配接數是被直接寫死在代碼裡面的,而在2.6版本中這個值變成可配置的。maxclients 的預設值是 10000,你也可以在 redis.conf 中對這個值進行修改。 當然,這個值隻是 Redis 一廂情願的值,Redis 還會照顧到系統本身對程序使用的檔案描述符數量的限制。在啟動時 Redis 會檢查系統的 soft limit,以檢視打開檔案描述符的個數上限。如果系統設定的數字,小于咱們希望的最大連接配接數加32,那麼這個 maxclients 的設定将不起作用,Redis 會按系統要求的來設定這個值。(加32是因為 Redis 内部會使用最多32個檔案描述符,是以連接配接能使用的相當于所有能用的描述符号減32)。 當上面說的這種情況發生時(maxclients 設定後不起作用的情況),Redis 的啟動過程中将會有相應的日志記錄。比如下面指令希望設定最大用戶端數量為100000,是以 Redis 需要 100000+32 個檔案描述符,而系統的最大檔案描述符号設定為10144,是以 Redis 隻能将 maxclients 設定為 10144 – 32 = 10112。

–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. 是以說當你想設定 maxclients 值時,最好順便修改一下你的系統設定,當然,養成看日志的好習慣也能發現這個問題。 具體的設定方法就看你個人的需求了,你可以隻修改此次會話的限制,也可以直接通過sysctl 修改系統的預設設定。如: ulimit -Sn 100000 # This will only work if hard limit is big enough. sysctl -w fs.file-max=100000

對于 Redis 的輸出(也就是指令的傳回值)來說,其大小經常是不可控的,可能是一個簡單的指令,能夠産生體積龐大的傳回資料。另外也有可能因為執行指令太多,産生的傳回資料的速率超過了往用戶端發送的速率,這時也會産生消息堆積,進而造成輸出緩沖區越來越大,占用過多記憶體,甚至導緻系統崩潰。 是以 Redis 設定了一些保護機制來避免這種情況的出現,這些機制作用于不同種類的用戶端,有不同的輸出緩沖區大小限制,限制方式有兩種: 一種是大小限制,當某一個用戶端的緩沖區超過某一大小時,直接關閉掉這個用戶端連接配接 另一種是當某一個用戶端的緩沖區持續一段時間占用空間過大時,也直接關閉掉用戶端連接配接。

對普通用戶端來說,限制為0,也就是不限制,因為普通用戶端通常采用阻塞式的消息應答模式,如:發送請求,等待傳回,再發請求,再等待傳回。這種模式通常不會導緻輸出緩沖區的堆積膨脹。 對于 Pub/Sub 用戶端來說,大小限制是32m,當輸出緩沖區超過32m時,會關閉連接配接。持續性限制是,當用戶端緩沖區大小持續60秒超過8m,也會導緻連接配接關閉。 而對于 Slave 用戶端來說,大小限制是256m,持續性限制是當用戶端緩沖區大小持續60秒超過64m時,關閉連接配接。

上面三種規則都是可配置的。可以通過 CONFIG SET 指令或者修改 redis.conf

輸入緩沖區大小限制 Redis 對輸入緩沖區大小的限制比較暴力,當用戶端傳輸的請求大小超過1G時,服務端會直接關閉連接配接。這種方式可以有效防止一些用戶端或服務端 bug 導緻的輸入緩沖區過大的問題。

Client 逾時

對目前的 Redis 版本來說,服務端預設是不會關閉長期空閑的用戶端的。但是你可以修改預設配置來設定你希望的逾時時間。比如用戶端超過多長時間無互動,就直接關閉。同理,這也可以通過 CONFIG SET 指令或者修改 redis.conf 檔案來配置。

值得注意的是,逾時時間的設定,隻對普通用戶端起作用,對 Pub/Sub 用戶端來說,長期空閑狀态是正常的。

另外,實際的逾時時間可能不會像設定的那樣精确,這是因為 Redis 并不會采用計時器或者輪訓周遊的方法來檢測用戶端逾時,而是通過一種漸近式的方式來完成,每次檢查一部分。是以導緻的結果就是,可能你設定的逾時時間是10s,但是真實執行的時間是逾時12s後用戶端才被關閉。

CLIENT 指令

Redis 的 CLIENT 指令能夠實作三種功能:檢查連接配接的狀态,殺掉某個連接配接以及為連接配接設定名字。

如上面指令的輸出可知,目前此 Redis 有兩個用戶端連接配接,每一行表示一個連接配接的

各項資訊: addr: 用戶端的TCP位址,包括IP和端口 fd: 用戶端連接配接 socket 對應的檔案描述符句柄号 name: 連接配接的名字,預設為空,可以通過 CLIENT SETNAME 設定 age: 用戶端存活的秒數 idle: 用戶端空閑的秒數 flags: 用戶端的類型 (N 表示普通用戶端,更多類型見 http://redis.io/commands/client-list) omem: 輸出緩沖區的大小 cmd: 最後執行的指令名稱

繼續閱讀