一、Redis簡介
Redis是一款基于key-value的高性能NoSQL資料庫,開源免費,遵守BSD協議,支持string(字串) 、 hash(哈希) 、list(串列) 、 set(集合) 、 zset(有序集合)等資料結構,除此之外還提供了鍵過期、發布訂閱、Lua腳本、事務、流水線(Pipeline)、持久化和主從復制等功能,并通過 Redis 哨兵(Sentinel)和 Redis Cluster(集群)自動磁區提供了高可用性,可用于資料庫、快取和訊息佇列等多種場景,
二、資料結構
Redis 是一個key-value資料庫,即資料存盤是以一個唯一的 key 對應一個 value,value 有 5 種基礎資料結構: string (字串)、 hash (哈希) 、 list (串列)、 set (集合)和 zset (有序集合),
1、string(字串)
string 的值可以是字串(簡單的、以及json、xml格式的)、數字,甚至是二進制資料(圖片、音頻、視頻), 最大能存盤512MB,Redis 的字串是動態的,是可以修改的,當字串長度小于 1M 時,擴容都是加倍現有的空間,如果超過 1M,擴容時一次只會多擴 1M 的空間,
相關命令
(1)設定值與獲取值
set key value 設定指定 key 的值
get key 獲取指定 key 的值
批量設定與獲取
mset key value [key value ...] 同時設定一個或多個 key-value 對,
msetlen key value [key value ...] 同時設定一個或多個 key-value 對,當且僅當所有給定 key 都不存在,
mget key1 [key2..] 獲取所有(一個或多個)給定 key 的值,
從 Redis 2.6.12 開始 set 命令支持一些選項修改其行為:
·ex seconds:設定 key 秒級過期時間,
·px milliseconds:設定 key 毫秒級過期時間,
·nx:只有 key 不存在時,才可以設定成功,
·xx:只有 key 存在時,才可以設定成功,
用法:set key value [ex seconds] [px milliseconds] [nx|xx]
同時redis也有相關命令實作以上行為:
setex key seconds value 將值 value 關聯到 key ,并將 key 的過期時間設為 seconds (以秒為單位),
psetex key milliseconds value 這個命令和 SETEX 命令相似,但它以毫秒為單位設定 key 的生存時間,而不是像 SETEX 命令那樣,以秒為單位,
setnx key value 只有在 key 不存在時設定 key 的值,
由于以上三個命令可以使用 set 命令選項替代,所以可能會被廢棄,并最終被洗掉,
(2)自增自減
incr key 將 key 中儲存的數字值增一,
decr key 將 key 中儲存的數字值減一,
incrby key increment 將 key 所儲存的值加上給定的增量值(increment),
decrby key decrement key 所儲存的值減去給定的減量值(decrement) ,
如果 key 不存在,那么 key 的值會先被初始化為 0 ,然后再執行操作,
如果值包含錯誤的型別,或字串型別的值不能表示為數字,那么回傳一個錯誤,
以上操作的值僅限于 64 位有符號整數,
incrbyfloat key increment 將 key 所儲存的值加上給定的浮點增量值(increment) ,
(3)其他命令
strlen key 回傳 key 所儲存的字串值的長度(實際是位元組長度),
getset key value 將給定 key 的值設為 value ,并回傳 key 的舊值(old value),
append key value 如果 key 已經存在并且是一個字串, APPEND 命令將 value 追加到 key 原來的值的末尾,
setrange key offset value 用 value 引數覆寫給定 key 所儲存的字串值,從偏移量 offset 開始,
getrange key start end 回傳 key 中字串值的子字符,
內部編碼
int:8個位元組的長整型,
embstr:小于等于44個位元組的字串,
raw:大于44個位元組的字串,
應用場景
快取(例如可以將用戶資訊序列化成json字串存盤)、鎖(set nx、setnx)、計數器(incr、incrby、decr、decrby)等
2、hash (哈希)
hash 的值本身又是一個鍵值對結構,如下圖所示,這樣的結構特別適合用于存盤物件,

相關命令
(1)設定與獲取
hset key field value 將哈希表 key 中的欄位 field 的值設為 value ,
hget key field 獲取存盤在哈希表中指定欄位的值
hmset key field1 value1 [field2 value2 ] 同時將多個 field-value (域-值)對設定到哈希表 key 中,
hmget key field1 [field2] 獲取所有給定欄位的值
hgetall key 獲取在哈希表中指定 key 的所有欄位和值
hsetnx key field value 只有在欄位 field 不存在時,設定哈希表欄位的值,
使用hgetall時,如果哈希元素個數比較多,會存在阻塞Redis的可能,這時可以使用hscan命令,該命令會漸進式遍歷哈希結構
hscan key cursor [MATCH pattern] [COUNT count] 迭代哈希表中的鍵值對,
如果要獲取hash 表中所以的欄位或值,可以使用如下命令:
hkeys key 獲取所有哈希表中的欄位
hvals key 獲取哈希表中所有值
(2)自增
hincrby key field increment 為哈希表 key 中的指定欄位的整數值加上增量 increment ,
hincrbyfloat key field increment 為哈希表 key 中的指定欄位的浮點數值加上增量 increment ,
(3)其他命令
hlen key 獲取哈希表中欄位的數量
hexists key field 查看哈希表 key 中,指定的欄位是否存在,
hdel key field2 [field2] 洗掉一個或多個哈希表欄位
當 hash 移除了最后一個元素之后,該資料結構自動被洗掉,記憶體被回收,
內部編碼
·ziplist(壓縮串列):一塊連續的記憶體空間,元素之間沒有任何冗余空隙,比較節省記憶體,
當哈希型別元素個數小于hash-max-ziplist-entries配置(默認512個),且所有值都小于hash-max-ziplist-value配置(默認64位元組)時使用,
·hashtable(哈希表):相對ziplist占用了更多的記憶體,但它的讀寫時間復雜度為O(1),
應用場景
hash 結構也可以用來存盤用戶資訊,不同于 string 結構每次都需要序列化和反序列化(存在一定開銷),hash 可以對每個欄位進行單獨操作,但是 hash 結構使用 hashtable 編碼時會消耗更多記憶體,請根據實際情況取舍,
3、list (串列)
list 串列是簡單的字串串列,按照插入順序排序,每一個字串就是一個元素,元素可以重復,你可以從兩端對串列進行插入和彈出操作,還可以根據索引獲取元素或者指定范圍內的元素,存盤結構如下圖所示

相關命令
(1)添加元素
lpush key value1 [value2] 從串列左邊添加一個或多個元素
rpush key value1 [value2] 從串列右邊添加一個或多個元素
lpushx key value 從串列左邊添加一個或多個元素,串列不存在時操作無效
rpushx key value 從串列右邊添加一個或多個元素,串列不存在時操作無效
linsert key before|after pivot value 在串列中指定元素前或者后插入元素
(2)修改元素
lset key index value 通過索引設定串列元素的值
(3)查找元素
lindex key index 通過索引獲取串列中的元素
lrange key start stop 獲取串列指定范圍內的元素
llen key 獲取串列長度
(4)洗掉元素
lpop key 移出并獲取串列左邊第一個元素
rpop key 移出并獲取串列右邊第一個元素
blpop key1 [key2 ] timeout 移出并獲取串列左邊第一個元素, 如果串列沒有元素會阻塞串列直到等待超時(s)或發現可彈出元素為止,
brpop key1 [key2 ] timeout 移出并獲取串列右邊第一個元素, 如果串列沒有元素會阻塞串列直到等待超時或發現可彈出元素為止,
rpoplpush source destination 移除串列的右邊第一個元素,并將該元素添加到另一個串列的左邊并回傳
brpoplpush source destination timeout 移除串列的右邊第一個元素,并將該元素添加到另一個串列的左邊并回傳; 如果串列沒有元素會阻塞串列直到等待超時或發現可彈出元素為止,
lrem key count value 根據引數 count 的值,移除串列中與引數 value 相等的元素
ltrim key start stop 對一個串列進行修剪(trim),就是說,讓串列只保留指定區間內的元素,不在指定區間之內的元素都將被洗掉,
補充:
blpop和brpop是lpop和rpop的阻塞版本,如果串列為空時,它會等待timeout后回傳,如果timeout=0,客戶端會被一直阻塞直到有新的元素添加進來,串列不為空時客戶端會立即回傳,
lrem命令根據count的不同有三種情況:
·count>0,從左到右,洗掉count個 value 元素,
·count<0,從右到左,洗掉count絕對值個 value 元素,
·count=0,洗掉所有與 value 相同的元素,
當串列彈出了最后一個元素之后,該資料結構自動被洗掉,記憶體被回收,
內部編碼
·ziplist(壓縮串列):當串列的元素個數小于list-max-ziplist-entries配置(默認512個) , 同時串列中每個元素的值都小于list-max-ziplist-value配置時(默認64位元組) 時使用該編碼,
·linkedlist(鏈表):普通的雙向鏈表,帶有prev和next指標,占用了更多的記憶體,獲取某個節點的前置節點和后置節點的復雜度都是O(1),
·quicklist(快速串列):Redis 3.2 版本提供,結合了 ziplist 和 linkedlist 兩者的優勢,之后 list 都采用該編碼,
應用場景
普通佇列(lpush+rpop)、訊息佇列(lpush+brpop)、分頁(lrange)等,
4、set (集合)
set 是一種無序的集合,并且不允許有重復元素,支持多個集合取交集、并集、差集,結構如下

