Redis(二) -- 淺談Redis中的基礎對象

一:摘要概述

Redis中有幾種比較經常使用基礎的對象,本文將會詳細介紹string、hash、list、set、zset對象底層實現數據結構以及它們的常見應用場景與特色redis

二:redisobject

源碼位置位於server.h文件中605行開始算法

typedef struct redisObject {
    unsigned type:4;
    unsigned encoding:4;
    unsigned lru:LRU_BITS;
    int refcount;
    void *ptr;
} robj;

複製代碼

2.1 type

redis中實際的對象類型,分爲5種0-4聲明。位於文件server.h中466行緩存

#define OBJ_STRING 0 /* String object. */
#define OBJ_LIST 1 /* List object. */
#define OBJ_SET 2 /* Set object. */
#define OBJ_ZSET 3 /* Sorted set object. */
#define OBJ_HASH 4 /* Hash object. */

複製代碼

2.2 encoding

redis五種對象string、list、hash、set、zset會用到的八種編碼格式,每一種編碼都對應一個數據結構安全

#define OBJ_ENCODING_RAW 0 
#define OBJ_ENCODING_INT 1 
#define OBJ_ENCODING_HT 2 
#define OBJ_ENCODING_ZIPLIST 5 
#define OBJ_ENCODING_INTSET 6 
#define OBJ_ENCODING_SKIPLIST 7
#define OBJ_ENCODING_EMBSTR 8 
#define OBJ_ENCODING_QUICKLIST 9
複製代碼

2.3 refcount

redis中內存的回收採用了比較簡單的引用計數法進行,每一個對象引用就refcount + 1,當這個引用計數減小爲0時內存就會被回收bash

三:string

3.1 經常使用場景

  • 分佈式鎖:分佈式鎖的實現基礎就是採用string的命令setnx
  • 用戶信息:不少時候用戶信息都會序列化後存到redis中緩存,可是這裏能夠考慮下hash。若是僅僅使用用戶數據部分信息,畢竟序列化與反序列化也是一筆開銷

3.2 編碼格式

  • int:當字符串中全是數字時會採用int編碼,這是真正的二進制數據存儲
  • embstr:內存地址連續,內存一次申請。字符串長度小於44
  • raw:底層採用sds實現,相對於embstr差異在於sds的建立與redisobject的建立分兩次實現

3.3 經常使用命令

# 存儲
set key value

# 互斥存儲
# 已存在的key再次存入數據不會更改緩存
setnx key value

# 過時存儲,單位秒
# 設定key過時時間,到期自動刪除
setex key seconds value

# 過時存儲,單位毫秒
psetex key milliseconds value

# 批量存儲
mset key value [key value ...]

# 取值
get key

# 批量取值
mget key [key ...]

# 追加
append key value

# 長度
strlen key

# 自增,只能是int編碼的字符串
incr key

# 自定義步長自增
incrby key increment

# 自減,只能是int編碼的字符串
# 這個能夠減到負數,秒殺扣減庫存啥的想一想能不能用這個命令
decr key

# 自定義步長自減
decrby key increment
複製代碼

四:list

4.1 經常使用場景

  • 消息隊列:通常不怎麼用,畢竟各類MQ、Kafka都已經很成熟了。並且redis實現消息隊列並不保證數據的安全
  • 排行榜計算:這種僅僅適用於定時計算更新,不能用於實時更新排行。好比美團天天計算區域入駐商家排行
  • 點贊列表:好比微信中的點贊(不知道咋作的,猜一下)

4.2 編碼格式

4.3 相關參數配置

配置參數位置位於redis.con文件中1083行和1099行微信

  • list-max-ziplist-size:配置單個ziplist大小
  • list-compress-depth:配置LZF壓縮算法開始節點

4.4 經常使用命令

# 建立list並壓入節點
# 壓入節點位於鏈表頭
lpush key value

# 壓入節點位於鏈表尾
rpush key value

# 彈出list頭節點
lpop key

# 彈出list尾節點
rpop key

# 刪除節點
# count > 0 從左開始搜索刪除count數量的value
# count < 0 從右開始搜索刪除|count|數量的value
# count = 0 刪除list中全部value
lrem key count value

# 範圍保留
# -1 表示列表最後一個元素
# -2 表示倒數第二個,以此類推
ltrim key start stop

# 計算長度
llen key

# 索引查詢節點
# index < 0 從右開始搜索
# index > 0 從左開始搜索
lindex key index

# 範圍查詢
# stop = -1 表示全部
lrange key start stop

# 阻塞彈出
# 隊列中沒有節點時會一直等待
# 多個key時表示挨着順序依次檢查,知道找到非空列表爲止
# timeout能夠設置等待時間,0表示一直等待
blpop key [key...] timeout
brpop key [key...] timeout
複製代碼

五:Hash

