1. 程式人生 > >複習電商筆記-33-Redis功能介紹

複習電商筆記-33-Redis功能介紹

 

Redis實現訊息佇列

 

 

為何Redis可以做訊息佇列

首先redis它的設計是用來做快取的,但是由於它自身的某種特性(下面會詳細討論)使得它可以用來做訊息佇列。它有幾個阻塞式的API可以使用,正是這些阻塞式的API讓他有做訊息佇列的能力。

試想一下在”資料庫解決所有問題“的思路下,不使用訊息佇列也是可以完成你的需求的。我們把任務全部存放在資料庫然後通過不斷的輪詢方式來取任務處理。這種做法雖然可以完成你的任務但是做法很粗劣。但是如果你的資料庫介面提供一個阻塞的方法那麼就可以避免輪詢操作了,你的資料庫也可以用來做訊息佇列,只不過目前的資料庫還沒有這樣的介面。

另外做訊息佇列的其他特性例如FIFO也很容易實現,只需要一個List物件從頭取資料,從尾部塞資料即可實現。

redis能做訊息佇列得益於

他list物件blpop brpop介面以及Pub/Sub(釋出/訂閱)的某些介面。

他們都是阻塞版的,所以可以用來做訊息佇列。

 

 

耗記憶體

儘管redis對一些資料結構採用了壓縮法儲存,但是用記憶體量還是過高。

 

Redis實現唯一計數的3種方法

唯一計數是網站系統中十分常見的一個功能特性,例如網站需要統計每天訪問的人數 unique visitor (也就是 UV)。計數問題很常見,但解決起來可能十分複雜:一是需要計數的量可能很大,比如大型的站點每天有數百萬的人訪問,資料量相當大;二是通常還希望擴充套件計數的維度,比如除了需要每天的 UV,還想知道每週或每月的 UV,這樣導致計算十分複雜。

在關係資料庫儲存的系統裡,實現唯一計數的方法就是 select count(distinct <item_id>),它十分簡單,但是如果資料量很大,這個語句執行是很慢的。用關係資料庫另外一個問題是插入資料效能也不高。

Redis 解決這類計數問題得心應手,相比關係資料庫速度更快,消耗資源更少,甚至提供了 3 種不同的方法。

 

 

基於 set

Redis 的 set 用於儲存唯一的資料集合,通過它可以快速判斷某一個元素是否存在於集合中,也可以快速計算某一個集合的元素個數,另外和可以合併集合到一個新的集合中。

SISMEMBER key member        # 判斷 member 是否存在

SADD key member          # 往集合中加入 member

SCARD key                   # 獲取集合元素個數

基於 set 的方法簡單有效,計數精確,適用面廣,易於理解,它的缺點是消耗資源比較大(當然比起關係資料庫是少很多的),如果元素個數很大(比如上億的計數),消耗記憶體很恐怖。

 

 

基於 bit

Redis 的 bit 可以用於實現比 set 記憶體高度壓縮的計數,它通過一個 bit 1 或 0 來儲存某個元素是否存在資訊。例如網站唯一訪客計數,可以把 user_id 作為 bit 的偏移量 offset,設定為 1 表示有訪問,使用1MB的空間就可以存放800 多萬(1024*1024*8=8388608)使用者的一天訪問計數情況。

SETBIT key offset value  # 設定位資訊

GETBIT key offset         # 獲取位資訊

BITCOUNT key [start end] # 計數

BITOP operation destkey key [key ...]  # 點陣圖合併

基於 bit 的方法比起 set 空間消耗小得多,但是它要求元素能否簡單對映為位偏移,適用面窄了不少,另外它消耗的空間取決於最大偏移量,和計數值無關,如果最大偏移量很大,消耗記憶體也相當可觀。

 

 

基於 HyperLogLog

實現超大資料量精確的唯一計數都是比較困難的,但是如果只是近似的話,計算科學裡有很多高效的演算法,其中 HyperLogLog Counting 就是其中非常著名的演算法,它可以僅僅使用 12 k左右的記憶體,實現上億的唯一計數,而且誤差控制在百分之一左右。

PFADD key element [element ...]  # 加入元素

PFCOUNT key [key ...]   # 計數

這種計數方法真的很神奇,我也沒有徹底弄明白,有興趣可以深入研究相關文章。

 

Redis的缺點

持久化

redis直接將資料儲存到記憶體中,可通過兩種方式持久化:定時快照和基於語句的追加。

定時快照的方法是指每隔一段時間將整個資料庫的資料寫到磁碟上,很明顯,每次均是寫全部資料,代價非常高;

而基於語句的追加方法值追蹤變化的資料,這類似於MySQL的binlog方法,但追加log可能過大,同時所有操作均要重新執行一遍,回寫速度慢。

 

 

耗記憶體

儘管redis對一些資料結構採用了壓縮法儲存,但是用記憶體量還是過高。

 

Redis應用舉例

  1. 快取(資料查詢、短連線、新聞內容、商品內容等等)。(最多使用)

2)分散式叢集架構中的session分離。

3)聊天室的線上好友列表。

4)任務佇列。(秒殺、搶購、12306等等)(先進先出)

5)應用排行榜。(可以給每個元素設定一個打分,這樣就可以排序)

6)網站訪問統計。

7)資料過期處理(可以精確到毫秒)。

 

 

取最新N個數據的操作

比如典型的取你網站的最新文章,通過下面方式,我們可以將最新的5000條評論的ID放在Redis的List集合中,並將超出集合部分從資料庫獲取

1)使用LPUSH latest.comments<ID>命令,向list集合中插入資料

2)插入完成後再用 LTRIM latest.comments 0 5000 命令使其永遠只儲存最近5000個ID

 

 

短連線

這樣就可以通過一個比較短的URL來訪問相同的地址。它是將連線地址通過一個演算法進行簡化變短。http://dwz.cn/NJfGa最後面這實際就是一個key,在它的資料庫中這個key就對應一個URL。當訪問http://dwz.cn/NJfGa這個地址時dwz.cn中的服務對這個後面的ID進行解析,從資料庫查詢出真正的地址。然後重定向訪問真正的連結。

 

 

聊天室好友線上列表

假設A存放你的好友,B存放所有線上的人,它們的交集就是你的線上好友。

 

 

應用排行

 

Redis配置檔案以及記憶體清理策略

 

 

Redis配置檔案

在windows平臺下預設的配置檔案是:redis.windows.conf,這裡面配置了非常多的資訊,一般配置保持預設,在一些特定的場景下可以自定義配置,常用到的配置項如下:

port 服務埠

bind 繫結ip其他ip不能訪問(多個ip空格隔開)

databases 資料庫數量,預設16個

daemonize設定為守護程序(linux平臺)

maxmemory最大的記憶體大小(1MB、1GB、1m、1g)

maxmemory-policy達到記憶體限制後的處理策略(後面詳細說明)

注意:修改後配置檔案需要重啟redis服務才能生效。

 

 

記憶體的清理策略Maxmemory-policy策略

Volatile-lru:使用LRU演算法刪除一個鍵(只對設定了生存時間的鍵)

Allkeys-lru:使用LRU演算法刪除一個鍵

Volatile-random:隨機刪除一個鍵(只對設定了生存時間的鍵)

Allkeys-random:隨機刪除一個鍵

Volatile-ttl:刪除生存時間最近的一個鍵

Noeviction:不刪除鍵,只返回錯誤

            LUR(Least Recently Used)演算法:最近最少使用