Redis常用數(shù)據(jù)結(jié)構(gòu)介紹和業(yè)務應用場景分析
redis數(shù)據(jù)結(jié)構(gòu)
redis內(nèi)置了很多常用數(shù)據(jù)結(jié)構(gòu),了解這些數(shù)據(jù)結(jié)構(gòu)的功能和應用場景能夠讓我們在需求開發(fā)時靈活運用來解決實際問題。
Strings字符串、數(shù)字
String是redis中最基礎的數(shù)據(jù)結(jié)構(gòu),你可以把它用作緩存最基礎的kv(key-value)類型的緩存(value最大為512MB),只需要把需要緩存的對象進行string的編解碼即可。另外String也可以保存數(shù)值類型的數(shù)據(jù),就可以來實現(xiàn)計數(shù)功能(redi提供了incr等原子操作)
常見應用場景
- 計數(shù)器: 保存各種計數(shù)(比如視頻播放數(shù)、點贊數(shù)、活動參與人數(shù)、剩余庫存數(shù)、紅包總金額)
- kv: key value類型的緩存數(shù)據(jù),比如保存一篇文章的內(nèi)容、保存一個用戶的信息等等
- 分布式限流: 通過帶有過期時間的計數(shù)器,每次請求減一判斷是否大于等于0,能夠?qū)崿F(xiàn)一些分布式限流的功能,比如限制一分鐘內(nèi)接口請求數(shù)不超過1000,還可以實現(xiàn)一個用戶一分鐘內(nèi)發(fā)布評論不超過N個的功能。
- 分布式鎖: 通過string的setnx,可以實現(xiàn)簡單的分布式鎖,比如限制一個用戶不要同時請求接口(避免接口處理過程中的用戶維度并發(fā)操作導致數(shù)據(jù)錯誤)。(有人會提出質(zhì)疑說網(wǎng)上的redis分布式鎖有這樣那樣的問題,其實大部分需要分布式鎖的場景都是比較簡單的,要實現(xiàn)出一個完美的分布式解決方案,可能會比較重影響接口性能或者實現(xiàn)復雜)
List
List列表更多的時候是把它當成隊列使用(最大2^32 - 1個元素),使用入隊出隊功能,如果來使用它作為各種列表的話,很多時候不具備防重功能在使用的時候不是很方便。
常見應用場景
- 搶紅包: 發(fā)紅包、拆紅包入隊,搶紅包則是出隊
Set
Set是一種無序不重復的集合,添加刪除檢查是否存在都是O(1)的時間復雜度。
Sorted Set
Sorted Set是結(jié)合了List和Set的一種數(shù)據(jù)結(jié)構(gòu),有序(按照元素score排序)的不重復(元素key不重復)的集合,Sorted Set是在業(yè)務開發(fā)中非常常用的數(shù)據(jù)結(jié)構(gòu)(比List和Set應用面更廣),因為在實際需求中,存在非常多的列表場景,比如視頻列表、評論列表、關注列表、點贊列表、排行榜等等各種列表,每個列表都要按照一定規(guī)則排序,并且大部分都不能重復,所以使用Sorted Set就非常合適。
常見應用場景
- 排行榜等榜單: 排行用的分數(shù)作為score
- 列表分頁: member存儲列表元素的id(視頻id、用戶id等),元素的id(具備遞增且唯一)作為score(如果量級比較小QPS很低用時間戳也可以不會有多少重復時間戳),使用zrevrangebyscore進行分頁查詢,使用zscore判斷是否關注等。
Hash
hash是一個map結(jié)構(gòu),可以像存儲對象的多個字段一樣存儲一個key的多類數(shù)據(jù)。
常見應用場景
- 保存一個對象的多個字段,比如一篇文章的作者、發(fā)布時間、標簽等等信息作為一個hash上的多個字段保存。
PubSub
redis中的pub/sub可以實現(xiàn)廣播功能,類似rocketmq中的broadcast
常見應用場景
- websocket場景,server給client發(fā)送消息時,由于不知道client和那個server建立的鏈接,所以可以通過發(fā)送廣播,讓對應的server發(fā)送消息。
其他數(shù)據(jù)結(jié)構(gòu)
除了上述最基本的數(shù)據(jù)結(jié)構(gòu)外,redis還提供了一些其他的數(shù)據(jù)結(jié)構(gòu),有的是需要安裝相關redis stack來使用的。
bitmap
bitmap本質(zhì)上還是使用的string字符串,不過可以通過bit來進行操作,把這個key的value值想象成bit組成的數(shù)組。
常見應用場景
- 記錄多個是否的標記為: 比如記錄一個用戶是否是會員、是否是認證用戶等等這類是否的標記,這些標記作為一個用戶的一個bitmap上的不同index上的bit位,這樣只需要請求一次就可以獲取到一個用戶的多種標記信息,并且存儲上相對kv存儲也比較節(jié)省資源。一個bitmap最多可以存儲512MB的數(shù)據(jù),一共有2^32個bit位,所以能夠存儲非常多的數(shù)據(jù),比如簽到場景可以存儲一個用戶某一天是否簽到過。
bloomfilter
bloomfilter(也叫布隆過濾器)可以理解成一種特殊的set集合,它可以用來判斷一個值是否在這個集合中,不過不同于普通的set,它的判斷存在一定誤判的可能(假陽性),如果bloomfilter判斷一個值不在這個集合中,那么一定不在,但是如果判斷在,那么有可能不在。
常見應用場景
減少請求量、緩存穿透量: 比如為了防止大量請求查詢緩存不存在穿透到數(shù)據(jù)庫中查詢,我們可以在緩存查詢前加一層布隆過濾器的查詢,如果不在布隆過濾器中,說明數(shù)據(jù)肯定不在數(shù)據(jù)庫和緩存中,就不需要繼續(xù)查詢了。
hyperloglog
hyperloglog是一種概率性的去重計數(shù)數(shù)據(jù)結(jié)構(gòu),可以實現(xiàn)一定精度的去重計數(shù)
常見應用場景
- 各類需要去重的計數(shù),但是有不希望保存所有的記錄數(shù)據(jù): 文章閱讀數(shù)、網(wǎng)站訪客數(shù)等等
geohash
geohash可以實現(xiàn)距離計算、距離查詢等地理位置相關的功能
常見應用場景
- 距離判斷、附近的人