Redis是一種基於鍵值對的NoSQL數據庫,它的值主要由string(字符串),hash(哈希),list(列表),set(集合),zset(有序集合)五種基本數據結構構成,除此以外還支持一些其餘的數據結構和算法。key都是由字符串構成的,那麼這五種數據結構的使用場景有哪些?一塊兒來看看!web
字符串類型是Redis最基礎的數據結構,字符串類型能夠是JSON
、XML
甚至是二進制的圖片等數據,可是最大值不能超過512MB。redis
Redis會根據當前值的類型和長度決定使用哪一種內部編碼來實現。算法
字符串類型的內部編碼有3種:數據庫
在web服務中,使用MySQL做爲數據庫,Redis做爲緩存。因爲Redis具備支撐高併發的特性,一般能起到加速讀寫和下降後端壓力的做用。web端的大多數請求都是從Redis中獲取的數據,若是Redis中沒有須要的數據,則會從MySQL中去獲取,並將獲取到的數據寫入redis。後端
Redis中有一個字符串相關的命令incr key
,incr
命令對值作自增操做,返回結果分爲如下三種狀況:緩存
0
,返回1
好比文章的閱讀量,視頻的播放量等等都會使用redis來計數,每播放一次,對應的播放量就會加1,同時將這些數據異步存儲到數據庫中達到持久化的目的。安全
在分佈式系統中,用戶的每次請求會訪問到不一樣的服務器,這就會致使session不一樣步的問題,假如一個用來獲取用戶信息的請求落在A服務器上,獲取到用戶信息後存入session。下一個請求落在B服務器上,想要從session中獲取用戶信息就不能正常獲取了,由於用戶信息的session在服務器A上,爲了解決這個問題,使用redis集中管理這些session,將session存入redis,使用的時候直接從redis中獲取就能夠了。服務器
爲了安全考慮,有些網站會對IP進行限制,限制同一IP在必定時間內訪問次數不能超過n次。微信
Redis中,哈希類型是指一個鍵值對的存儲結構。markdown
哈希類型的內部編碼有兩種:
hash-max-ziplist-entries
配置(默認512個)同時全部值都小於hash-max-ziplist-value
配置(默認64字節)時使用。ziplist使用更加緊湊的結構實現多個元素的連續存儲,因此比hashtable更加節省內存。因爲hash類型存儲的是一個鍵值對,好比數據庫有如下一個用戶表結構
id | name | age |
---|---|---|
1 | Java旅途 | 18 |
將以上信息存入redis,用代表:id做爲key,用戶屬性做爲值:
hset user:1 name Java旅途 age 18
複製代碼
使用哈希存儲會比字符串更加方便直觀
列表類型用來存儲多個有序的字符串,一個列表最多能夠存儲2^32-1
個元素,列表的兩端均可以插入和彈出元素。
列表的內部編碼有兩種:
list-max-ziplist-entries
配置(默認512個)同時全部值都小於list-max-ziplist-value
配置(默認64字節)時使用。ziplist使用更加緊湊的結構實現多個元素的連續存儲,因此比hashtable更加節省內存。列表用來存儲多個有序的字符串,既然是有序的,那麼就知足消息隊列的特色。使用lpush
+rpop
或者rpush
+lpop
實現消息隊列。除此以外,redis支持阻塞操做,在彈出元素的時候使用阻塞命令來實現阻塞隊列。
因爲列表存儲的是有序字符串,知足隊列的特色,也就能知足棧先進後出的特色,使用lpush
+lpop
或者rpush
+rpop
實現棧。
由於列表的元素不可是有序的,並且還支持按照索引範圍獲取元素。所以咱們可使用命令lrange key 0 9
分頁獲取文章列表
集合類型也能夠保存多個字符串元素,與列表不一樣的是,集合中不容許有重複元素而且集合中的元素是無序的。一個集合最多能夠存儲2^32-1
個元素。
集合類型的內部編碼有兩種:
set-max-intset-entries
配置(默認512個)時,redis會選用intset來做爲集合的內部實現,從而減小內存的使用。例如一個用戶對籃球、足球感興趣,另外一個用戶對橄欖球、乒乓球感興趣,這些興趣點就是一個標籤。有了這些數據就能夠獲得喜歡同一個標籤的人,以及用戶的共同感興趣的標籤。給用戶打標籤的時候須要①給用戶打標籤,②給標籤加用戶,須要給這兩個操做增長事務。
sadd user:1:tags tag1 tag2
複製代碼
sadd tag1:users user:1
sadd tag2:users user:1
複製代碼
使用交集(sinter)求兩個user的共同標籤
sinter user:1:tags user:2:tags
複製代碼
集合有兩個命令支持獲取隨機數,分別是:
srandmember key [count]
spop key [count]
用戶點擊抽獎按鈕,參數抽獎,將用戶編號放入集合,而後抽獎,分別抽一等獎、二等獎,若是已經抽中一等獎的用戶不能參數抽二等獎則使用spop
,反之使用srandmember
。
有序集合和集合同樣,不能有重複元素。可是能夠排序,它給每一個元素設置一個score做爲排序的依據。最多能夠存儲2^32-1
個元素。
有序集合類型的內部編碼有兩種:
ziplist(壓縮列表):當有序集合的元素個數小於list-max-ziplist-entries
配置(默認128個)同時全部值都小於list-max-ziplist-value
配置(默認64字節)時使用。ziplist使用更加緊湊的結構實現多個元素的連續存儲,更加節省內存。
skiplist(跳躍表):當不知足ziplist的要求時,會使用skiplist。
用戶發佈了n篇文章,其餘人看到文章後給喜歡的文章點贊,使用score來記錄點贊數,有序集合會根據score排行。流程以下
用戶發佈一篇文章,初始點贊數爲0,即score爲0
zadd user:article 0 a
複製代碼
有人給文章a點贊,遞增1
zincrby user:article 1 a
複製代碼
查詢點贊前三篇文章
zrevrange user:article 0 2
複製代碼
查詢點贊後三篇文章
zrange user:article 0 2
複製代碼
下單系統,下單後須要在15分鐘內進行支付,若是15分鐘未支付則自動取消訂單。將下單後的十五分鐘後時間做爲score,訂單做爲value存入redis,消費者輪詢去消費,若是消費的大於等於這筆記錄的score,則將這筆記錄移除隊列,取消訂單。
在開發中,字符串類型是用的最多的數據類型,致使咱們忽視了redis的其餘四種數據類型,在具體場景下選擇具體的數據類型對提高redis性能有很是大的幫助。redis雖然支持消息隊列的實現,可是並不支持ack。因此redis實現的消息隊列不能保證消息的可靠性,除非本身實現消息確認機制,不過這很是麻煩,因此若是是重要的消息仍是推薦使用專門的消息隊列去作。
若是以爲文章不錯,歡迎關注、點贊、收藏,大家的支持是我創做的動力,感謝你們。
若是文章寫的有問題,請不要吝惜文筆,歡迎留言指出,我會及時覈查修改。
若是你還想更加深刻的瞭解我,能夠微信搜索「Java旅途」進行關注。回覆「1024」便可得到學習視頻及精美電子書。天天7:30準時推送技術文章,讓你的上班路不在孤獨,並且每個月還有送書活動,助你提高硬實力!