天天看點

Redis 源碼學習- Redis指令

Redis指令

redis.h中定了指令的資料結構,并且在redis.c中定義了指令表。

Redis指令資料結構
struct redisCommand {
  
    char *name;

    redisCommandProc *proc;
    
    int arity;
 
    char *sflags;  /* Flags as string representation, one char per flag. */
 
    int flags;  /* The actual flags, obtained from the 'sflags' field. */

    /* Use a function to determine keys arguments in a command line.
     * Used for Redis Cluster redirect. */
    redisGetKeysProc *getkeys_proc;

    int firstkey;  /* The first argument that's a key (0 = no keys) */
    
    int lastkey;  說/* The last argument that's a key */
    
    int keystep;  /* The step between first and last key */

    long long microseconds, calls;
};           
Redis指令表定義
/* 
 * 指令表
 */
 struct redisCommand redisCommandTable[] = {
    {"get",getCommand,2,"r",0,NULL,1,1,1,0,0},
    {"set",setCommand,-3,"wm",0,NULL,1,1,1,0,0},
    ... // 後面的省略
};           
解析

指令的基本結構由指令名稱(name)和實作函數(proc)組成。

arity表示為參數的個數,可以用 -N 表示 >= N。sflags是一個用來表示FLAG的字元串,每個标志一個字元。指令中的FLAG首先是設定在sflags上,之後初始化伺服器時調用redis.c中的populateCommandTable()函數從 sflags 屬性中計算出真正的 FLAG 到 flags 屬性中。

getkeys_proc是從指令中判斷指令的鍵參數。在Redis 叢集轉向時使用。一個可選的函數,用于從指令中取出key參數,僅在以下三個參數都不足以表示key參數時使用。

firstkey為第一個 key 參數的位置;lastkey為最後一個 key 參數的位置;keystep為key參數步長,從 first 參數和 last 參數之間,所有 key 的步數(step)。比如說, MSET 指令的格式為 MSET key value [key value ...],它的 step 就為 2。

microseconds記錄執行這個指令耗費的總微秒數,初始化為 0。calls記錄指令被執行的總次數,初始化為 0。

FLAG含義解析

w: write command (may modify the key space).

寫入指令,可能會修改 key space

r: read command (will never modify the key space).

讀指令,不修改 key space

m: may increase memory usage once called. Don't allow if out of memory.

可能會占用大量記憶體的指令,調用時對記憶體占用進行檢查

a: admin command, like SAVE or SHUTDOWN.

管理用途的指令,比如 SAVE 和 SHUTDOWN

p: Pub/Sub related command.

釋出/訂閱相關的指令

f: force replication of this command, regardless of server.dirty.

無視 server.dirty ,強制複制這個指令。

s: command not allowed in scripts.

不允許在腳本中使用的指令

R: random command. Command is not deterministic, that is, the same command

with the same arguments, with the same key space, may have different results. For instance SPOP and RANDOMKEY are two random commands.

随機指令。指令是非确定性的:對于同樣的指令,同樣的參數,同樣的鍵,結果可能不同。比如 SPOP 和 RANDOMKEY 就是這樣的例子。

S: Sort command output array if called from script, so that the output is deterministic.

如果指令在 Lua 腳本中執行,那麼對輸出進行排序,進而得出确定性的輸出。

l: Allow command while loading the database.

允許在載入資料庫時使用的指令。

t: Allow command while a slave has stale data but is not allowed to server this data. Normally no command is accepted in this condition but just a few.

允許在附屬節點帶有過期資料時執行的指令。

這類指令很少有,隻有幾個。

M: Do not automatically propagate the command on MONITOR.

不要在 MONITOR 模式下自動廣播的指令。

k: Perform an implicit ASKING for this command, so the command will be accepted in cluster mode if the slot is marked as 'importing'.

為這個指令執行一個顯式的ASKING,使得在叢集模式下,一個被标示為importing的槽可以接收這指令。