自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

干貨分享:Redis如何處理客戶端連接?

運(yùn)維 系統(tǒng)運(yùn)維 Redis
edis是一個(gè)key-value存儲(chǔ)系統(tǒng)。本文主要介紹了Redis處理客戶端連接的一些內(nèi)部實(shí)現(xiàn)機(jī)制,包括連接處理、超時(shí)、緩沖區(qū)等一系列內(nèi)容。

本文主要介紹了 Redis 處理客戶端連接的一些內(nèi)部實(shí)現(xiàn)機(jī)制,包括連接處理、超時(shí)、緩沖區(qū)等一系列內(nèi)容。(注:本文所述內(nèi)容基于 Redis2.6 及以上版本。)

連接的建立

Redis通過(guò)監(jiān)聽(tīng)一個(gè) TCP 端口或者 Unix socket 的方式來(lái)接收來(lái)自客戶端的連接,當(dāng)一個(gè)連接建立后,Redis 內(nèi)部會(huì)進(jìn)行以下一些操作:

  • 首先,客戶端 socket 會(huì)被設(shè)置為非阻塞模式,因?yàn)?Redis 在網(wǎng)絡(luò)事件處理上采用的是非阻塞多路復(fù)用模型。
  • 然后為這個(gè)socket 設(shè)置 TCP_NODELAY 屬性,禁用 Nagle 算法
  • 然后創(chuàng)建一個(gè) readable 的文件事件用于監(jiān)聽(tīng)這個(gè)客戶端 socket 的數(shù)據(jù)發(fā)送

當(dāng)客戶端連接被初始化后,Redis 會(huì)查看目前的連接數(shù),然后對(duì)比配置好的 maxclients 值,如果目前連接數(shù)已經(jīng)達(dá)到***連接數(shù) maxclients 了,那么說(shuō)明這個(gè)連接不能再接收,Redis 會(huì)直接返回客戶端一個(gè)連接錯(cuò)誤,并馬上關(guān)閉掉這個(gè)連接。

服務(wù)端處理順序

如果有多個(gè)客戶端連接上 Redis,并且都向 Redis 發(fā)送命令,那么 Redis 服務(wù)端會(huì)先處理哪個(gè)客戶端的請(qǐng)求呢?答案其實(shí)并不確定,主要與兩個(gè)因素有關(guān),一是客戶端對(duì)應(yīng)的 socket 對(duì)應(yīng)的數(shù)字的大小,二是 kernal 報(bào)告各個(gè)客戶端事件的先后順序。

Redis 處理一個(gè)客戶端傳來(lái)數(shù)據(jù)的步驟如下:

  • 它對(duì)觸發(fā)事件的 socket 調(diào)用一次 read(),只讀一次(而不是把這個(gè) socket 上的消息讀完為止),是為了防止由于某個(gè)別客戶端持續(xù)發(fā)送太多命令,導(dǎo)致其它客戶端的請(qǐng)求長(zhǎng)時(shí)間得不到處理的情況。
  • 當(dāng)然,當(dāng)這一次 read() 調(diào)用完成后,它里面無(wú)論包含多少個(gè)命令,都會(huì)被一次性順序地執(zhí)行。這樣就保證了對(duì)各個(gè)客戶端命令的公平對(duì)待。

關(guān)于***連接數(shù) maxclients

在 Redis2.4 中,***連接數(shù)是被直接硬編碼在代碼里面的,而在2.6版本中這個(gè)值變成可配置的。maxclients 的默認(rèn)值是 10000,你也可以在 redis.conf 中對(duì)這個(gè)值進(jìn)行修改。

當(dāng)然,這個(gè)值只是 Redis 一廂情愿的值,Redis 還會(huì)照顧到系統(tǒng)本身對(duì)進(jìn)程使用的文件描述符數(shù)量的限制。在啟動(dòng)時(shí) Redis 會(huì)檢查系統(tǒng)的 soft limit,以查看打開(kāi)文件描述符的個(gè)數(shù)上限。如果系統(tǒng)設(shè)置的數(shù)字,小于咱們希望的***連接數(shù)加32,那么這個(gè) maxclients 的設(shè)置將不起作用,Redis 會(huì)按系統(tǒng)要求的來(lái)設(shè)置這個(gè)值。(加32是因?yàn)?Redis 內(nèi)部會(huì)使用最多32個(gè)文件描述符,所以連接能使用的相當(dāng)于所有能用的描述符號(hào)減32)。