5.1 經常使用場景

  • 商品對象、用戶對象。這個場景須要驗證性對待,若是商品對象、用戶對象信息每次都須要全量的話不妨存string,可是僅僅部分使用就能夠考慮使用hash結構
  • SKU等信息,這個場景下hash就比較合適了。一個hash結構中存儲某個商品全部sku

5.2 編碼格式

  • ziplist:使用ziplist存儲hash結構時一個數據會使用相鄰兩個ziplistEntry存儲field和value
  • hashtable:當數據存儲超過參數限制後就會將其底層結構由ziplist轉換爲dict進行存儲

5.3 相關參數配置

  • hash-max-ziplist-entries:默認512,即ziplist節點爲1024。當節點數量超過該值限制後底層數據結構轉爲dict
  • hash-max-ziplist-value:默認64,當hash中插入任意一個長度超過該限制的value後底層數據結構轉換爲dict

5.4 經常使用命令

# 存儲
hset key field value 

# 不容許更改存儲
# 若field值存在則本次存儲不會覆蓋原有value值
hsetnx key field value

# 批量存儲
hmset key field value [field value ...]

# 查詢
hget key field

# 批量查詢
hmget key field [field ...]

# 全量查詢
hgetall key 

# 全量查詢field值
hkeys key

# 全量查詢value值
hvals key

# 刪除field
hdel key field [field ...]

# 計算鍵值對數量
hlen key
# field存在判斷
hexists key field

# 增量式迭代
# cursor表示迭代開始的遊標
# count 表示迭代返回數據數量
# pattern 表示正則匹配結果限制
hscan key cursor [Count count] [Match pattern]
複製代碼

六:Set

6.1 經常使用場景

  • 推薦:經過sinter命令計算交集,好比美團給你推薦附近外賣時就能夠根據你的外賣記錄與附近商家計算交集推送
  • 安全提示:微信羣成員保存在一個set中,用戶好友也保存在set中。當用戶加入羣聊時能夠提醒非好友用戶注意安全

6.2 編碼格式

  • intset:整數集合,用於存儲set集合中全部value都是整數的數據
  • hashtable:field用於存儲set集合值

6.3 相關參數配置

  • set-max-inset-entries:默認512,表示當元素數量超過限定之後轉換爲hashtable編碼

6.4 經常使用命令

# 存儲
sadd member [member ...]

# 彈出元素並返回
spop key count

# 查詢全部元素
smembers key [count]

# 計算元素數量
scard key 

# 刪除指定元素
srem key member [member ...]

# 判斷元素存在
sismember key member

# 計算給定集合與後續集合差集
# 返回計算結果
sdiff key [key ...]

# 計算給定集合與後續集合差集
# 存儲結果到destination並返回
sdiffstore destination key [key ...]

# 計算給定集合與後續集合交集
# 返回計算結果
sinter key [key ...]

# 計算給定集合與後續集合差集
# 存儲結果到destination並返回
sinterstore destination key [key ...]

# 計算給定集合與後續集合差集
# 返回計算結果
sunion key [key ...]

# 計算給定集合與後續集合差集
# 存儲結果到destination並返回
sunionstore destination key [key ...]
複製代碼

七:Zset

7.1 經常使用場景

  • 排行榜:美團要作一個銷量排行榜,就可使用店家的訂單作score,這個查詢出來的結果就是有序的
  • 權重隊列:score做爲優先級,這樣取出來的數據權重都是最大優先執行的
  • 延時任務:score做爲任務啓動執行時間,取值時判斷該值執行便可

7.2 編碼格式

7.3 相關參數配置

  • zset-max-ziplist-entries:默認值128,指定ziplist存儲元素最多128個。超過轉換爲skiplist
  • zset-max-ziplist-value:默認值64,存儲數據值最大64字節,超過轉換爲skiplist

7.4 經常使用命令

# 存儲
# xx 表示當zset中存在本次插入的member時才存儲
# nx 表示當zset中不存在本次插入的member時才存儲
zadd key [nx|xx] score member [score member ...]

# 查詢排序指定[start,stop]範圍內元素
# withscores 查詢結果順帶返回元素分數
zrange key start stop [withscores]

# 查詢指定元素分數
zscore key member

# 元素數量統計
zcard key

# 返回score位於[min,max]區間的元素數量
zcount key min max 

# 對指定元素分數增長incrment值
zincrby key incrment member

# 返回指定分數區間範圍內元素
# withscores 返回時攜帶分數一塊兒返回
# limit offset count表示跳過offset數量結果再返回count數量結果
zrangebyscore key min max [withscores] [limit offset count]

# 倒序返回指定分數區間範圍內元素
# withscores 返回時攜帶分數一塊兒返回
# limit offset count表示跳過offset數量結果再返回count數量結果
zrevrangebyscore key max min [withrescores] [limit offset count]

# 刪除指定分數範圍[min,max]內元素
zremrangebyscore key min max

# 移除指定元素
zrem key member

複製代碼
相關文章
相關標籤/搜索