相關命令
(1)添加
sadd key member1 [member2] 向集合添加一個或多個元素,回傳添加成功的個數
(2)洗掉
spop key 洗掉并回傳集合中的一個隨機元素,Redis從3.2版本開始支持[count]引數
srem key member1 [member2] 洗掉集合中一個或多個元素
smove source destination member 將 member 元素從 source 集合移動到 destination 集合
當集合中最后一個元素洗掉之后,資料結構自動洗掉,記憶體被回收,
(3)獲取、查找
scard key 獲取集合的元素個數
smembers key 回傳集合中的所有元素
srandmember key [count] 回傳集合中一個或多個亂數
sismember key member 判斷 member 元素是否是集合 key 的元素
sscan key cursor [MATCH pattern] [COUNT count] 迭代集合中的元素
(4)差集、并集、交集
sdiff key1 [key2] 回傳給定所有集合的差集
sunion key1 [key2] 回傳所有給定集合的并集
sinter key1 [key2] 回傳給定所有集合的交集
sdiffstore destination key1 [key2] 回傳給定所有集合的差集并存盤在 destination 中sinter
sunionstore destination key1 [key2] 所有給定集合的并集存盤在 destination 集合中
sinterstore destination key1 [key2] 回傳給定所有集合的交集并存盤在 destination 中
內部編碼
·intset(整數集合): 一個整數集合, 占用記憶體較少,只能存盤整數型別的資料,當集合中的元素都是整數且元素個數小于set-maxintset-entries配置(默認512個) 時使用,
·hashtable(哈希表):當 intset 編碼無法滿足時使用,
應用場景
打標簽、投票、抽獎、社交(例如共同的好友、微博共同的關注)等,
5、zset (有序集合)
zset 和 set 不同的是每個元素都會關聯一個double型別的分數(score),redis正是通過分數來為集合中的元素進行排序,有序集合的元素同樣不允許重復,但分數(score)卻可以重復,結構如下

