redis使用基礎(四) ——Redis排序與消息通知

redis使用基礎(四)redis

——Redis排序與消息通知微信

 

(轉載請附上本文連接——linhxx)網絡

 

1、排序機器學習

一、命令tcp

         SORT key [ALPHA] [DESC] [LIMIT start end],對列表、集合和有序集合進行排序,當加上alpha參數後,則能夠按照字典順序排序,加上desc則倒序排序,加上limit則支持分頁。性能

二、關鍵參數學習

         by參數:by key:*->val,能夠指定排序的標準,能夠本身傳入一個list,也能夠指定某個列進行排序。優化

         get參數:get key:*->val,能夠指定sort排序的返回結果,而不是將整個集合進行返回,要多個參數時採用多個get,另外get#會返回元素自己的鍵值。ui

         store參數:store key2,能夠將前面排序的結果保存在另一個key裏面。編碼

三、性能問題

         sort的時間複雜度O(n+mlog m),n是待排序的基數,m是排序後的值。另外redis會在排序前用一個空間爲n的容器進行存儲排序期間的臨時數據。

         所以,須要注意幾個問題:

         1)儘量減小待排序的集合數量,以減小n

         2)若是不須要所有結果,則用limit,以減小m

         3)若是要排序的結果大,則用store進行存儲。

 

2、消息隊列

         redis消息隊列能夠分爲兩類,生產者和消費者,當生產者產生的數據會放入消息隊列中,消費者監測到消息隊列內有數據的時候,能夠進行後續的處理。

一、命令

         redis提供一個命令叫BRPOP,與RPOP的區別在於,當使用命令對key進行操做時,若是key沒有值,則會阻塞等待,直到等到有值後取出進行操做。另外,和brpop類似的,也有BLPOP命令。

二、優先級

         因爲brpop命令能夠支持多個鍵,而且當每一個鍵都有未處理的數據時,會從最左邊的鍵開始處理。例若有兩個郵件提醒業務,一個是開通帳號的驗證,一個是新消息提醒。則若是太多的不採用優先級,新消息提醒的業務會讓開通帳號的業務阻塞。由於開通帳號的時效性要求更高,所以須要將其放在左邊。

三、發佈訂閱模式

         發佈訂閱模式有特殊的命令,發佈的命令是PUBLISH channel message,訂閱的命令是SUBSCRIBE channel message,不過因爲redis的發佈命令不會對消息進行持久化,即後面訂閱的沒法查看到發佈者以前發佈的消息。

         subscribe命令後,會讓客戶端進入訂閱狀態,此後只能輸入四種命令:subscribe、unsubscribe、psubscribe、punsubscribe,其餘命令會報錯。

處於訂閱狀態後,客戶端會收到3種類型的回覆,每一個回覆有三個值,第一個值是回覆的類型,根據類型不一樣,二三兩個值也不一樣。消息類型以下:

1)subscribe 表示訂閱成功的反饋,此時第二個返回值是訂閱的頻道名稱,第三個值是當前客戶端訂閱的頻道數量。

2)message 表示收到的訂閱消息,也是此模式的核心,其第二個值是頻道的名稱,第三個值是消息的內容。

3)unsubscribe 表示成功取消訂閱某個頻道,第二個值是取消的頻道名稱,第三個是剩餘的訂閱頻道數量,若是是0,則此時會取消訂閱模式,後面就能夠繼續輸入其餘非訂閱的命令。

四、批量訂閱模式

         命令psubscribe,支持blob模式,即相似正則的模式,如psubscribe channel.*,則訂閱全部channel開頭的頻道。

         與此相應的,punsubscribe命令支持批量取消訂閱。

 

3、管道

         redis和客戶端是用tcp進行的鏈接,所以來回傳送消息都要通過網絡,來回的總耗時稱爲消息時延。當執行多個命令時,每條命令須要執行完畢有返回的時候,下一條纔會執行。

         當須要一塊兒執行時,redis底層的通訊對管道提供了支持,當一組命令中每條命令都不依賴於前一條時,能夠一塊兒發送請求,一塊兒返回,以減小網絡通訊的次數。

 

4、空間消耗

一、複雜度

         redis爲每種數據類型都提供兩種編碼方式,例如hash,當元素不少的時候會使用散列表的方式進行存儲,時間複雜度僅O(1);可是當元素不多時,O(n)和O(1)差距不大,爲了節約內存,redis會採用內部編碼方法,用時間換空間。

         redis可使用OBJECT ENCODING key的方式,查看每一個鍵的內部編碼類型。

二、編碼

         redis在內部編碼採用結構體類型,以下:

         typedef struct redisObject{

         unsigned type:4;

         unsigned notuse:2;

         unsigned encoding:4;

         unsigned lru:22;

         int refcount;

         void *ptr;

}

type表明類型,用數字0-4表示五種類型;notuse是預留空間,未使用;ptr指針指向具體存儲的數據;encoding有9種,0-8,包括原生編碼、整型、哈希表、zipmap、雙向鏈表、ziplist、skiplist、字符串。針對redis的五種數據類型,分別有不一樣的encoding方式,以下圖所示:(來自網絡)

 

三、字符串優化

         字符串存儲在一個結構體,包括字符串長度、具體內容、剩餘空間。當執行set命令,要佔用30字節,而當鍵值是64位的整數,則ptr指針會直接指向值,而不是指向結構體,能夠節約到16字節。

         當存儲的是0-9999時,redis因爲會默認存儲這些數字,則ptr指針直接指向引用,佔用0字節的空間。

四、散列優化

         在配置文件中設置hash-max-ziplist-entries和hash-max-ziplist-value,當散列的鍵的個數少於entiries值,且每一個鍵值都小於value值,則會使用ziplist的方式編碼,不然用哈希表來編碼。ziplist犧牲時間換空間,哈希表犧牲空間換時間,所以數據少用ziplist,多的時候用哈希表。

         所以,兩個參數不宜設置的太大。

五、列表優化

         列表和散列類似,有list-max-ziplist-entries和list-max-ziplist-value來配置。編碼方式包括ziplist、雙向鏈表、quicklist,quicklist結合ziplist和雙向鏈表的有點,達到減小空間的同時適當減小時間。

六、集合優化

         配置文件配置set-max-intset-entries,小於時採用intset編碼,不然用哈希表。intset使得集合內部有序排列,便於用二分法進行查找,可是添加和刪除則須要進行排序,元素多的時候速度慢。

七、有序集合優化

         配置文件配置zset-max-ziplist-entries和zset-max-ziplist-value。包括ziplist和skiplist編碼方式,skiplist是使用哈希表和跳躍列表兩種結構來存儲,哈希表用來存儲分數的映射,跳躍列表用來存儲分數和元素值的映射。

 

 

——written by linhxx

 

更多最新文章,歡迎關注微信公衆號「決勝機器學習」,或掃描右邊二維碼。

相關文章
相關標籤/搜索