redis分析系列之set命令
阿新 • • 發佈:2022-01-28
前言
最近研究下redis原始碼,現在從最基本的命令列操作來分析,redis是如何處理命令操作的
1.redis的set命令操作
我們在redis-cli執行下面的命令
set c c
debug 發現 t_string.c ,執行了void setCommand(client *c)
其中 client 的定義,client 有非常多的引數,現在我們比較關心的是querybuf 引數
typedef struct client {
....
sds querybuf; /* 請求引數 */
} redisClient;
2.命令解析
redis-cli 客戶端執行 set c c 命令後,redis服務會儲存到 client的querybuf 欄位裡面,資料封裝成"*3\r\n$3\r\nset\r\n$1\r\nc\r\n$1\r\nc\r\n"
其中 *3 表示 有3個數據, \r\n 作為分隔符
$3 代表 第一個引數有3個位元組數目,就是 set
$1代表 第二個引數c
3.解析好引數後,最後呼叫setGenericCommand
繼續debug ,發現 key 和value 都會儲存成 robj物件,
robj 定義
typedef struct redisObject {
// 型別 (包含 字串,int 等等)
unsigned type: 4;
// 編碼
unsigned encoding: 4;
int refcount;
void *ptr;//字串地址(通過不同的型別,儲存了不同的指標物件)
} robj;
驗證下,是不是我們剛才提交的 set c c ,其中 key 是 c value 也是 c
列印一下,果然是我們輸入的引數,
繼續 debug,先lookupKeyWrite 查詢key是否存在,然後 setKey 寫入redis的hashtable中,最後傳送通知,寫入回覆 reply
總結
- set 命令是在 t_string.c 檔案的setCommand函式處理的
- key和value 會包裝成 robj 物件
- 判斷是否有過期時間,有的話,會處理 expire ,其中setExpire 會處理過期時間
- setKey函式會寫入redis的hashtable中
- 呼叫notifyKeyspaceEvent 事件通知
- 呼叫addReply方法,寫入回覆到客戶端