相關命令
(1)添加、自增
zadd key score1 member1 [score2 member2] 向有序集合添加一個或多個元素,或者更新已存在元素的分數,被成功添加的新元素的數量,不包括那些被更新的、已經存在的元素,
從 Redis 3.0.2開始,zadd命令可以添加如下選項:
·nx: 元素不存在時才能設定成功,
·xx: 元素存在時才能設定成功,
·ch: 回傳發生變化元素的數量(包括新添加的和被更新的元素)
·incr: 對 score 做增加, 等同于 zincrby 命令,
zincrby key increment member 有序集合中對指定元素的分數加上增量 increment
從 Redis 2.4 版本開始, zadd 命令每次可以添加多個元素
(2)統計數量
zcard key 獲取有序集合的元素數量
zcount key min max 計算在有序集合中指定區間分數的元素數量
zlexcount key min max 在有序集合中計算指定字典區間內元素數量
zlexcount命令說明:
元素名稱前需要加 [ 符號作為開頭, [ 符號與元素之間不能有空格
可以使用 - 和 + 表示得分最小值和最大值
min 和 max 不能反, max 放前面 min放后面會導致回傳結果為0
計算數量時,引數 min 和 max 的位置也計算在內,
(3)查找
zscore key member 回傳有序集中指定元素的分數值
zrangebylex key min max [LIMIT offset count] 通過字典區間回傳有序集合的元素
zrank key member 回傳有序集合中指定元素的索引
zrevrank key member 回傳有序集合(按分數從高到低排序時)中指定元素的索引
zrange key start stop [WITHSCORES] 通過索引區間回傳有序集合成指定區間內的元素
zrevrange key start stop [WITHSCORES] 通過索引區間回傳有序集合成指定區間內的元素,分數從高到底
zrangebyscore key min max [WITHSCORES] [LIMIT offset count] 通過分數回傳有序集合指定區間內的元素
zrevrangebyscore key max min [WITHSCORES] [LIMIT offset count] 通過分數回傳有序集合指定區間內的元素,分數從高到低排序
引數說明:
默認情況下,min和max區間的取值使用閉區間(小于等于或大于等于),你也可以通過給引數前增加“(”符號來使用可選的開區間(小于或大于),min和max也可以是-inf和+inf,代表無限小和無限大,
[LIMIT offset count]:offset代表查找的起始位置,count代表回傳的元素個數
zscan key cursor [MATCH pattern] [COUNT count] 迭代有序集合中的元素(包括元素成員和元素分值)
首次迭代 設定 cursor 為0,再次迭代時以上次回傳的游標為引數
(4)洗掉
zrem key member [member ...] 洗掉有序集合中的一個或多個元素
zremrangebylex key min max 洗掉有序集合中給定的字典區間的所有元素
zremrangebyrank key start stop 洗掉有序集合中給定的索引區間的所有元素
zremrangebyscore key min max 洗掉有序集合中給定的分數區間的所有元素
zset 中最后一個元素被洗掉后,資料結構自動洗掉,記憶體被回收,
(5)交集
zunionstore destination numkeys key [key ...] 計算給定的一個或多個有序集的并集,并存盤在新的 key 中
zinsterstore destination numkeys key [key ...] 計算給定的一個或多個有序集的交集并將結果集存盤在新的有序集合 key 中
內部編碼
·ziplist(壓縮串列):當有序集合的元素個數小于zset-max-ziplistentries配置(默認128個) , 同時每個元素的值都小于zset-max-ziplist-value配置(默認64位元組) 時,
·skiplist(跳躍表): 當 ziplist 編碼無法滿足時使用,
應用場景
排行榜、時間軸、商品推薦等,
其他資料結構
Redis 除了上面五種基礎結構外,還有Bitmaps,HyperLogLog、GEO、Stream四種資料結構,
6、Bitmaps
Bitmaps 實際上不是一種資料結構,它就是字串,但是它可以對字串的位進行操作,可以把Bitmaps 當成一個位陣列來看待,以字母a為例,它的ASCII碼是98,對應的二進制是01100001,Bitmaps 的結構如下:

相關命令
setbit key offset value 對 key 所儲存的字串值,設定或清除指定偏移量上的位(bit)
gitbit key offset 對 key 所儲存的字串值,獲取指定偏移量上的位(bit),
bitcount key [start][end] 計算指定范圍內,被設定為 1 的位元位的數量,
bitpos key bit [start] [end] 回傳位圖中第一個值為 bit(0或1) 的二進制位的位置,
bitop operation destkey key [key …] 對一個或多個保存二進制位的字串 key 進行位元操作,并將結果保存到 destkey 上
operation 可以是 and、 or、 not、 xor這四種操作中的任意一種:
bitop and destkey key [key ...] ,對一個或多個 key 求邏輯并,并將結果保存到 destkey ,
bitop or destkey key [key ...] ,對一個或多個 key 求邏輯或,并將結果保存到 destkey ,
bitop xor destkey key [key ...] ,對一個或多個 key 求邏輯異或,并將結果保存到 destkey ,
bitop not destkey key ,對給定 key 求邏輯非,并將結果保存到 destkey ,
除了 not 操作之外,其他操作都可以接受一個或多個 key 作為輸入,
bitfield key [get type offset] [set type offset value] [incrby type offset increment] [overflow wrap|sat|fail]
該命令詳情請查看:
https://redis.io/commands/bitfield
或http://www.redis.cn/commands/bitfield.html
應用場景
通過資料結構我們發現 bitmaps 適用于存盤 bool 行為的資料,比如統計用戶一年的登錄天數,使用 setbit 命令記錄登錄(比如用戶a第一天登錄了 setbit a 0 1),使用 bitcount 命令統計數量(bitcount a 0 364),時間越久用戶越多,節省存盤空間的效果就越明顯,
7、HyperLogLog
HyperLogLog 是 Redis 2.8.9 添加的資料結構,它是一種用來做基數統計的演算法,可以使用固定且很少的記憶體(每個 HyperLogLog 結構需要12K位元組再加上key本身的幾個位元組)來存盤集合的唯一元素,但是它統計的結果并不是一個精確值,而是一個帶有 0.81% 標準錯誤(standard error)的近似值,HyperLogLog 具有去重功能,
相關命令
pfadd key element [element ...] 添加指定元素到 HyperLogLog 中,
pfcount key [key ...] 回傳給定 HyperLogLog 的基數估算值,
pfmerge destkey sourcekey [sourcekey ...] 將多個 HyperLogLog 合并為一個 HyperLogLog
題外話:命令的開頭 pf 是 HyperLogLog 資料結構發明人 Philippe Flajolet 的首字母縮寫,
應用場景
統計某個網站或某個頁面的UV(只統計總數,不需要絕對準確,也不用知道是誰訪問的),
8、GEO
Redis 3.2 提供了GEO(地理資訊定位) 功能,它的底層實作是zset,
相關命令
geoadd key longitude latitude member [longitude latitude member ...] 將指定的地理空間位置(緯度、經度、名稱)添加到指定的key中
有效的經度介于 -180 度至 180 度之間,
有效的緯度介于 -85.05112878 度至 85.05112878 度之間,
geopos key member [member ...] 從key里回傳所有給定位置元素的位置(經度和緯度)
geodist key member1 member2 [unit] 回傳兩個給定位置之間的距離,
引數unit:
m 表示單位為米(默認),
km 表示單位為千米,
mi 表示單位為英里,
ft 表示單位為英尺,
georadius key longitude latitude radius m|km|ft|mi [withcoord] [withdist]
[withhash] [COUNT count] [asc|desc] [store key] [storedist key]
以給定的經緯度為中心, 回傳鍵包含的位置元素當中, 與中心的距離不超過給定最大距離的所有位置元素,
可選引數:
ithcoord: 回傳結果中包含經緯度,
withdist: 回傳結果中包含離中心節點位置的距離,
withhash: 回傳結果中包含geohash, 有關geohash后面介紹,
COUNT count: 指定回傳結果的數量,
asc|desc: 回傳結果按照離中心節點的距離做升序或者降序,
store key: 將回傳結果的地理位置資訊保存到指定鍵,
storedist key: 將回傳結果離中心節點的距離保存到指定鍵,
georadiusbymember key member radiusm|km|ft|mi [withcoord] [withdist]
[withhash] [COUNT count] [asc|desc] [store key] [storedist key]
同上,只不過他是以指定的成員為中心,
geohash key member [member …] 回傳一個或多個位置元素的 geohash 表示,
9、Stream
Stream 是 Redis 5.0 添加的資料結構,它是一個新的強大的支持多播的可持久化的訊息佇列,借鑒了 Kafka 的設計,我們前面說到 List 結構,它也可以做訊息佇列,但只支持點對點模式,Redis 有一個單獨模塊 PubSub(發布訂閱) 支持訊息多播,但是它不能持久化,Stream 不僅可以持久化,還支持訊息分組、ACK(應答)等功能,由于本人沒有使用過該資料結構,更多內容請參考:https://redis.io/topics/streams-intro或http://www.redis.cn/topics/streams-intro.html
到這里 Redis 的資料結構就介紹完了,更多使用請參考
https://redis.io
http://www.redis.cn
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/29472.html
標籤:NoSQL
下一篇:mongodb 簡單的增刪改查
