目錄
1.引言
2.客戶端屬性
2.1套接字描述符
2.2 name
2.3?客戶端標志
2.4輸入緩沖區(qū)
2.5命令與命令參數
2.6命令實現的函數
2.7輸出緩沖區(qū)
2.8身份驗證
?2.9 時間
3.客戶端的創(chuàng)建的關閉
3.1普通客戶端的創(chuàng)建
?3.2普通客戶端的關閉
3.AOF的偽客戶端
? ?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
1.引言
1.客戶端的套接字描述符。2.客戶端的名字。3.客戶端的標志值(flag)。4.指向客戶端正在使用的數據庫的指針,以及該數據庫的號碼。5.客戶端當前要執(zhí)行的命令、命令的參數、命令參數的個數,以及指向命令實現函數的指針。6.· 客戶端的輸入緩沖區(qū)和輸出緩沖區(qū)。7.· 客戶端的復制狀態(tài)信息,以及進行復制所需的數據結構。8.· 客戶端執(zhí)行 BRPOP 、 BLPOP 等列表阻塞命令時使用的數據結構。9.· 客戶端的事務狀態(tài),以及執(zhí)行 WATCH 命令時用到的數據結構。10.· 客戶端執(zhí)行發(fā)布與訂閱功能時用到的數據結構。11.· 客戶端的身份驗證標志。 · 客戶端的創(chuàng)建時間,客戶端和服務器最后一次通信的時間,以及 客戶端的輸出緩沖區(qū)大小超出軟性限制(soft limit)的時間
2.客戶端屬性
2.1套接字描述符
typedef struct redisClient {
// ...
int fd;
// ...
} redisClient
127.0.0.1:6379[2]> client list
id=2 addr=127.0.0.1:38462 fd=6 name= age=450796 idle=0 flags=N db=2 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=32768 obl=0 oll=0 omem=0 events=r cmd=client
2.2 name
在默認情況下,一個連接到服務器的客戶端是沒有名字的
使用CLIENT setname命令可以為客戶端設置一個名字,讓客戶端的 身份變得更清晰
client setname second
OK
使用client 展現
client list
id=3 addr=127.0.0.1:38502 fd=6 name=second age=136 idle=59 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=0 obl=0 oll=0 omem=0 events=r cmd=client
id=4 addr=127.0.0.1:38504 fd=7 name= age=22 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=second
數據結構
typedef struct redisClient {
// ...
robj *name;
// ...
} redisClient;
如果客戶端沒有為自己設置名字,那么相應客戶端狀態(tài)的name屬性 指向NULL指針;相反地,如果客戶端為自己設置了名字,那么name屬 性將指向一個字符串對象,而該對象就保存著客戶端的名字
下圖示例
2.3?客戶端標志
客戶端的標志屬性flags記錄了客戶端的角色(role),以及客戶端目前所處的狀態(tài):
typedef struct redisClient {
// ...
int flags;
// ...
} redisClient;
標志形態(tài)
flags = <flag>
flags = <flag1> | <flag2> | ...
每個標志使用一個常量表示,一部分標志記錄了客戶端的角色:
·在主從服務器進行復制操作時,主服務器會成為從服務器的客戶 端,而從服務器也會成為主服務器的客戶端。REDIS_MASTER標志表 示客戶端代表的是一個主服務器,REDIS_SLAVE標志表示客戶端代表 的是一個從服務器
2.4輸入緩沖區(qū)
客戶端狀態(tài)的輸入緩沖區(qū)用于保存客戶端發(fā)送的命令請求:
typedef struct redisClient {
// ...
sds querybuf;
// ...
} redisClient;
舉個例子:
SET key value
那么客戶端狀態(tài)的querybuf屬性將是一個包含以下內容的SDS值
*3\r\n$3\r\nSET\r\n$3\r\nkey\r\n$5\r\nvalue\r\n

?
2.5命令與命令參數
在服務器將客戶端發(fā)送的命令請求保存到客戶端狀態(tài)的querybuf屬性之后,服務器將對命令請求的內容進行分析,并將得出的命令參數以及命令參數的個數分別保存到客戶端狀態(tài)的argv屬性和argc屬性

