1. 程式人生 > >Redis應用場景分析

Redis應用場景分析

在上一篇文章《Redis資料結構探究》中,對Redis的五種資料結構和它們的底層實現進行了分析,這篇文章主要結合近期應用Redis的經歷,對Redis的使用場景做出分析。

在上篇文章中,簡單總結了Redis有以下應用場景:

1、快取服務

這是Redis應用最廣泛的部分,用於減小資料庫訪問壓力,提高系統併發量,邏輯也比較簡單。

  • select時,如redis中無此資料,則查詢資料庫並插入redis,如redis中有此資料,則直接返回。
  • update時,先更新資料庫,如redis中包含此資料,則更新redis。

2、SESSION伺服器

使用者的登入session資料一般是儲存在資料庫或單獨的session伺服器上,以便使用者在訪問叢集應用時不會受到影響,而使用Redis來作為session儲存方式的好處是:

  • 存取速度快。
  • 支援持久化。
  • 可以檢視實時使用者數量。
    其中,支援持久化是比較重要的一點,因為部分系統比如購物網站會將購物車資訊儲存在session中,如不支援持久化可能會發生資料丟失。

3、訊息佇列

Redis提供的list可以很方便地提供push/pop操作,可以很容易實現訊息佇列,在以下應用場景應用較多:

  • 對某些操作作非同步處理,使用生產者消費者模式進行通訊。
  • 分散式系統中使用訊息佇列進行排程,實現應用解耦。
  • 高併發情況下使用訊息佇列對請求流量削峰,將併發請求序列化,拒絕重複請求。
  • 日誌操作中使用訊息佇列解決多執行緒環境下日誌操作的併發問題。

4、排行榜

Redis中的set是一個有序集合,有序集合的鍵是成員,而值是分值。這樣既可以根據成員來訪問元素,又可以根據分值來順序訪問元素結構。這樣在實現排行榜功能時,向集合內插入元素就可以形成一個有序的集合,只要自定義分值來源,就可以實現排行榜功能,而不用每次進行排序。其他需要頻繁排序的操作也可以使用,比如優先順序佇列等。

5、列表/時間軸

一些新聞網站/部落格/微博等往往在首頁需要一個時間排序的列表或時間軸,每次在生成時間軸時往往需要一個select order操作,請求時間較長且消耗效能,如果在redis中構建一個list,通過將資料不斷push的方式,構建一個時序列表。
在微博系統中,個人feed流頁和評論首頁是通過這種方式儲存的,可以顯著地提升系統響應速度,並且減小資料庫壓力。

6、秒殺系統

在秒殺系統中,一般會有以下問題:

  • 短時間內大量併發
  • 併發讀寫時衝突嚴重,或產生錯誤。如果使用Mysql的行級鎖,可能某些請求無法獲取到鎖,資料庫負載過大時會導致宕機。
  • 請求失敗重複傳送,有效請求少,耗費系統性能

使用Redis,可以解決這些問題,有如下方式。

  • 過濾重複請求,以ip,引數,URL等記錄請求,過濾一定時間內的客戶端重複請求。
  • 使用list記錄請求,將請求順序執行,並記錄請求數量,如果有數量限制則拒絕超出數量外的請求。
  • 不直接在資料庫中扣減記憶體,而是將訂單記錄在list中,後續操作非同步執行,並及時持久化到硬碟,防止記憶體資料丟失。
  • 通過原子操作保證全域性唯一id

7、標籤操作

系統中一般會有標籤、收藏等聚合操作,這類操作具有使用頻率高,歷史資料變動小的特性,一般我們不會給記錄這類操作的不重要的欄位新增索引,所以在查詢時比較耗費效能,而使用Redis的set就可以解決這類問題,前幾天給系統中的標籤功能引入了索引,去掉了select * group by 這條查詢。

  • 使用者標記某條資料時,將資料id存入標籤id的set中
  • 取消標記時,從set裡移除該資料
  • 查詢時,直接取出set

8、計數器

上篇文章中說到了string型別可以儲存字串和浮點數,儲存浮點數時可以進行自增操作,使用INCRBY可以保證原子遞增,使用getset可以重置。可以用來記錄訪問次數,訂單id等。另外,由於有過期時間,也可以實現黑名單等功能。

最近在使用Redis時,總結了一些技巧,比如可以利用Redis的主從複製特性搭建叢集,像資料庫分庫一樣將資料分例項存放,利用redis的多個庫實現名稱空間作用,而不是通過key或字首。在進行查詢時,因為redis訪問需要網路io,可以利用hmget等方式一次獲取多條資料,而不是單條單條地獲取。合理設定value的大小。
本文對redis的使用場景進行了簡單的總結,實際中會發現redis的使用能顯著提升系統性能,應用也十分廣泛,是後端開發的必備神器。