小結
-
字串內部編碼:int embstr raw,用途:快取,
-
哈希內部編碼:壓縮ziplist hashtable
-
串列內部編碼:壓縮ziplist linkedlist,用途:訊息佇列,
-
集合內部編碼:intset hashtable,用途:標簽,計算用戶共同感興趣的標簽,sinter user:1:tags user:2:tags
-
有序集合內部編碼:壓縮ziplist 跳躍表zskiplist,用途:熱評的排行榜,zrevrangebyrank user:ranking:2016_0315 0 9
-
Bitmaps用途:通過極小空間進行位運算實作對狀態的判斷,例如可以做一個答題瓜分獎勵的活動,每個用戶答題答對可以設定
setbit user 1 1,然后后用bitcount統計有多少個1,看用戶答對了多少題,
跳躍表
跳躍表支持平均OlogN、最壞ON復雜度的節點查找,
在大部分情況下,跳躍表的效率可以和平衡樹相媲美,Redis使用跳躍表作為有序集合的底層實作之一,
實作
由redis.h/zskiplistNode和redis.h/zskiplist兩個結構定義,zskiplistNode表示跳躍表節點,而zskiplist保存跳躍表
節點的相關資訊,比如節點數量,以及表頭節點和表尾結點的指標,
zskiplist結構:頭結點header,尾結點tail,層數level,長度length,
zskiplistNode結構:層level(層中有前進指標和跨度),后退指標backwrad,分值score,成員物件obj,
SDS簡單動態字串
struct sdshdr {
// 記錄buf陣列中已使用位元組的數量
// 等于SDS所保存字串的長度
int len;
// 記錄buf陣列中未使用位元組的數量
int free;
// 位元組陣列,用于保存字串
char buf[];
}

-
free表示這個SDS沒有分配 未使用空間,
-
len表示SDS保存了無位元組長的字串,
-
buf是一個char陣列,
SDS與C字串區別
-
O(1)復雜度獲取字串長度,
-
防止緩沖區溢位,
-
減少修改字串時帶來的記憶體重分配次數,
字串
命令
set key value [ex seconds] [px milliseconds] [nx|xx]
內部編碼
字串型別的內部編碼有3種:
-
int:8個位元組長整型,
-
embstr:小于等于39個位元組的字串,
-
raw:大于39個位元組的字串,
Redis會根據當前值的型別和長度決定使用哪種內部編碼實作,
整數:
set key 8653
ok
object encoding key
"int"
短字符:
set key "hello"
ok
object encoding key
"embstr"
長字符:
set key "40 bytes"
ok
object encoding key
"raw"
使用場景
-
快取
-
計數
-
Session集中管理
-
限速
哈希
命令
hset key field value
hset uset:1 name tom
hget key field
hget uset:1 name
"tom"
內部編碼
- ziplist(壓縮串列):哈希型別元素個數小于hash-max-ziplist-entries默認512個、同時所有值都小于hash-max-
ziplist-value配置時,Redis會使用ziplist實作,節省記憶體方面比hashtable優秀,
- hashtable:哈希型別無法滿足ziplist條件時,會用這個,hashtable的讀寫時間復雜度都是O(1),
hset hashkey f3 "bigger than 64 bytes"
object encoding hashkey
"hashtable"
hmset hashkey f1 v1 f2 v2 f3 v3 ...... f513 v513
object encoding hashkey
"hashtable"
串列
從右邊插入元素:rpush key value
lrange listkey 0 -1
從左邊插入元素:lpush key value
linsert key before | after pivot value
查找:lrange key start end
洗掉:lpop key
內部編碼
-
ziplist:元素個數小于list-max-ziplist-entries,同時每個值都小于list-max-ziplist-value,Redis選用壓縮串列減少記憶體,
-
linkedlist:無法滿足ziplist就會用鏈表來實作,
使用場景
-
訊息佇列
-
文章串列
集合
用來保存多個的字串元素,不允許重復元素,無序,
sadd key a b c 添加key
3
srem key a b 洗掉key
2
scard key 計算key
1
smembers key 獲取所有元素
sinter key 求交集
suinon key 求并集
sdiff key 求差集
內部編碼
-
intset(整數集合)
-
hashtable
使用場景
標簽(tag)
給用戶添加標簽
sadd user:1:tags tag1 tag2 tag3
sadd uset:1:tags tag1 tag2 tag3
給標簽添加用戶
sadd tag1:users user:1 user:3
sadd tag2:users user:1 user:2
計算用戶共同感興趣的標簽
sinter user:1:tag2 user:2:tag
有序集合
不能重復,可以排序的set,給每個元素設定了一個score作為排序的依據,
串列、集合和有序集合三者異同點

命令
zadd key score member 添加成員
zadd user:ranking 251 tom
有序集合提供排序欄位,產生代價,zadd復雜度為Ologn,sadd為O1,
zcard user:ranking 計算成員數
zscore key member 回傳某個成員分數
zrank key member 計算成員的排名
zrem key member 洗掉成員
zrange ...
集合間的操作
(1)交集
(2)并集
內部編碼
-
壓縮串列
-
跳躍表
使用場景
添加用戶贊數:
zadd user:ranking:2016_03_15 mike 3
獲得贊后:
zincrby user:ranking:2016_03_15 mike 1
取消贊:
zrem
獲取贊數最多的十個用戶:
zrevrangebyrank user:ranking:2016_0315 0 9
展示用戶資訊以及用戶分數:
此功能將用戶名作為鍵后綴,將用戶資訊保存在哈希型別中,至于用戶的分數和排名可以使用zscore和zrank
hgetall user:info:tom
zscore user:ranking:2016_03_15 mike
zrank user:ranking:2016_03_15 mike
Bitmaps
Bitmap通常被用來在極小空間消耗下通過位的運算(AND/OR/XOR/NOT)實作對狀態的判斷,常見的使用場景例如:“答對12道題的同學有機會瓜分獎池”,這種如果使用bitmap來實作,就非常容易判斷出用戶是否全部答對,

答題系統設計如下:
- 每個用戶每輪答題,設定一個key,比如user1在第一輪答題的key是 round:1:user1,
- 每答對一道題,設定相關的bit為1,比如user1答對了第5題,那么就設定第5個bit為1就可以了,如:SETBIT round:1:user1 5 1 ;如果用戶1在第一輪答對了第9題,那么就把第9個bit設定為1,SETBIT round:1:user1 9 1;值得注意的是,Bitmaps默認bit都是0,答錯可以不設定,
- 計算用戶總共答對了幾道題,就可以使用 BITCOUNT 命令統計1的bit個數,
可見,Redis的bitmap介面可以用非常高的存盤效率和計算加速效果,
待更新:
HyperLogLog
GEO
Reference
《Redis設計與實作》
《Redis開發與運維》
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/308490.html
標籤:NoSQL
上一篇:Redis單節點安裝與使用