當(dāng)上面說(shuō)的這種情況發(fā)生時(shí)(maxclients 設(shè)置后不起作用的情況),Redis 的啟動(dòng)過(guò)程中將會(huì)有相應(yīng)的日志記錄。比如下面命令希望設(shè)置***客戶端數(shù)量為100000,所以 Redis 需要 100000+32 個(gè)文件描述符,而系統(tǒng)的***文件描述符號(hào)設(shè)置為10144,所以 Redis 只能將 maxclients 設(shè)置為 10144 – 32 = 10112。

$ ./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.

所以說(shuō)當(dāng)你想設(shè)置 maxclients 值時(shí),***順便修改一下你的系統(tǒng)設(shè)置,當(dāng)然,養(yǎng)成看日志的好習(xí)慣也能發(fā)現(xiàn)這個(gè)問(wèn)題。

具體的設(shè)置方法就看你個(gè)人的需求了,你可以只修改此次會(huì)話的限制,也可以直接通過(guò)sysctl 修改系統(tǒng)的默認(rèn)設(shè)置。如:

ulimit -Sn 100000 # This will only work if hard limit is big enough.
sysctl -w fs.file-max=100000

輸出緩沖區(qū)大小限制

對(duì)于 Redis 的輸出(也就是命令的返回值)來(lái)說(shuō),其大小經(jīng)常是不可控的,可能是一個(gè)簡(jiǎn)單的命令,能夠產(chǎn)生體積龐大的返回?cái)?shù)據(jù)。另外也有可能因?yàn)閳?zhí)行命令太多,產(chǎn)生的返回?cái)?shù)據(jù)的速率超過(guò)了往客戶端發(fā)送的速率,這時(shí)也會(huì)產(chǎn)生消息堆積,從而造成輸出緩沖區(qū)越來(lái)越大,占用過(guò)多內(nèi)存,甚至導(dǎo)致系統(tǒng)崩潰。

所以 Redis 設(shè)置了一些保護(hù)機(jī)制來(lái)避免這種情況的出現(xiàn),這些機(jī)制作用于不同種類的客戶端,有不同的輸出緩沖區(qū)大小限制,限制方式有兩種:

  • 一種是大小限制,當(dāng)某一個(gè)客戶端的緩沖區(qū)超過(guò)某一大小時(shí),直接關(guān)閉掉這個(gè)客戶端連接
  • 另一種是當(dāng)某一個(gè)客戶端的緩沖區(qū)持續(xù)一段時(shí)間占用空間過(guò)大時(shí),也直接關(guān)閉掉客戶端連接

對(duì)于不同客戶端的策略如下:

  • 對(duì)普通客戶端來(lái)說(shuō),限制為0,也就是不限制,因?yàn)槠胀蛻舳送ǔ2捎米枞降南?yīng)答模式,如:發(fā)送請(qǐng)求,等待返回,再發(fā)請(qǐng)求,再等待返回。這種模式通常不會(huì)導(dǎo)致輸出緩沖區(qū)的堆積膨脹。
  • 對(duì)于 Pub/Sub 客戶端來(lái)說(shuō),大小限制是32m,當(dāng)輸出緩沖區(qū)超過(guò)32m時(shí),會(huì)關(guān)閉連接。持續(xù)性限制是,當(dāng)客戶端緩沖區(qū)大小持續(xù)60秒超過(guò)8m,也會(huì)導(dǎo)致連接關(guān)閉。
  • 而對(duì)于 Slave 客戶端來(lái)說(shuō),大小限制是256m,持續(xù)性限制是當(dāng)客戶端緩沖區(qū)大小持續(xù)60秒超過(guò)64m時(shí),關(guān)閉連接。

上面三種規(guī)則都是可配置的??梢酝ㄟ^(guò) CONFIG SET 命令或者修改 redis.conf 文件來(lái)配置。

輸入緩沖區(qū)大小限制

Redis 對(duì)輸入緩沖區(qū)大小的限制比較暴力,當(dāng)客戶端傳輸?shù)恼?qǐng)求大小超過(guò)1G時(shí),服務(wù)端會(huì)直接關(guān)閉連接。這種方式可以有效防止一些客戶端或服務(wù)端 bug 導(dǎo)致的輸入緩沖區(qū)過(guò)大的問(wèn)題。

