天天看點

Redis各個資料類型的使用場景

Redis支援五種資料類型:

string(字元串)

hash(哈希)

list(清單)

set(集合)

zset(sorted set:有序集合)。

Redis清單指令

String

String資料結構是簡單的key-value類型,value其實不僅可以是String,也可以是數字。 

正常key-value緩存應用; 

正常計數:微網誌數,粉絲數等。

hash

Redis hash是一個string類型的field和value的映射表,hash特别适合用于存儲對象。 

存儲部分變更的資料,如使用者資訊等。

list

list就是連結清單,略有資料結構知識的人都應該能了解其結構。使用Lists結構,我們可以輕松地實作最新消息排行等功能。List的另一個應用就是消息隊列,可以利用List的PUSH操作,将任務存在List中,然後工作線程再用POP操作将任務取出進行執行。Redis還提供了操作List中某一段的api,你可以直接查詢,删除List中某一段的元素。 

Redis的list是每個子元素都是String類型的雙向連結清單,可以通過push和pop操作從清單的頭部或者尾部添加或者删除元素,這樣List即可以作為棧,也可以作為隊列。

消息隊列系統 

使用list可以建構隊列系統,使用sorted set甚至可以建構有優先級的隊列系統。 

比如:将Redis用作日志收集器 

實際上還是一個隊列,多個端點将日志資訊寫入Redis,然後一個worker統一将所有日志寫到磁盤。

取最新N個資料的操作

//把目前登入人添加到連結清單裡

<code>ret = r.lpush("login:last_login_times", uid)</code>

//保持連結清單隻有N位

<code>ret = redis.ltrim("login:last_login_times", 0, N-1)</code>

//獲得前N個最新登陸的使用者Id清單

比如sina微網誌: 

在Redis中我們的最新微網誌ID使用了常駐緩存,這是一直更新的。但是做了限制不能超過5000個ID,是以擷取ID的函數會一直詢問Redis。隻有在start/count參數超出了這個範圍的時候,才需要去通路資料庫。 

系統不會像傳統方式那樣“重新整理”緩存,Redis執行個體中的資訊永遠是一緻的。SQL資料庫(或是硬碟上的其他類型資料庫)隻是在使用者需要擷取“很遠”的資料時才會被觸發,而首頁或第一個評論頁是不會麻煩到硬碟上的資料庫了。

set

set就是一個集合,集合的概念就是一堆不重複值的組合。利用Redis提供的set資料結構,可以存儲一些集合性的資料。set中的元素是沒有順序的。 

案例: 

在微網誌應用中,可以将一個使用者所有的關注人存在一個集合中,将其所有粉絲存在一個集合。Redis還為集合提供了求交集、并集、差集等操作,可以非常友善的實作如共同關注、共同喜好、二度好友等功能,對上面的所有集合操作,你還可以使用不同的指令選擇将結果傳回給用戶端還是存集到一個新的集合中。

交集,并集,差集

//book表存儲book名稱

//即屬于ruby又屬于web的書?

<code>inter_list = redis.sinter("tag:web", "tag:ruby")</code>

//即屬于ruby,但不屬于web的書?

<code>diff_list = redis.sdiff("tag:ruby", "tag:web")</code>

//屬于ruby和屬于web的書的合集?

擷取某段時間所有資料去重值 

這個使用Redis的set資料結構最合适了,隻需要不斷地将資料往set中扔就行了,set意為集合,是以會自動排重。

sorted set

和set相比,sorted set增加了一個權重參數score,使得集合中的元素能夠按score進行有序排列,比如一個存儲全班同學成績的sorted set,其集合value可以是同學的學号,而score就可以是其考試得分,這樣在資料插入集合的時候,就已經進行了天然的排序。可以用sorted set來做帶權重的隊列,比如普通消息的score為1,重要消息的score為2,然後工作線程可以選擇按score的倒序來擷取工作任務。讓重要的任務優先執行。

排行榜應用,取TOP N操作 

這個需求與上面需求的不同之處在于,前面操作以時間為權重,這個是以某個條件為權重,比如按頂的次數排序,這時候就需要我們的sorted set出馬了,将你要排序的值設定成sorted set的score,将具體的資料設定成相應的value,每次隻需要執行一條ZADD指令即可。

//将登入次數和使用者統一存儲在一個sorted set裡

//當使用者登入時,對該使用者的登入次數自增1

<code>ret = r.zincrby("login:login_times", 1, uid)</code>

//那麼如何獲得登入次數最多的使用者呢,逆序排列取得排名前N的使用者

比如線上遊戲的排行榜,根據得分你通常想要:

這些操作對于Redis來說小菜一碟,即使你有幾百萬個使用者,每分鐘都會有幾百萬個新的得分。 

模式是這樣的,每次獲得新得分時,我們用這樣的代碼:

你可能用userID來取代username,這取決于你是怎麼設計的。 

得到前100名高分使用者很簡單:

使用者的全球排名也相似,隻需要:

需要精準設定過期時間的應用 

比如你可以把上面說到的sorted set的score值設定成過期時間的時間戳,那麼就可以簡單地通過過期時間排序,定時清除過期資料了,不僅是清除Redis中的過期資料,你完全可以把Redis裡這個過期時間當成是對資料庫中資料的索引,用Redis來找出哪些資料需要過期删除,然後再精準地從資料庫中删除相應的記錄。

範圍查找 

來自Redis在Google Group上的一個問題,有一位同學發貼求助,說要解決如下的一個問題:他有一個IP範圍對應位址的清單,現在需要給出一個IP的情況下,迅速的查找到這個IP在哪個範圍,也就是要判斷此IP的所有地。這個問題引來了Redis作者Salvatore Sanfilippo(@antirez)的回答。解答如下: 

例如有下面兩個範圍,10-20和30-40

A_start 10, A_end 20

B_start 30, B_end 40 

我們将這兩個範圍的起始位置存在Redis的sorted set資料結構中,基本範圍起始值作為score,範圍名加start和end為其value值:

這樣資料在插入sorted set後,相當于是将這些起始位置按順序排列好了。 

現在我需要查找15這個值在哪一個範圍中,隻需要進行如下的zrangbyscore查找:

這個指令的意思是在Sorted Sets中查找大于15的第一個值。(+inf在Redis中表示正無窮大,15前面的括号表示&gt;15而非&gt;=15) 

查找的結果是A_end,由于所有值是按順序排列的,是以可以判定15是在A_start到A_end區間上,也就是說15是在A這個範圍裡。至此大功告成。 

當然,如果你查找到的是一個start,比如咱們用25,執行下面的指令:

傳回結果表明其下一個節點是一個start節點,也就是說25這個值不處在任何start和end之間,不屬于任何範圍。 

當然,這個例子僅适用于類似上面的IP範圍查找的案例,因為這些值範圍之間沒有重合。如果是有重合的情況,這個問題本身也就變成了一個一對多的問題。

Pub/Sub

Pub/Sub 從字面上了解就是釋出(Publish)與訂閱(Subscribe),在Redis中,你可以設定對某一個key值進行消息釋出及消息訂閱,當一個key值上進行了消息釋出後,所有訂閱它的用戶端都會收到相應的消息。這一功能最明顯的用法就是用作實時消息系統,比如普通的即時聊天,群聊等功能。

使用場景

Pub/Sub建構實時消息系統

Redis的Pub/Sub系統可以建構實時的消息系統 

比如很多用Pub/Sub建構的實時聊天系統的例子。

本文轉自 于學康 51CTO部落格,原文連結:http://blog.51cto.com/blxueyuan/2056714,如需轉載請自行聯系原作者