8.1 對象

Redis用到的所有主要數(shù)據(jù)結(jié)構(gòu),簡單動態(tài)字符串(SDS)、雙端列表、字典、跳躍表、整數(shù)集合、壓縮列表。
Redis并沒有直接使用這些數(shù)據(jù)結(jié)構(gòu)來實現(xiàn)鍵值對的數(shù)據(jù)庫,而是基于這些數(shù)據(jù)結(jié)構(gòu)創(chuàng)建了一個對象西永,這個系統(tǒng)包含字符串對象、列表對象、哈希對象、集合對象和有序集合對象這五種類型的對象,每中對象都用到了至少一種我們前面所介紹的數(shù)據(jù)結(jié)構(gòu)。
通過這五種不同類型的對象,Redis可以在執(zhí)行命令之前,根據(jù)對象的類型來判斷一個對象是否可以執(zhí)行給定的命令。使用對象的一個好處是,我們可以針對不同的使用場景,為對象設(shè)置多種不同的數(shù)據(jù)結(jié)構(gòu)實現(xiàn),從而優(yōu)化對象在不同場景下的使用效率。
Redis的對象系統(tǒng)還實現(xiàn)了基于引用計數(shù)技術(shù)的內(nèi)存回收機制,當程序不在使用某個對象的時候,這個對象所占用的內(nèi)存就會被自動釋放;另外,Redis還通過引用計數(shù)技術(shù)實現(xiàn)了對象的共享機制,這一機制可以在適當?shù)臈l件下,通過讓多個數(shù)據(jù)庫鍵共享用一個對象來節(jié)約內(nèi)次。
最后,Redis的對象帶有訪問時間記錄信息,該信息可以用于計算數(shù)據(jù)庫鍵的空轉(zhuǎn)時長,在服務(wù)器啟用了maxmemory功能的情況下,空轉(zhuǎn)時長較大的那些鍵可能會優(yōu)先被服務(wù)器刪除。

8.1 對象的類型與編碼

Redis使用對象來表示數(shù)據(jù)庫中的鍵和值,每次當我們在Redis的數(shù)據(jù)庫中新創(chuàng)建一個鍵值對,我們至少創(chuàng)建兩個對象,一個對象用作鍵值對的鍵,另一個對象用作鍵值對的值。
Redis中的每個對象都由一個redisObject結(jié)構(gòu)表示,該結(jié)構(gòu)中和保存數(shù)據(jù)有關(guān)的三個屬性分別是type屬性、encoding屬性和ptr屬性:

typedef struct redisObject{
    //類型
    unsigned type:4;
    //編碼
    unsigned encoding:4;
    //指向底層實現(xiàn)數(shù)據(jù)結(jié)構(gòu)的指針
    void *ptr;
}

8.1.1 類型

對象的type屬性記錄了對象的類型,這個屬性的值如下

類型常量 對象的名稱
REDIS_STRING 字符串對象
REDIS_LIST 列表對象
REDIS_HASH 哈希對象
REDIS_SET 集合對象
REDIS_ZSET 有序結(jié)合對象

對于Redis數(shù)據(jù)庫保存的鍵值對來說,鍵總是一個字符串對象,而值則可以是String, List, Hash, Set, ZSet對象中的其中一個。

TYPE命令:當我們對一個數(shù)據(jù)庫鍵執(zhí)行TYPE命令時,命令返回的結(jié)果為數(shù)據(jù)庫鍵對應的值對象的類型,而不是鍵對象的類型

8.1.2 編碼和底層實現(xiàn)

對象的ptr指針指向?qū)ο蟮牡讓訉崿F(xiàn)數(shù)據(jù)結(jié)構(gòu),而這些數(shù)據(jù)結(jié)構(gòu)由對象的encoding屬性決定。
encoding屬性記錄了對象所使用的編碼,也就是說這個對象上用了什么數(shù)據(jù)結(jié)構(gòu)作為對象的底層實現(xiàn),屬性如下:

編碼常量 編碼所對應的底層數(shù)據(jù)結(jié)構(gòu)
REDIS_ENCODING_INT long類型的整數(shù)
REDIS_ENCODING_EMBSTR embstr編碼的簡單動態(tài)字符串
REDIS_ENCODING_RAW 簡單動態(tài)字符串
REDIS_ENCODING_HT 字典
REDIS_ENCODING_LINKEDLIST 雙端列表
REDIS_ENCODING_ZIPLIST 壓縮列表
REDIS_ENCODING_INTSET 整數(shù)集合
REDIS_ENCODING_SKIPLIST 跳躍表