?
2.6命令實現的函數
當服務器從協議內容中分析并得出argv屬性和argc屬性的值之后, 服務器將根據項argv[0]的值,在命令表中查找命令所對應的命令實現函數(repertoire)
下圖展示了一個命令表示例,該表是一個字典,字典的鍵是一個 SDS結構,保存了命令的名字,字典的值是命令所對應的redisCommand 結構,這個結構保存了命令的實現函數、命令的標志、命令應該給定的 參數個數、命令的總執(zhí)行次數和總消耗時長等統(tǒng)計信
?當程序在命令表中成功找到argv[0]所對應的redisCommand結構時, 它會將客戶端狀態(tài)的cmd指針指向這個結構
typedef struct redisClient {
// ...
struct redisCommand *cmd;
// ...
} redisClient;
之后,服務器就可以使用cmd屬性所指向的redisCommand結構,以 及argv、argc屬性中保存的命令參數信息,調用命令實現函數,執(zhí)行客戶端指定的命令
下圖舉例 演示了服務器在argv[0]為"SET"時,查找命令表并將客戶端 狀態(tài)的cmd指針指向目標redisCommand結構的整個過程
?note1?針對命令表的查找操作不區(qū)分輸入字母的大小寫,所以無論argv[0] 是"SET"、"set"、或者"SeT"等等,查找的結果都是相同的
2,7輸出緩沖區(qū)
執(zhí)行命令所得的命令回復會被保存在客戶端狀態(tài)的輸出緩沖區(qū)里 面,每個客戶端都有兩個輸出緩沖區(qū)可用,一個緩沖區(qū)的大小是固定 的,另一個緩沖區(qū)的大小是可變的
1.固定大小的緩沖區(qū)用于保存那些長度比較小的回復,比如OK、簡 短的字符串值、整數值、錯誤回復等等
2.可變大小的緩沖區(qū)用于保存那些長度比較大的回復,比如一個非 常長的字符串值,一個由很多項組成的列表,一個包含了很多元素的集合等等
客戶端的固定大小緩沖區(qū)由buf和bufpos兩個屬性組成
typedef struct redisClient {
// ...
char buf[REDIS_REPLY_CHUNK_BYTES];
int bufpos;
// ...
} redisClient;
buf是一個大小為REDIS_REPLY_CHUNK_BYTES字節(jié)的字節(jié)數組,而bufpos屬性則記錄了buf數組目前已使用的字節(jié)數量。
REDIS_REPLY_CHUNK_BYTES常量目前的默認值為16*1024,也 即是說,buf數組的默認大小為16KB
舉個例子:展現回復一個"OK”
?note2:當buf數組的空間已經用完,或者回復因為太大而沒辦法放進buf數 組里面時,服務器就會開始使用可變大小緩沖區(qū)
可變大小緩沖區(qū)由reply鏈表和一個或多個字符串對象組成:
typedef struct redisClient {
// ...
list *reply;
// ...
} redisClient;
通過使用鏈表來連接多個字符串對象,服務器可以為客戶端保存一 個非常長的命令回復,而不必受到固定大小緩沖區(qū)16KB大小的限制。
?2.8身份驗證
客戶端狀態(tài)的authenticated屬性用于記錄客戶端是否通過了身份驗證:
authenticated屬性僅在服務器啟用了身份驗證功能時使用。如果服 務器沒有啟用身份驗證功能的話,那么即使authenticated屬性的值為 0(這是默認值),服務器也不會拒絕執(zhí)行客戶端發(fā)送的命令請求。 關于服務器身份驗證的更多信息可以參考示例配置文件對 requirepass選項的相關說明
設置密碼
config requirepass 111111
typedef struct redisClient {
// ...
int authenticated;
// ...
} redisClient;
如果authenticated的值為0,那么表示客戶端未通過身份驗證;如果 authenticated的值為1,那么表示客戶端已經通過了身份驗證
舉個例子?對于一個尚未進行身份驗證的客戶端來說,客戶端狀態(tài) 的authenticated屬性
?當客戶端authenticated屬性的值為0時,除了AUTH命令之外,客戶 端發(fā)送的所有其他命令都會被服務器拒絕執(zhí)行
redis> PING
(error) NOAUTH Authentication required.
redis> SET msg "hello world"
(error) NOAUTH Authentication required.
當客戶端通過AUTH命令成功進行身份驗證之后,客戶端狀態(tài) authenticated屬性的值就會從0變?yōu)?
# authenticated
屬性的值從0
變?yōu)?
redis> AUTH 123321
OK
redis> PING
PONG
redis> SET msg "hello world"
Ok
2.9 時間
typedef struct redisClient {
// ...
time_t ctime;
time_t lastinteraction;
time_t obuf_soft_limit_reached_time;
// ...
} redisClient
1.ctime屬性記錄了創(chuàng)建客戶端的時間,這個時間可以用來計算客戶 端與服務器已經連接了多少秒,CLIENT list命令的age域記錄了這個秒 數
2.astinteraction屬性記錄了客戶端與服務器最后一次進行互動 (interaction)的時間,這里的互動可以是客戶端向服務器發(fā)送命令請 求,也可以是服務器向客戶端發(fā)送命令回復。
lastinteraction屬性可以用來計算客戶端的空轉(idle)時間,也即是,距離客戶端與服務器最后一次進行互動以來,已經過去了多少秒, CLIENT list命令的idle域記錄了這個秒數
3.客戶端的創(chuàng)建的關閉
3.1普通客戶端的創(chuàng)建
如果客戶端是通過網絡連接與服務器進行連接的普通客戶端,那么 在客戶端使用connect函數連接到服務器時,服務器就會調用連接事件處 理器,為客戶端創(chuàng)建相應的客戶端狀態(tài),并將這個 新的客戶端狀態(tài)添加到服務器狀態(tài)結構clients鏈表的末尾
舉個例子:假設當前有c1和c2兩個普通客戶端正在連接服務器,那 么當一個新的普通客戶端c3連接到服務器之后,服務器會將c3所對應的 客戶端狀態(tài)添加到clients鏈表的末尾
?3.2普通客戶端的關閉
一個普通客戶端可以因為多種原因而被關閉:
如果客戶端進程退出或者被殺死,那么客戶端與服務器之間的網 絡連接將被關閉,從而造成客戶端被關閉。
·如果客戶端向服務器發(fā)送了帶有不符合協議格式的命令請求,那么這個客戶端也會被服務器關閉。 ·如果客戶端成為了CLIENT KILL命令的目標,那么它也會被關 閉。
·如果用戶為服務器設置了timeout配置選項,那么當客戶端的空轉 時間超過timeout選項設置的值時,客戶端將被關閉。不過timeout選項有 一些例外情況:如果客戶端是主服務器(打開了REDIS_MASTER標 志),從服務器(打開了REDIS_SLAVE標志),正在被BLPOP等命令 阻塞(打開了REDIS_BLOCKED標志),或者正在執(zhí)行SUBSCRIBE、 PSUBSCRIBE等訂閱命令,那么即使客戶端的空轉時間超過了timeout選 項的值,客戶端也不會被服務器關閉。
·如果客戶端發(fā)送的命令請求的大小超過了輸入緩沖區(qū)的限制大小 (默認為1 GB),那么這個客戶端會被服務器關閉。 ·如果要發(fā)送給客戶端的命令回復的大小超過了輸出緩沖區(qū)的限制 大小,那么這個客戶端會被服務器關閉。文章來源:http://www.zghlxwxcb.cn/news/detail-400857.html
3.AOF的偽客戶端
服務器在載入AOF文件時,會創(chuàng)建用于執(zhí)行AOF文件包含的Redis 命令的偽客戶端,并在載入完成之后,關閉這個偽客戶端文章來源地址http://www.zghlxwxcb.cn/news/detail-400857.html
? ?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
到了這里,關于圖解redis的client的實現的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!