前言
最近研究下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方法,寫入回復到客戶端