Redis五種基本數據結構
在學習String,Hash基本數據結構之前,我們先來了解一下Redis的五種基本類型的框架。
五種類型的框架
String類型的使用場景:(針對於實體對象)
1. 單值緩存
set key value //存儲值
get key // 獲取值
2. 對象緩存
除了可以set和get存儲和獲取鍵值對以外 還可以利用 mset以對象的方式存儲和獲取信息。mset,mget批量的存儲與取出
1. set user:1 value(json格式數據) //這裏就不詳細展開了
2. mset user:1:name litianhao user:1:balance 65 //存儲對象多個數據
mget user:1:name user:1:balance //獲取對象多個數據
對象緩存mset的優點是修改的時候可以只針對對象中的一個key值進行操作,簡單快捷。
3. 分佈式鎖
setnx key value
將key的值設爲value,當且僅當key不存在。若給定的key已經存在,則setnx不做任何操作
setnx product:10001 true //返回1代表獲取鎖成功
setnx product:10001 true // 返回0代表獲取鎖失敗
執行業務操作
4. 計數器
博客或者帖子的閱讀數,都可以用String的計數器來實現
INCR article: readcount: {文章id}
GET artical:readcount:{文章id}
通過get我們也可以看到它的瀏覽數是多少
總結:這裏就是我們微信裏面或者博客閱讀數的底層實現吧,每一次有用戶打開文章進行閱讀,在底層的時候就會調用一次我們的原子加操作,這樣的話,我們文章的閱讀數就會增加,底層其實是依靠redis的String應用場景中的計數器來完成的。
6. Web集羣session共享
Spring session + redis實現session共享
7. 分佈式系統全局序列號
INCRBY orderld 1000 批量生產序列號提升性能`,就是原子計數器實際上
Hash的使用場景
Hash的常用操作
HSET key field value 存儲一個哈希表key的鍵值
HSETNX key field value 存儲一個不存在哈希表key的鍵值
HMSET key field value [field value..] 存一個哈希表key中存儲多個鍵值對
HGET key field 獲取哈希表key對應的filed鍵值
HDEL key field [field ..] 刪除哈希表key中的field鍵值
HLEN key 返回哈希表中key中的filed的數量
HGETALL key 返回哈希表key中所有的鍵值
1. 對象緩存
對象緩存除了用String以外,還可以用哈希的批量操作進行對對象的存儲,接下來就是用HMSET做對象的批量操作。
HMSET user {userid}:name litianhao {userid}: balance 65 // 用戶字段 名稱 字段 名稱
HMSET user 1:name litianhao 1:balance 65 // 例子
HMGET user 1:name 1:balance
2. 電商購物車
- 以用戶id作爲key
- 商品id作爲field
- 商品數量作爲value
購物車的操作
1 添加商品 hset card:1001 10088 1 往id爲1001的用戶的購物車中添加商品號爲10088的商品1件
2 增加數量 hincrby card:1001 10088 1
3 商品總數 hlen card:1001
4 刪除商品 hdel card:1001 10088
5 獲取購物車中所有的商品 hgetall card:1001
注意:Redis中存儲的是商品購物車中的id,不能存儲商品的名稱,因爲redis的內存是有限的,最終獲取到商品名稱時通過redis中的商品id在通過ajdx異步的去獲取商品的名稱。
Hash結構的優缺點:
優點:
- 同類型的數據歸類存儲,方便管理。對數據的管理更加集中,一個用戶表都可以放在一個key下面
- 相比String類型的操作消耗內存,cpu更小
- 相比String類型更節省存儲空間
缺點:
- 過期的功能不能使用在field上,只能用在key上。
- Redis集羣架構下不適合大規模使用
Redis集羣: 有很多很多的redis節點,一個user(key)通過一些哈希的算法映射到一個節點上,redis集羣就是多個redis數據分片,有可能會出現一個節點集羣佔用的容量非常非常的大,甚至幾個TB,其它的幾點很少,有可能不到一個G。如果在集羣的架構下Hash涉及到不是特別好的情況下,會導致數據傾斜,而且性能會大幅度降低,甚至宕機(redis由於是單線程)
List類型的使用場景
List的使用操作:
LPUSH key value [value..] // 將一個或多個值value插入到key列表的表頭
RPUSH key value [value..] // 將一個或多個值value插入到key列表的表尾
LPOP key // 移除並返回key列表的表頭元素
RPOP key // 移除並返回key列表的尾元素
LRANGE key start stop // 從 start到stop的消息取出來
BLPOP key [key..] timeout //從key列表表頭彈出一個元素,若列表表頭沒有元素,阻塞等待timeout秒,如果爲0,一直等待
BRPOP key[key..] timeout // 從key列表表尾彈出一個元素,若列表中沒有元素,則阻塞等待timeout秒,如果爲0,一直等待
List實現我們常用的數據結構:
Stack(棧) = LPUSH + LPOP 可以實現一個先進後出的棧結構
Queue(隊列) = LPUSH + RPOP 可以實現一個先進先出的隊列
Blocking MQ(阻塞隊列) = LPUSH + BRPOP
1. 實現消息列表的消息流底層(如微博的公衆號和微信公衆號的消息)–小用戶量的粉絲纔可以這樣推送消息
上面的含義是向id號10086推送信息"123",然後接着向10086推送信息"456",最終獲取id10086的list列表中的從後到前的信息列表0 1
SET類型的使用場景
1. 微信裏面的抽獎活動
主要涉及到:
- 點擊參與抽獎加入到集合 SADD key {userid}
- 查看參與抽獎所有用戶 SMEMBER key
- 抽取count名中獎者加入另一個集合 SRANDMEMBER key [count] / SPOP key [count]
現在有抽獎活動act:1,現在參與的用戶有 1888,1999,2000,2100,2200,然後SMEMBERS獲取所有的用戶id,然後SRANDMEMBER act:1 2 的意思是隨機抽取act:1活動的兩名幸運者加入獲獎集合。
2. 微博的點贊,收藏,標籤
-
點贊
SADD like:{消息id} {用戶id}
-
取消點贊
SREM like:{消息id} {用戶id}
-
檢查用戶是否點過贊
SISMEMBER like:{消息id} {用戶id}
-
獲取點讚的用戶列表
SMEMBERS like:{消息id}
-
獲取點讚的用戶數
SCARD like:{消息id}
3. 集合操作 之微信微博的關注模型
集合的基本操作:
set1 = {a,b,c}
set2 = {b,c,d}
set3 = {c,d,e}
SINTER set1 set2 set3 -> {c} 求交集
SUNION set1 set2 set3 -> {a,b,c,d,e} 求並集
SDIFF set1 set2 set3 ->{a} 求差集 set1 - (set2 + set3)
社交中的用戶與用戶之間的關注模型。無非關注的對象不同
- 新浪微博或者微信共同關注的人,共同的粉絲
- 淘寶店鋪的共同關注
- 美團的商家關注
- 滴滴打車的司機關注,路線的關注
- 電商商品的篩選
注意:但是有些大的明星粉絲的關注或者粉絲的集合會非常的龐大,所以針對於這些大v整個後端的實現會和我們普通人不一樣,因爲它的數據量巨大,所以不太利於集合的運算,因爲集合的運算需要取出所有的對象元素進行交集並集運算,所以在他們的後端其實是特殊化,或者機器都是單獨部署的。
ZSet集合
1. ZSet集合操作實現排行榜
- 點擊新聞
- 展示當日排行top
- 微博微信的熱搜與排行榜
還比如
微博、微信、陌陌 附近的人
微信搖一搖 附近的人
滴滴打車 附近的車
美團 附近的餐館