深刻了解Redis(4)-類型檢查與命令多態

Redis 中用於操做鍵的命令基本上能夠分爲兩種類型。redis

其中一種命令能夠對任何類型的鍵執行, 好比說 DEL 命令、 EXPIRE 命令、 RENAME 命令、 TYPE 命令、 OBJECT 命令, 等等。數據庫

而另外一種命令只能對特定類型的鍵執行, 好比說:服務器

  • SET 、 GET 、 APPEND 、 STRLEN 等命令只能對字符串鍵執行;
  • HDEL 、 HSET 、 HGET 、 HLEN 等命令只能對哈希鍵執行;
  • RPUSH 、 LPOP 、 LINSERT 、 LLEN 等命令只能對列表鍵執行;
  • SADD 、 SPOP 、 SINTER 、 SCARD 等命令只能對集合鍵執行;
  • ZADD 、 ZCARD 、 ZRANK 、 ZSCORE 等命令只能對有序集合鍵執行;

類型檢查的實現

在執行一個類型特定的命令以前, Redis 會先檢查輸入鍵的類型是否正確, 而後再決定是否執行給定的命令。函數

類型特定命令所進行的類型檢查是經過 redisObject 結構的 type 屬性來實現的:編碼

  • 在執行一個類型特定命令以前, 服務器會先檢查輸入數據庫鍵的值對象是否爲執行命令所需的類型, 若是是的話, 服務器就對鍵執行指定的命令;
  • 不然, 服務器將拒絕執行命令, 並向客戶端返回一個類型錯誤。

舉個例子, 對於 LLEN 命令來講:code

  • 在執行 LLEN 命令以前, 服務器會先檢查輸入數據庫鍵的值對象是否爲列表類型, 也便是, 檢查值對象 redisObject 結構 type 屬性的值是否爲 REDIS_LIST , 若是是的話, 服務器就對鍵執行 LLEN 命令;
  • 不然的話, 服務器就拒絕執行命令並向客戶端返回一個類型錯誤;

過程如圖:對象

多態命令

Redis 除了會根據值對象的類型來判斷鍵是否可以執行指定命令以外, 還會根據值對象的編碼方式, 選擇正確的命令實現代碼來執行命令。blog

舉個例子, 在前面介紹列表對象的編碼時咱們說過, 列表對象有 ziplist 和 linkedlist 兩種編碼可用, 其中前者使用壓縮列表 API 來實現列表命令, 然後者則使用雙端鏈表 API 來實現列表命令。ip

如今, 考慮這樣一個狀況, 若是咱們對一個鍵執行 LLEN 命令, 那麼服務器除了要確保執行命令的是列表鍵以外, 還須要根據鍵的值對象所使用的編碼來選擇正確的 LLEN 命令實現:ci

  • 若是列表對象的編碼爲 ziplist , 那麼說明列表對象的實現爲壓縮列表, 程序將使用 ziplistLen 函數來返回列表的長度;
  • 若是列表對象的編碼爲 linkedlist , 那麼說明列表對象的實現爲雙端鏈表, 程序將使用 listLength 函數來返回雙端鏈表的長度;

借用面向對象方面的術語來講, 咱們能夠認爲 LLEN 命令是多態(polymorphism)的: 只要執行 LLEN 命令的是列表鍵, 那麼不管值對象使用的是 ziplist 編碼仍是 linkedlist 編碼, 命令均可以正常執行。

圖 8-19 展現了 LLEN 命令從類型檢查到根據編碼選擇實現函數的整個執行過程, 其餘類型特定命令的執行過程也是相似的。

相關文章
相關標籤/搜索