每種類型的對象都至少使用了兩種不同的編碼

類型 編碼 對象
REDIS_STRING REDIS_ENCODING_INT 使用整數(shù)值實現(xiàn)的字符串對象
REDIS_STRING REDIS_ENCODING_EMBSTR 使用embstr編碼的簡單動態(tài)字符串實現(xiàn)的字符串對象
REDIS_STRING REDIS_ENCODING_RAW 使用簡單動態(tài)字符串實現(xiàn)的字符串對象
REDIS_LIST REDIS_ENCODING_ZIPLIST 使用壓縮列表實現(xiàn)的列表對象
REDIS_LIST REDIS_ENCODING_LINKEDLIST 使用雙端列表實現(xiàn)的列表對象
REDIS_HASH REDIS_ENCODING_ZIPLIST 使用壓縮列表實現(xiàn)的哈希對象
REDIS_HASH REDIS_ENCODING_HT 使用字典實現(xiàn)的哈希對象
REDIS_SET REDIS_ENCODING_INTSET 使用整數(shù)集合實現(xiàn)的集合對象
REDIS_SET REDIS_ENCODING_HT 使用字典實現(xiàn)的集合對象
REDIS_ZSET REDIS_ENCODING_ZIPLIST 使用壓縮列表實現(xiàn)的有序集合對象
REDIS_ZSET REDIS_ENCODING_SKIPLIST 使用跳躍表實現(xiàn)的有序集合對象

OBJECT ENCODING命令:可以查看一個數(shù)據(jù)庫鍵的值對象的編碼:

通過encoding屬性來設(shè)定對象所使用的編碼。而不是為特定類型的對象關(guān)聯(lián)一種固定的編碼,極大地提升了Redis的靈活性,因為Redis可以根據(jù)不同的使用場景來為一個對象設(shè)置不同的編碼,從而優(yōu)化對象在某一場景下的效率。

8.1.3 Key(鍵)命令

1. DEL
DEL key [key ...]

刪除給定的一個或多個key
不存在的key會被忽略

2. DUMP
DUMP key

序列化給定key,并返回被序列化的值,使用RESTORE命令可以將這個值反序列化為Redis
序列化生成的值有以下幾個特點:

  • 帶有64為的校驗和,用于檢測錯誤,RESTORE在進行反序列化之前會先檢查校驗和。
  • 值的編碼格式和RDB文件保持一致。
  • RDB版本會編碼在序列化值當眾,如果因為Redis的版本不同造成RDB格式不兼容,那么Redis會拒絕為這個值進行反序列操作。
    序列化的值不包括任何生存時間信息。
3. EXISTS
EXISTS key

檢查給定的key是否存在

4. EXPIRE
EXPIRE key seconds

為給定的key設(shè)置生存時間,當key過期時,會被自動刪除。

5. EXPIREAT
EXPIREAT key timestamp

EXPIREAT的作用和EXPIRE類似,都用于為key設(shè)置生存時間
不同在于EXPIREAT命令接受的時間參數(shù)是UNIX時間戳

6. KEYS
KEYS pattern

查詢所有符合給定模式patternkey
KEYS * 匹配數(shù)據(jù)庫中所有的key
KEYS h?llo匹配hello, hallohxllo
KEYS h*llo匹配hllo, heeeeello
KEYS h[ae]llo匹配hellohallo,但不匹配hillo

7. MIGRATE
MIGRATE host port key destination-db timeout [COPY] [REPLACE]

