1. 程式人生 > >Redis使用場景

Redis使用場景

持久 上一個 數據持久化 tac AS 緩存 tag 消息 關系

1、字符串使用場景

a) 緩存功能

典型使用場景:Redis作為緩存層,MySQL作為存儲層,絕大部分請求的數據都是從Redis中獲取,由於Redis具有支撐高並發的特性,所以緩存通常能起到加速讀寫和降低後端壓力的作用。

開發提示:與MySQL等關系型數據庫不同的是,Redis沒有命令空間,而且也沒有對鍵名有強制要求,但設計合理的鍵名,有利於防止鍵沖突和項目的可維護性,比較推薦的方式是使用“業務名:對象名:id:[屬性]”作為鍵名。例如MySQL的數據庫名為vs,用戶表名為user,那麽對應的鍵可以用"vs:user:1","vs:user:1:name"來表示,如果當前Redis只被一個業務使用,甚至可以去掉vs。如果鍵名比較長,例如"user:{uid}:friends:message:{mid}",可以在能描述含義的前提下適當減少鍵的長度,例如采用縮寫形式,從而減少由於鍵過長的內存浪費。

b) 計數

典型應用場景:視頻播放數計數的基礎組件,用戶每播放一次視頻,相應的視頻播放數就會自增1。Redis可以實現快速計數、查詢緩存的功能,同時數據可以異步落地到其他數據源。

開發提示:實際上一個真實的計數系統要考慮的問題會很多,防作弊、按照不同維度計數,數據持久化到底層數據源等。

c) 共享Session

典型應用場景:用戶登陸信息,Redis將用戶的Session進行集中管理,每次用戶更新或查詢登陸信息都直接從Redis中集中獲取。

d) 限速

典型應用場景:驗證碼接口訪問頻率限制,用戶登陸時需要讓用戶輸入手機驗證碼,從而確定是否是用戶本人,但是為了短信接口不被頻繁訪問,會限制用戶每分鐘獲取驗證碼的頻率,例如一分鐘不能超過5次。

2、哈希使用場景

a) 緩存用戶信息

相比於使用字符串序列化緩存用戶信息,哈希類型變得更加直觀,並且在更新操作上會更加便捷。可以將每個用戶的id定義為鍵後綴,多對field-value對應每個用戶的屬性。

哈希類型和關系型數據庫不同之處:

哈希類型是稀疏的,而關系型數據庫是完全結構化的,例如哈希類型每個鍵可以有不同的field,而關系型數據庫一旦添加新的列,所有行都要為其設置值(即使為NULL)。

關系型數據庫可以做復雜的關系查詢,而Redis去模擬關系型復雜查詢開發困難,維護成本高。

三種緩存用戶信息優缺點比較:

原生字符串類型:每個屬性一個鍵

優點:簡單直觀,每個屬性都支持更新操作。

缺點:占用過多的鍵,內存占用量較大,同時用戶信息內聚性比較差,所以此種方案一般不會在生產環境使用。

序列化字符串類型:將用戶信息序列化後用一個鍵保存。

優點:簡化編程,如果合理的使用序列化可以提高內存的使用效率。

缺點:序列化和反序列化有一定的開銷,同時每次更新屬性都需要把全部數據取出進行反序列化,更新後再序列化到Redis中。

哈希類型:每個用戶屬性使用一對field-value,但是只用一個鍵保存。

優點:簡單直觀,如果使用合理可以減少內存空間的使用。

缺點:要控制哈希在ziplist和hashtable兩種內部編碼的轉換,hashtable會消耗更多內存。

3、列表使用場景

a) 消息隊列

Redis的lpush+brpop命令組合即可實現阻塞隊列,生產者客戶端使用lrpush從列表左側插入元素,多個消費者客戶端使用brpop命令阻塞式的"搶"列表尾部的元素,多個客戶端保證了消費的負載均衡和高可用性。

b) 文章列表

每個用戶有屬於自己的文章列表,現在需要分頁展示文章列表。此時可以考慮使用列表,因為列表不但是有序的,同時支持按照索引範圍獲取元素。

c) 開發提示

lpush + lpop = Stack(棧)

lpush + rpop = Queue(隊列)

lpush + ltrim = Capped Collection(有限集合)

lpush + brpop = Message Queue(消息隊列)

4、集合

a) 標簽(tag)

集合類型比較典型的使用場景是標簽(tag),例如一個用戶可能對娛樂、體育比較感興趣,另一個用戶可能對歷史、新聞比較感興趣,這些興趣就是標簽。 開發提示:用戶和標簽的關系維護應該在一個事物執行,防止部分命令失敗造成的數據不一致。

5、有序集合

a) 排行榜系統

有序集合比較典型的使用場景就是排行榜系統,例如視頻網站需要對用戶上傳的視頻做排行榜,榜單的維度可能是多個方面的:按照時間、按照播放數量、按照獲得的贊數。

Redis使用場景