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ù)據(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)時長荆责,在服務器啟用了maxmemory
功能的情況下滥比,空轉(zhuǎn)時長較大的那些鍵可能會優(yōu)先被服務器刪除。
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
屬性來設定對象所使用的編碼笛钝。而不是為特定類型的對象關(guān)聯(lián)一種固定的編碼质况,極大地提升了Redis
的靈活性,因為Redis可以根據(jù)不同的使用場景來為一個對象設置不同的編碼玻靡,從而優(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
設置生存時間襟士,當key
過期時卿嘲,會被自動刪除慷嗜。
5. EXPIREAT
EXPIREAT key timestamp
EXPIREAT
的作用和EXPIRE
類似淀弹,都用于為key
設置生存時間
不同在于EXPIREAT
命令接受的時間參數(shù)是UNIX
時間戳
6. KEYS
KEYS pattern
查詢所有符合給定模式pattern
的key
KEYS *
匹配數(shù)據(jù)庫中所有的key
KEYS h?llo
匹配hello
, hallo
和hxllo
等
KEYS h*llo
匹配hllo
, heeeeello
等
KEYS h[ae]llo
匹配hello
和hallo
,但不匹配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)部察看給定key
的Redis
對象。
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
命令的作用類似脑漫,但是它以毫秒為單位設置key
的生存時間髓抑,而不像EXPIRE
命令那樣,以秒為單位窿撬。
12. PEXPIREAT
PEXPIREAT key milliseconds-timestamp
這個命令和EXPIREAT
命令類似,但它以毫秒為單位設置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]