redis入門介紹及社交行業應用
背景
最近工作中開始使用redis,本文就本人目前的理解對redis做一個概括性的介紹,並簡單舉例幾個工作中的應用,最後總結redis使用中的規範,期望以比較全面的方式整理redis相關知識給大家。
redis介紹
Redis(Remote Dictionary Server)可以理解是一個基於記憶體的key-value儲存資料結構。“基於記憶體”表示所有資料直接存在記憶體中,擁有較快的IO速度,“基於key-value”表示它很適合與基於key的查詢操作,達到O(1)的複雜度。
redis擁有簡單key-value資料結構儲存功能,主要資料結構包括string、hash、set、list、zset和不常見的複雜資料結構bitmap和Hyperloglogs。
下面列舉不同資料結構的操作來加深對redis提供資料結構的理解:
1、string資料結構 set box “hello" (新增元素,表示設定key為box,value為hello) get box (獲取key為box對應的value值) 2、list資料結構 LPUSH friends “sandy” (向列表左邊加入元素) RPUSH friends “bruce" (向列表右邊加入元素) LRANGE friends 0 -1 (兩個引數,左右封閉,第二個引數-1表示顯示所有元素) LLEN friends (返回list的長度) LPOP friends (刪除左邊元素,並返回該值) RPOP friends (刪除右邊元素,並返回該值) 可以應用list資料結構實現佇列和棧的效果 3、set資料結構(同一個key裡面的元素集合沒有重複) SADD home_member “xwc" (新增元素) SREM home_member “xwc” (刪除元素) SISMEMBER home_member “xwc” (判斷是否存在xwc,存在返回1,不存在返回0) SMEMBERS home_member (返回set中所有元素) SRANDMEMBER key [count] 隨機返回count個數元素 SUNION A B (將A,B集合放一起) 4、hash資料結構 命令結構:HSET key field value HSET user name "John Smith” (給key為user,屬性為name的欄位賦值John Smith) HSET user email "
[email protected]" (給key為user,屬性為email的欄位賦值[email protected]) HGETALL user (獲取key為user的所有屬性值) HINCBY user age 5 (給key為user,屬性為age的值加上5) 5、zset資料結構 命令結構:ZADD key score value ZADD xwc 112 "apple” (設定key為xwc,value為apple,分數score為102分,zset會根據score欄位排序) ZADD xwc 120 "banana” (同上) ZRANGE xwc 0 -1 (返回key為xwc,value為從小到大排序的集合所有元素) zrevrange xwc 0 2 (返回按分數從大到小排序的前3個元素)
redis應用
相對於傳統關係型資料庫,redis具有簡單資料結構、單執行緒,記憶體儲存和支援高併發的特點,適合很多社交應用。
1、指標計數
社交應用一般會有帖子廣場(feed 流),可以實時採集使用者行為資訊日誌,對每個帖子的點選、點贊、轉發、分享哥和曝光進行計數統計。
使用hash資料結構可以對不同feedID的幾個屬性指標統計。
2、排行榜
排行榜例如feed熱門榜需要實時計算熱度,根據熱度來排名。redis的zset資料結構就非常合適,因為zset的每一個元素都有score,可以更新score來實現排行榜功能。
具體實現有兩種:
- 離線計算,使用一個list來維護需要排序的候選集,定時對list裡面的元素計算score更新zset。
- 實時計算,使用flink、spark streaming實時消費使用者對帖子的行為日誌,對新行為帖子計算score分數。實現較複雜,但是幾乎實時更新帖子榜單。
3、過濾與去重
使用redis儲存使用者訪問帖子歷史記錄來實現去重功能。
4、熱門資料儲存
資料如果分為冷熱,將熱資料放到redis,當訪問資料時如果redis沒有則可以從傳統資料庫讀取。利用redis記憶體儲存訪問快的特點來優化服務效能。
5、記錄近一段時間資訊
很多時候我們只需要保留最近2天活躍的使用者資訊,這個時候可以使用zset資料結構,score使用使用者最近訪問的timestamp,這樣可以根據score維持兩天內使用者資訊,超過2天的刪除。
6、pub/sub 訊息訂閱釋出
Redis的Pub/Sub非常非常簡單,執行穩定並且快速,支援模式匹配,能夠實時訂閱與取消頻道。redis與kafka的pub/sub不同之處在於沒有持久化,如果訂閱者掛掉,那麼在從掛掉到恢復後這段時間的訊息是丟失的,所以redis適用於可以容忍丟失訊息的場景。
7、佇列功能
redis支援阻塞佇列,list列表沒元素的時候阻塞,實現一個功能簡單的messaging系統。
8、好友關係儲存
redis簡單的資料結構適合儲存一對多關係,如使用者關注列表,使用者粉絲列表。
9、快取資料
相對於存在磁碟,如果資料量不是很大,存在記憶體儲存redis能加速讀寫效率。
關於redis常見問題?
這裡整理了幾個認識redis過程的常見問題:
1、redis為什麼這麼快?
- 純記憶體,類似於HashMap結構,HashMap的優勢就是查詢和操作的時間複雜度都是O(1);
- 資料結構簡單,讀寫資料量小
- 單執行緒處理,減少執行緒上下文切換開銷,省去考慮同步問題
- 多路IO複用(多路是處理多執行緒連線,IO複用是重複使用一個執行緒執行請求)
因為是單執行緒處理每次執行,cpu不是redis程式的瓶頸,反而記憶體最可能是瓶頸。
2、redis能不能持久化?
能,支援RDB和AOF持久化。
-
RDB:定時執行快照儲存記憶體中資料到本地磁碟,直接將databases中的key-value的二進位制形式儲存在了rdb檔案中。
優點:效能較高,因為是快照,且執行頻率比aof低,而且rdb檔案中直接儲存的是key-values的二進位制形式,對於恢復資料也快。 缺點:在上一次快照和下一次快照之間宕機,這個時間段之內的資料丟失。
-
AOF(Ahead of File):redis將對資料的每一條修改命令追加到aof檔案中。 **優點:**宕機後資料能從AOF檔案中獲取,資料沒有丟失。 **缺點:**效能較低,因為每次修改操作都會將追加到AOF檔案。
關於redis持久化資訊可參考:RDB+AOF
3、redis是否支援分散式?
支援,這是在redis 3.0之後開始支援叢集模式部署。 一個Redis 叢集包含 16384 個雜湊槽(hash slot),資料庫中的每個key都屬於這 16384個雜湊槽的其中一個(會根據key計算crc16的hashcode,然後對16384取模),叢集中的每個節點負責處理一部分雜湊槽。 例如一個叢集有三個節點,其中:
- 節點 A 負責處理 0 號至 5500 號雜湊槽。
- 節點 B 負責處理 5501 號至 11000 號雜湊槽。
- 節點 C 負責處理 11001 號至 16384 號雜湊槽。
如果有新節點加入或退出,可以根據一致性hash演算法來重新平衡槽的分佈。
redis一共支援三種模式:主從模式、sentinel模式和cluster模式,其中叢集模式就是純分散式的,擴充套件性好。
4、redis與memcache的區別是什麼?
redis和memcache讀寫效能和儲存效率相當,此外還有如下不同:
redis | memcache | |
---|---|---|
資料結構 | 支援多種資料結構 | 只支援key-value資料結構 |
叢集模型 | 支援 | 不支援 |
資料持久化/同步 | 支援 | 不支援 |
網路IO模型 | 多執行緒 | 單執行緒IO複用 |
資料一致性 | 通過事物支援 | 通過CAS支援 |
參考: