節(jié)選自《redis開發(fā)與運維》
先來看一段client list的執(zhí)行結(jié)果
127.0.0.1:6379> client list
id=254487 addr=10.2.xx.234:60240 fd=1311 name= age=8888581 idle=8888581 flags=N
db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=0 obl=0 oll=0 omem=0 events=r cmd=get
id=300210 addr=10.2.xx.215:61972 fd=3342 name= age=8054103 idle=8054103 flags=N
db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=0 obl=0 oll=0 omem=0 events=r cmd=get
輸出結(jié)果的每一行代表一個客戶端的信息仅孩,可以看到每行包含了十幾個屬性胧后,它們是每個客戶端的一些執(zhí)行狀態(tài),理解這些屬性對于Redis的開發(fā)和運維人員非常有幫助。下面將選擇幾個重要的屬性進行說明婿滓,其余通過表格的形式進行展示。
(1)標識:id粥喜、addr凸主、fd、name
這四個屬性屬于客戶端的標識:
·id:客戶端連接的唯一標識额湘,這個id是隨著Redis的連接自增的卿吐,重啟Redis后會重置為0。
·addr:客戶端連接的ip和端口锋华。
·fd:socket的文件描述符嗡官,與lsof命令結(jié)果中的fd是同一個,如果fd=-1代表當前客戶端不是外部客戶端毯焕,而是Redis內(nèi)部的偽裝客戶端衍腥。
·name:客戶端的名字,后面的client setName和client getName兩個命令會對其進行說明纳猫。
(2)輸入緩沖區(qū):qbuf婆咸、qbuf-free
Redis為每個客戶端分配了輸入緩沖區(qū),它的作用是將客戶端發(fā)送的命令臨時保存续担,同時Redis從會輸入緩沖區(qū)拉取命令并執(zhí)行擅耽,輸入緩沖區(qū)為客戶端發(fā)送命令到Redis執(zhí)行命令提供了緩沖功能,如圖4-5所示物遇。
client list中qbuf和qbuf-free分別代表這個緩沖區(qū)的總?cè)萘亢褪S嗳萘浚琑edis沒有提供相應的配置來規(guī)定每個緩沖區(qū)的大小憾儒,輸入緩沖區(qū)會根據(jù)輸入內(nèi)容大小的不同動態(tài)調(diào)整询兴,只是要求每個客戶端緩沖區(qū)的大小不能超過1G,超過后客戶端將被關(guān)閉起趾。下面是Redis源碼中對于輸入緩沖區(qū)的硬編碼:
[圖片上傳失敗...(image-e1b72f-1571740556050)]
/* Protocol and I/O related defines */
#define REDIS_MAX_QUERYBUF_LEN (102410241024) /* 1GB max query buffer. */
輸入緩沖使用不當會產(chǎn)生兩個問題:
·一旦某個客戶端的輸入緩沖區(qū)超過1G诗舰,客戶端將會被關(guān)閉。
·輸入緩沖區(qū)不受maxmemory控制训裆,假設(shè)一個Redis實例設(shè)置了maxmemory為4G眶根,已經(jīng)存儲了2G數(shù)據(jù),但是如果此時輸入緩沖區(qū)使用了3G边琉,已經(jīng)超過maxmemory限制属百,可能會產(chǎn)生數(shù)據(jù)丟失、鍵值淘汰变姨、OOM等情況(如圖4-6所示)族扰。
[圖片上傳失敗...(image-79c38d-1571740556050)]
執(zhí)行效果如下:
127.0.0.1:6390> info memory
# Memory
used_memory_human:5.00G
...
maxmemory_human:4.00G
....
上面已經(jīng)看到,輸入緩沖區(qū)使用不當造成的危害非常大,那么造成輸入緩沖區(qū)過大的原因有哪些渔呵?輸入緩沖區(qū)過大主要是因為Redis的處理速度跟不上輸入緩沖區(qū)的輸入速度怒竿,并且每次進入輸入緩沖區(qū)的命令包含了大量bigkey,從而造成了輸入緩沖區(qū)過大的情況扩氢。還有一種情況就是Redis發(fā)生了阻塞耕驰,短期內(nèi)不能處理命令,造成客戶端輸入的命令積壓在了輸入緩沖區(qū)录豺,造成了輸入緩沖區(qū)過大朦肘。
那么如何快速發(fā)現(xiàn)和監(jiān)控呢?監(jiān)控輸入緩沖區(qū)異常的方法有兩種:
·通過定期執(zhí)行client list命令巩检,收集qbuf和qbuf-free找到異常的連接記錄并分析厚骗,最終找到可能出問題的客戶端。
·通過info命令的info clients模塊兢哭,找到最大的輸入緩沖區(qū)领舰,例如下面命令中的其中client_biggest_input_buf代表最大的輸入緩沖區(qū),例如可以設(shè)置超過10M就進行報警:
127.0.0.1:6379> info clients
# Clients
connected_clients:1414
client_longest_output_list:0
client_biggest_input_buf:2097152
blocked_clients:0
這兩種方法各有自己的優(yōu)劣勢迟螺,表4-3對兩種方法進行了對比冲秽。
表4-3 對比client list和info clients監(jiān)控輸入緩沖區(qū)的優(yōu)劣勢
[圖片上傳失敗...(image-dcc3de-1571740556050)]
輸入緩沖區(qū)問題出現(xiàn)概率比較低,但是也要做好防范矩父,在開發(fā)中要減少bigkey锉桑、減少Redis阻塞、合理的監(jiān)控報警窍株。
(3)輸出緩沖區(qū):obl民轴、oll、omem
Redis為每個客戶端分配了輸出緩沖區(qū)球订,它的作用是保存命令執(zhí)行的結(jié)果返回給客戶端后裸,為Redis和客戶端交互返回結(jié)果提供緩沖,如圖4-7所示冒滩。
與輸入緩沖區(qū)不同的是微驶,輸出緩沖區(qū)的容量可以通過參數(shù)client-output-buffer-limit來進行設(shè)置,并且輸出緩沖區(qū)做得更加細致开睡,按照客戶端的不同分為三種:普通客戶端因苹、發(fā)布訂閱客戶端、slave客戶端篇恒,如圖4-8所示扶檐。
[圖片上傳失敗...(image-5b93ed-1571740556050)]
[圖片上傳失敗...(image-320e63-1571740556050)]
應的配置規(guī)則是:
client-output-buffer-limit
·<class>:客戶端類型,分為三種婚度。a)normal:普通客戶端蘸秘;b)slave:slave客戶端官卡,用于復制;c)pubsub:發(fā)布訂閱客戶端醋虏。
·<hard limit>:如果客戶端使用的輸出緩沖區(qū)大于<hard limit>寻咒,客戶端會被立即關(guān)閉。
·<soft limit>和<soft seconds>:如果客戶端使用的輸出緩沖區(qū)超過了<soft limit>并且持續(xù)了<soft limit>秒颈嚼,客戶端會被立即關(guān)閉毛秘。
Redis的默認配置是:
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit slave 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
和輸入緩沖區(qū)相同的是,輸出緩沖區(qū)也不會受到maxmemory的限制阻课,如果使用不當同樣會造成maxmemory用滿產(chǎn)生的數(shù)據(jù)丟失叫挟、鍵值淘汰、OOM等情況限煞。
實際上輸出緩沖區(qū)由兩部分組成:固定緩沖區(qū)(16KB)和動態(tài)緩沖區(qū)抹恳,其中固定緩沖區(qū)返回比較小的執(zhí)行結(jié)果,而動態(tài)緩沖區(qū)返回比較大的結(jié)果署驻,例如大的字符串奋献、hgetall、smembers命令的結(jié)果等旺上,通過Redis源碼中redis.h的redisClient結(jié)構(gòu)體(Redis3.2版本變?yōu)镃lient)可以看到兩個緩沖區(qū)的實現(xiàn)細節(jié):
typedef struct redisClient {
// 動態(tài)緩沖區(qū)列表 list *reply;
// 動態(tài)緩沖區(qū)列表的長度(對象個數(shù))
unsigned long reply_bytes;
// 固定緩沖區(qū)已經(jīng)使用的字節(jié)數(shù) int bufpos;
// 字節(jié)數(shù)組作為固定緩沖區(qū) char buf[REDIS_REPLY_CHUNK_BYTES];
} redisClient;
固定緩沖區(qū)使用的是字節(jié)數(shù)組瓶蚂,動態(tài)緩沖區(qū)使用的是列表。當固定緩沖區(qū)存滿后會將Redis新的返回結(jié)果存放在動態(tài)緩沖區(qū)的隊列中宣吱,隊列中的每個對象就是每個返回結(jié)果窃这,如圖4-9所示。
[圖片上傳失敗...(image-24b35c-1571740556050)]
client list中的obl代表固定緩沖區(qū)的長度征候,oll代表動態(tài)緩沖區(qū)列表的長度杭攻,omem代表使用的字節(jié)數(shù)。例如下面代表當前客戶端的固定緩沖區(qū)的長度為0疤坝,動態(tài)緩沖區(qū)有4869個對象朴上,兩個部分共使用了133081288字節(jié)=126M內(nèi)存:
id=7 addr=127.0.0.1:56358 fd=6 name= age=91 idle=0 flags=O db=0 sub=0 psub=0 multi=-1
qbuf=0 qbuf-free=0 obl=0 oll=4869 omem=133081288 events=rw cmd=monitor
監(jiān)控輸出緩沖區(qū)的方法依然有兩種:
·通過定期執(zhí)行client list命令,收集obl卒煞、oll、omem找到異常的連接記錄并分析叼架,最終找到可能出問題的客戶端畔裕。
·通過info命令的info clients模塊,找到輸出緩沖區(qū)列表最大對象數(shù)乖订,例如:
127.0.0.1:6379> info clients
# Clients
connected_clients:502
client_longest_output_list:4869
client_biggest_input_buf:0
blocked_clients:0
其中扮饶,client_longest_output_list代表輸出緩沖區(qū)列表最大對象數(shù),這兩種統(tǒng)計方法的優(yōu)劣勢和輸入緩沖區(qū)是一樣的乍构,這里就不再贅述了甜无。相比于輸入緩沖區(qū),輸出緩沖區(qū)出現(xiàn)異常的概率相對會比較大,那么如何預防呢岂丘?方法如下:
·進行上述監(jiān)控陵究,設(shè)置閥值,超過閥值及時處理奥帘。
·限制普通客戶端輸出緩沖區(qū)的铜邮,把錯誤扼殺在搖籃中,例如可以進行如下設(shè)置:
client-output-buffer-limit normal 20mb 10mb 120
·適當增大slave的輸出緩沖區(qū)的寨蹋,如果master節(jié)點寫入較大松蒜,slave客戶端的輸出緩沖區(qū)可能會比較大,一旦slave客戶端連接因為輸出緩沖區(qū)溢出被kill已旧,會造成復制重連秸苗。
·限制容易讓輸出緩沖區(qū)增大的命令,例如运褪,高并發(fā)下的monitor命令就是一個危險的命令惊楼。
及時監(jiān)控內(nèi)存,一旦發(fā)現(xiàn)內(nèi)存抖動頻繁吐句,可能就是輸出緩沖區(qū)過大胁后。
(4)客戶端的存活狀態(tài)
client list中的age和idle分別代表當前客戶端已經(jīng)連接的時間和最近一次的空閑時間:
id=2232080 addr=10.16.xx.55:32886 fd=946 name= age=603382 idle=331060 flags=N db=0
sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=0 obl=0 oll=0 omem=0 events=r cmd=get
例如上面這條記錄代表當期客戶端連接Redis的時間為603382秒,其中空閑了331060秒:
id=254487 addr=10.2.xx.234:60240 fd=1311 name= age=8888581 idle=8888581 flags=N db=0
sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=0 obl=0 oll=0 omem=0 events=r cmd=get
例如上面這條記錄代表當期客戶端連接Redis的時間為8888581秒嗦枢,其中空閑了8888581秒攀芯,實際上這種就屬于不太正常的情況,當age等于idle時文虏,說明連接一直處于空閑狀態(tài)侣诺。
為了更加直觀地描述age和idle,下面用一個例子進行說明:
String key = "hello";
// 1) 生成jedis氧秘,并執(zhí)行g(shù)et操作 Jedis jedis = new Jedis("127.0.0.1", 6379);
System.out.println(jedis.get(key));
// 2) 休息10秒 TimeUnit.SECONDS.sleep(10);
// 3) 執(zhí)行新的操作ping
System.out.println(jedis.ping());
// 4) 休息5秒 TimeUnit.SECONDS.sleep(5);
// 5) 關(guān)閉jedis連接 jedis.close();
下面對代碼中的每一步進行分析年鸳,用client list命令來觀察age和idle參數(shù)的相應變化。
為了與redis-cli的客戶端區(qū)分丸相,本次測試客戶端IP地址:10.7.40.98搔确。
1)在執(zhí)行代碼之前,client list只有一個客戶端灭忠,也就是當前的redis-cli膳算,下面為了節(jié)省篇幅忽略掉這個客戶端。
127.0.0.1:6379> client list
id=45 addr=127.0.0.1:55171 fd=6 name= age=2 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
2)使用Jedis生成了一個新的連接弛作,并執(zhí)行g(shù)et操作涕蜂,可以看到IP地址為10.7.40.98的客戶端,最后執(zhí)行的命令是get映琳,age和idle分別是1秒和0秒:
127.0.0.1:6379> client list
id=46 addr=10.7.40.98:62908 fd=7 name= age=1 idle=0 flags=N db=0 sub=0 psub=0
multi=-1 qbuf=0 qbuf-free=0 obl=0 oll=0 omem=0 events=r cmd=get
3)休息10秒机隙,此時Jedis客戶端并沒有關(guān)閉蜘拉,所以age和idle一直在遞增:
27.0.0.1:6379> client list
id=46 addr=10.7.40.98:62908 fd=7 name= age=9 idle=9 flags=N db=0 sub=0 psub=0
multi=-1 qbuf=0 qbuf-free=0 obl=0 oll=0 omem=0 events=r cmd=get
4)執(zhí)行新的操作ping,發(fā)現(xiàn)執(zhí)行后age依然在增加有鹿,而idle從0計算旭旭,也就是不再閑置:
127.0.0.1:6379> client list
id=46 addr=10.7.40.98:62908 fd=7 name= age=11 idle=0 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
5)休息5秒骤肛,觀察age和idle增加:
127.0.0.1:6379> client list
id=46 addr=10.7.40.98:62908 fd=7 name= age=15 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
6)關(guān)閉Jedis抽减,Jedis連接已經(jīng)消失:
redis-cli client list | grep "10.7.40.98”為空
(5)客戶端的限制maxclients和timeout
Redis提供了maxclients參數(shù)來限制最大客戶端連接數(shù),一旦連接數(shù)超過maxclients脖祈,新的連接將被拒絕年局。maxclients默認值是10000际看,可以通過info clients來查詢當前Redis的連接數(shù):
127.0.0.1:6379> info clients
Clients
connected_clients:1414
...
可以通過config set maxclients對最大客戶端連接數(shù)進行動態(tài)設(shè)置:
127.0.0.1:6379> config get maxclients
"maxclients"
"10000"
127.0.0.1:6379> config set maxclients 50
OK
127.0.0.1:6379> config get maxclients
"maxclients"
"50"
一般來說maxclients=10000在大部分場景下已經(jīng)絕對夠用,但是某些情況由于業(yè)務方使用不當(例如沒有主動關(guān)閉連接)可能存在大量idle連接矢否,無論是從網(wǎng)絡連接的成本還是超過maxclients的后果來說都不是什么好事仲闽,因此Redis提供了timeout(單位為秒)參數(shù)來限制連接的最大空閑時間,一旦客戶端連接的idle時間超過了timeout僵朗,連接將會被關(guān)閉赖欣,例如設(shè)置timeout為30秒:
Redis默認的timeout是0,也就是不會檢測客戶端的空閑 127.0.0.1:6379> config set timeout 30
OK
下面繼續(xù)使用Jedis進行模擬验庙,整個代碼和上面是一樣的顶吮,只不過第2)步驟休息了31秒:
String key = "hello";
// 1) 生成jedis,并執(zhí)行g(shù)et操作 Jedis jedis = new Jedis("127.0.0.1", 6379);
System.out.println(jedis.get(key));
// 2) 休息31秒 TimeUnit.SECONDS.sleep(31);
// 3) 執(zhí)行g(shù)et操作 System.out.println(jedis.get(key));
// 4) 休息5秒 TimeUnit.SECONDS.sleep(5);
// 5) 關(guān)閉jedis連接 jedis.close();
執(zhí)行上述代碼可以發(fā)現(xiàn)在執(zhí)行完第2)步之后粪薛,client list中已經(jīng)沒有了Jedis的連接悴了,也就是說timeout已經(jīng)生效,將超過30秒空閑的連接關(guān)閉掉:
127.0.0.1:6379> client list
id=16 addr=10.7.40.98:63892 fd=6 name= age=19 idle=19 flags=N db=0 sub=0 psub=0
multi=-1 qbuf=0 qbuf-free=0 obl=0 oll=0 omem=0 events=r cmd=get
超過timeout后违寿,Jedis連接被關(guān)閉 redis-cli client list | grep “10.7.40.98”為空
同時可以看到湃交,在Jedis代碼中的第3)步拋出了異常,因為此時客戶端已經(jīng)被關(guān)閉藤巢,所以拋出的異常是JedisConnectionException搞莺,并且提示Unexpected end of stream:
stream: world
Exception in thread "main" redis.clients.jedis.exceptions.JedisConnectionException:
Unexpected end of stream.
如果將Redis的loglevel設(shè)置成debug級別,可以看到如下日志掂咒,也就是客戶端被Redis關(guān)閉的日志:
12885:M 26 Aug 08:46:40.085 - Closing idle client
Redis源碼中redis.c文件中clientsCronHandleTimeout函數(shù)就是針對timeout參數(shù)進行檢驗的才沧,只不過在源碼中timeout被賦值給了server.maxidletime:
int clientsCronHandleTimeout(redisClient *c) {
// 當前時間 time_t now = server.unixtime;
// server.maxidletime就是參數(shù)timeout
if (server.maxidletime &&
// 很多客戶端驗證,這里就不占用篇幅绍刮,最重要的驗證是下面空閑時間超過了maxidletime就會 // 被關(guān)閉掉客戶端 (now - c->lastinteraction > server.maxidletime))
{
redisLog(REDIS_VERBOSE,"Closing idle client");
// 關(guān)閉客戶端 freeClient(c);
}
}
Redis的默認配置給出的timeout=0糜工,在這種情況下客戶端基本不會出現(xiàn)上面的異常,這是基于對客戶端開發(fā)的一種保護录淡。例如很多開發(fā)人員在使用JedisPool時不會對連接池對象做空閑檢測和驗證,如果設(shè)置了timeout>0油坝,可能就會出現(xiàn)上面的異常嫉戚,對應用業(yè)務造成一定影響刨裆,但是如果Redis的客戶端使用不當或者客戶端本身的一些問題,造成沒有及時釋放客戶端連接彬檀,可能會造成大量的idle連接占據(jù)著很多連接資源帆啃,一旦超過maxclients;后果也是不堪設(shè)想窍帝。所在在實際開發(fā)和運維中努潘,需要將timeout設(shè)置成大于0,例如可以設(shè)置為300秒坤学,同時在客戶端使用上添加空閑檢測和驗證等等措施疯坤,例如JedisPool使用common-pool提供的三個屬性:minEvictableIdleTimeMillis、testWhileIdle深浮、timeBetweenEvictionRunsMillis压怠,4.2節(jié)已經(jīng)進行了說明,這里就不再贅述飞苇。
(6)客戶端類型
client list中的flag是用于標識當前客戶端的類型菌瘫,例如flag=S代表當前客戶端是slave客戶端、flag=N代表當前是普通客戶端布卡,flag=O代表當前客戶端正在執(zhí)行monitor命令雨让,表4-4列出了11種客戶端類型。
[圖片上傳失敗...(image-d18643-1571740556050)]
(7)其他
上面已經(jīng)將client list中重要的屬性進行了說明忿等,表4-5列出之前介紹過以及一些比較簡單或者不太重要的屬性栖忠。
表4-5 client list命令結(jié)果的全部屬性
[圖片上傳失敗...(image-bcff52-1571740556050)]
[圖片上傳失敗...(image-4a93ae-1571740556050)]
2.client setName和client getName
client setName xx
client getName
client setName用于給客戶端設(shè)置名字,這樣比較容易標識出客戶端的來源这弧,例如將當前客戶端命名為test_client娃闲,可以執(zhí)行如下操作:
127.0.0.1:6379> client setName test_client
OK
此時再執(zhí)行client list命令,就可以看到當前客戶端的name屬性為test_client:
127.0.0.1:6379> client list
id=55 addr=127.0.0.1:55604 fd=7 name=test_client age=23 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
如果想直接查看當前客戶端的name匾浪,可以使用client getName命令皇帮,例如下面的操作:
127.0.0.1:6379> client getName
"test_client"
client getName和setName命令可以做為標識客戶端來源的一種方式,但是通常來講蛋辈,在Redis只有一個應用方使用的情況下属拾,IP和端口作為標識會更加清晰。當多個應用方共同使用一個Redis冷溶,那么此時client setName可以作為標識客戶端的一個依據(jù)渐白。
3.client kill
client kill ip:port
此命令用于殺掉指定IP地址和端口的客戶端,例如當前客戶端列表為:
127.0.0.1:6379> client list
id=49 addr=127.0.0.1:55593 fd=6 name= age=9 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
id=50 addr=127.0.0.1:52343 fd=7 name= age=4 idle=4 flags=N db=0 sub=0 psub=0
multi=-1 qbuf=0 qbuf-free=0 obl=0 oll=0 omem=0 events=r cmd=get
如果想殺掉127.0.0.1:52343的客戶端逞频,可以執(zhí)行:
127.0.0.1:6379> client kill 127.0.0.1:52343
OK
執(zhí)行命令后纯衍,client list結(jié)果只剩下了127.0.0.1:55593這個客戶端:
127.0.0.1:6379> client list
id=49 addr=127.0.0.1:55593 fd=6 name= age=9 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
由于一些原因(例如設(shè)置timeout=0時產(chǎn)生的長時間idle的客戶端),需要手動殺掉客戶端連接時苗胀,可以使用client kill命令襟诸。
4.client pause
client pause timeout(毫秒)
如圖4-10所示瓦堵,client pause命令用于阻塞客戶端timeout毫秒數(shù),在此期間客戶端連接將被阻塞歌亲。
[圖片上傳失敗...(image-8e7472-1571740556050)]
例如在一個客戶端執(zhí)行:
127.0.0.1:6379> client pause 10000
OK
在另一個客戶端執(zhí)行ping命令菇用,發(fā)現(xiàn)整個ping命令執(zhí)行了9.72秒(手動執(zhí)行redis-cli,只為了演示陷揪,不代表真實執(zhí)行時間):
127.0.0.1:6379> ping
PONG
(9.72s)
該命令可以在如下場景起到作用:
·client pause只對普通和發(fā)布訂閱客戶端有效惋鸥,對于主從復制(從節(jié)點內(nèi)部偽裝了一個客戶端)是無效的,也就是此期間主從復制是正常進行的悍缠,所以此命令可以用來讓主從復制保持一致卦绣。
·client pause可以用一種可控的方式將客戶端連接從一個Redis節(jié)點切換到另一個Redis節(jié)點。
需要注意的是在生產(chǎn)環(huán)境中扮休,暫陀保客戶端成本非常高。
5.monitor
monitor命令用于監(jiān)控Redis正在執(zhí)行的命令玷坠,如圖4-11所示蜗搔,我們打開了兩個redis-cli,一個執(zhí)行set get ping命令八堡,另一個執(zhí)行monitor命令樟凄。可以看到monitor命令能夠監(jiān)聽其他客戶端正在執(zhí)行的命令兄渺,并記錄了詳細的時間戳缝龄。
[圖片上傳失敗...(image-c63b7-1571740556050)]
monitor的作用很明顯,如果開發(fā)和運維人員想監(jiān)聽Redis正在執(zhí)行的命令挂谍,就可以用monitor命令叔壤,但事實并非如此美好,每個客戶端都有自己的輸出緩沖區(qū)口叙,既然monitor能監(jiān)聽到所有的命令炼绘,一旦Redis的并發(fā)量過大,monitor客戶端的輸出緩沖會暴漲妄田,可能瞬間會占用大量內(nèi)存俺亮,圖4-12展示了monitor命令造成大量內(nèi)存使用。
[圖片上傳失敗...(image-c88e14-1571740556050)]