key原子性地從當前實例傳送到目標實例的指定數(shù)據(jù)庫上,一旦傳送成功,key保證會出現(xiàn)在目標實例上,而當前實例上的key會被刪除。
這個命令是一個原子操作,它在執(zhí)行的時候會阻塞進行遷移的兩個實例,直到以下任意結(jié)果發(fā)生:遷移成功,遷移失敗,等待超時。
命令的內(nèi)部實現(xiàn)是這樣的:它在當前實例對給定key執(zhí)行DUMP命令 ,將它序列化,然后傳送到目標實例,目標實例再使用RESTORE對數(shù)據(jù)進行反序列化,并將反序列化所得的數(shù)據(jù)添加到數(shù)據(jù)庫中;當前實例就像目標實例的客戶端那樣,只要看到RESTORE命令返回OK,它就會調(diào)用DEL刪除自己數(shù)據(jù)庫上的key。
timeout參數(shù)以毫秒為格式,指定當前實例和目標實例進行溝通的最大間隔時間。這說明操作并不一定要在timeout毫秒內(nèi)完成,只是說數(shù)據(jù)傳送的時間不能超過這個timeout數(shù)。
MIGRATE命令需要在給定的時間規(guī)定內(nèi)完成IO操作。如果在傳送數(shù)據(jù)時發(fā)生IO錯誤,或者達到了超時時間,那么命令會停止執(zhí)行,并返回一個特殊的錯誤:IOERR
IOERR出現(xiàn)時,有以下兩種可能:

  • key可能存在于兩個實例
  • key可能只存在于當前實例
    唯一不可能發(fā)生的情況就是丟失key,因此,如果一個客戶端執(zhí)行MIGRATE命令,并且不幸遇上IOERR錯誤,那么這個客戶端唯一要做的就是檢查自己數(shù)據(jù)庫上的key是否已經(jīng)被正確地刪除。
  • COPY:不移除源實例上的key。
  • REPLACE:替換目標實例上已存在的key。
8. MOVE
MOVE key db

將當前數(shù)據(jù)庫的key移動到給定的數(shù)據(jù)庫db當中。
如果當前數(shù)據(jù)庫(源數(shù)據(jù)庫)和給定數(shù)據(jù)庫(目標數(shù)據(jù)庫)有相同名字的給定key,或者key不存在于當前數(shù)據(jù)庫,那么MOVE沒有任何效果。
因此,也可以利用這一特性,將MOVE當作鎖(locking)原語(primitive)。

9. OBJECT
OBJECT subcommand [arguments [arguments]]

OBJECT命令允許從內(nèi)部察看給定keyRedis對象。
OBJECT命令有多個子命令:
OBJECT REFCOUNT <key>返回給定key引用所儲存的值的次數(shù)。此命令主要用于除錯。
OBJECT ENCODING <key>返回給定key鎖儲存的值所使用的內(nèi)部表示(representation)。
OBJECT IDLETIME <key>返回給定key自儲存以來的空閑時間(idle, 沒有被讀取也沒有被寫入),以秒為單位。

10. PERSIST
PERSIST key

移除給定key的生存時間,將這個key從『易失的』(帶生存時間key)轉(zhuǎn)換成『持久的』(一個不帶生存時間、永不過期的key)。

11. PEXPIRE
PEXPIRE key milliseconds

這個命令和EXPIRE命令的作用類似,但是它以毫秒為單位設(shè)置key的生存時間,而不像EXPIRE命令那樣,以秒為單位。

12. PEXPIREAT
PEXPIREAT key milliseconds-timestamp

這個命令和EXPIREAT命令類似,但它以毫秒為單位設(shè)置key的過期unix時間戳,而不是像EXPIREAT那樣,以秒為單位。

13. PTTL
PTTL key

這個命令類似于TTL命令,但它以毫秒為單位返回key的剩余生存時間,而不是像TTL命令那樣,以秒為單位。

14. RANDOMKEY
RANDOMKEY

從當前數(shù)據(jù)庫中隨機返回(不刪除)一個key。

15. RENAME
RENAME key newkey

key改名為newkey
key 和newkey相同,或者key不存在時,返回一個錯誤。 當newkey已經(jīng)存在時,RENAME`命令將覆蓋舊值。

16. RENAMENX
RENAMENX key newkey

當且僅當newkey不存在時,將key改名為newkey
key不存在時,返回一個錯誤。

17. RESTORE
RESTORE key ttl serialized-value [REPLACE]

反序列化給定的序列化值,并將它和給定的key關(guān)聯(lián)。

18. SORT
SORT key [BY pattern] [LIMIT offset count] [GET pattern [GET pattern ...]] [ASC | DESC] [ALPHA] [STORE destination]

返回或保存給定列表、集合、有序集合key中經(jīng)過排序的元素。
排序默認以數(shù)字作為對象,值被解釋為雙精度浮點數(shù),然后進行比較。

19. TTL
TTL key

以秒為單位,返回給定key的剩余生存時間(TTL, time to live)。

20. TYPE
TYPE key

返回key所儲存的值的類型。
返回值:

  • none (key不存在)
  • string (字符串)
  • list (列表)
  • set (集合)
  • zset (有序集)
  • hash (哈希表)
21. SCAN
SCAN cursor [MATCH pattern] [COUNT count]

參考:http://redisdoc.com/key/scan.html

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容