Client 超時(shí)

對(duì)當(dāng)前的 Redis 版本來(lái)說(shuō),服務(wù)端默認(rèn)是不會(huì)關(guān)閉長(zhǎng)期空閑的客戶端的。但是你可以修改默認(rèn)配置來(lái)設(shè)置你希望的超時(shí)時(shí)間。比如客戶端超過(guò)多長(zhǎng)時(shí)間無(wú)交互,就直接關(guān)閉。同理,這也可以通過(guò) CONFIG SET 命令或者修改 redis.conf 文件來(lái)配置。

值得注意的是,超時(shí)時(shí)間的設(shè)置,只對(duì)普通客戶端起作用,對(duì) Pub/Sub 客戶端來(lái)說(shuō),長(zhǎng)期空閑狀態(tài)是正常的。

另外,實(shí)際的超時(shí)時(shí)間可能不會(huì)像設(shè)定的那樣精確,這是因?yàn)?Redis 并不會(huì)采用計(jì)時(shí)器或者輪訓(xùn)遍歷的方法來(lái)檢測(cè)客戶端超時(shí),而是通過(guò)一種漸近式的方式來(lái)完成,每次檢查一部分。所以導(dǎo)致的結(jié)果就是,可能你設(shè)置的超時(shí)時(shí)間是10s,但是真實(shí)執(zhí)行的時(shí)間是超時(shí)12s后客戶端才被關(guān)閉。

CLIENT 命令

Redis 的 CLIENT 命令能夠?qū)崿F(xiàn)三種功能:檢查連接的狀態(tài),殺掉某個(gè)連接以及為連接設(shè)置名字。

CLIENT LIST 命令能夠獲取當(dāng)前所有客戶端的狀態(tài),使用方法如下:

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 有兩個(gè)客戶端連接,每一行表示一個(gè)連接的各項(xiàng)信息:

  • addr: 客戶端的TCP地址,包括IP和端口
  • fd: 客戶端連接 socket 對(duì)應(yīng)的文件描述符句柄號(hào)
  • name: 連接的名字,默認(rèn)為空,可以通過(guò) CLIENT SETNAME 設(shè)置
  • age: 客戶端存活的秒數(shù)
  • idle: 客戶端空閑的秒數(shù)
  • flags: 客戶端的類型 (N 表示普通客戶端,更多類型見(jiàn) http://redis.io/commands/client-list)
  • omem: 輸出緩沖區(qū)的大小
  • cmd: ***執(zhí)行的命令名稱

你可以查看CLIENT LIST的文檔來(lái)具體查看所有輸出的含義。

當(dāng)你通過(guò)上面命令獲取到客戶端列表后,就可以通過(guò) CLIENT KILL 命令來(lái)殺死指定的連接了。CLIENT KILL 的參數(shù)就是上面的 addr 值。

如上面提到的 CLIENT SETNAME 和 CLIENT GETNAME 可以用來(lái)為一個(gè)連接設(shè)置一個(gè)名字。

責(zé)任編輯:黃丹 來(lái)源: nosqlfan.com
相關(guān)推薦

2009-12-22 18:18:11

WCF客戶端編程

2024-05-29 07:30:41

2020-11-17 08:53:07

MySQL數(shù)據(jù)庫(kù)技術(shù)

2010-02-22 11:10:17

WCF獲取客戶端IP

2009-12-22 10:29:59

WCF客戶端處理

2021-06-22 15:06:13

Redis客戶端 Redis-clie

2013-03-13 10:51:44

瘦客戶端VDI

2021-08-06 10:37:34

ElasticOpenSearch開(kāi)發(fā)者

2020-03-24 15:15:29

HttpClientOkHttpJava

2010-12-31 14:23:57

Exchange Se

2017-05-24 08:58:16

HiveServer界面工具

2010-02-24 16:39:27

WCF客戶端處理

2010-09-29 15:05:44

DHCP客戶端故障

2011-08-17 10:10:59

2021-09-22 15:46:29

虛擬桌面瘦客戶端胖客戶端

2009-08-21 15:36:41

服務(wù)端與客戶端

2009-08-21 15:54:40

服務(wù)端與客戶端

2010-12-17 10:16:33

OpenVAS

2009-02-16 18:50:08

WindowsXmanagerLinux

2010-05-31 10:11:32

瘦客戶端
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)