Redis各個數據類型的使用場景

Redis支持五種數據類型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合)。css

Redis列表命令

參考:http://www.redis.net.cn/tutorial/3501.htmlhtml


使用場景

String

String數據結構是簡單的key-value類型,value其實不只能夠是String,也能夠是數字。 
常規key-value緩存應用; 
常規計數:微博數,粉絲數等。nginx

hash

Redis hash是一個string類型的field和value的映射表,hash特別適合用於存儲對象。 
存儲部分變動的數據,如用戶信息等。web

list

list就是鏈表,略有數據結構知識的人都應該能理解其結構。使用Lists結構,咱們能夠輕鬆地實現最新消息排行等功能。List的另外一個應用就是消息隊列,能夠利用List的PUSH操做,將任務存在List中,而後工做線程再用POP操做將任務取出進行執行。Redis還提供了操做List中某一段的api,你能夠直接查詢,刪除List中某一段的元素。 
Redis的list是每一個子元素都是String類型的雙向鏈表,能夠經過push和pop操做從列表的頭部或者尾部添加或者刪除元素,這樣List便可以做爲棧,也能夠做爲隊列。redis

消息隊列系統 
使用list能夠構建隊列系統,使用sorted set甚至能夠構建有優先級的隊列系統。 
好比:將Redis用做日誌收集器 
實際上仍是一個隊列,多個端點將日誌信息寫入Redis,而後一個worker統一將全部日誌寫到磁盤。數據庫

取最新N個數據的操做api

//把當前登陸人添加到鏈表裏
ret = r.lpush("login:last_login_times", uid) //保持鏈表只有N位 ret = redis.ltrim("login:last_login_times", 0, N-1) //得到前N個最新登錄的用戶Id列表 last_login_list = r.lrange("login:last_login_times", 0, N-1)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

好比sina微博: 
在Redis中咱們的最新微博ID使用了常駐緩存,這是一直更新的。可是作了限制不能超過5000個ID,所以獲取ID的函數會一直詢問Redis。只有在start/count參數超出了這個範圍的時候,才須要去訪問數據庫。 
系統不會像傳統方式那樣「刷新」緩存,Redis實例中的信息永遠是一致的。SQL數據庫(或是硬盤上的其餘類型數據庫)只是在用戶須要獲取「很遠」的數據時纔會被觸發,而主頁或第一個評論頁是不會麻煩到硬盤上的數據庫了。緩存

set

set就是一個集合,集合的概念就是一堆不重複值的組合。利用Redis提供的set數據結構,能夠存儲一些集合性的數據。set中的元素是沒有順序的。 
案例: 
在微博應用中,能夠將一個用戶全部的關注人存在一個集合中,將其全部粉絲存在一個集合。Redis還爲集合提供了求交集、並集、差集等操做,能夠很是方便的實現如共同關注、共同喜愛、二度好友等功能,對上面的全部集合操做,你還可使用不一樣的命令選擇將結果返回給客戶端仍是存集到一個新的集合中。ruby

交集,並集,差集數據結構

//book表存儲book名稱 set book:1:name "The Ruby Programming Language" set book:2:name "Ruby on rail" set book:3:name "Programming Erlang" //tag表使用集合來存儲數據,由於集合擅長求交集、並集 sadd tag:ruby 1 sadd tag:ruby 2 sadd tag:web 2 sadd tag:erlang 3 //即屬於ruby又屬於web的書? inter_list = redis.sinter("tag:web", "tag:ruby") //即屬於ruby,但不屬於web的書? diff_list = redis.sdiff("tag:ruby", "tag:web") //屬於ruby和屬於web的書的合集? union_list = redis.sunion("tag:ruby", "tag:web")
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

獲取某段時間全部數據去重值 
這個使用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裏 zadd login:login_times 5 1 zadd login:login_times 1 2 zadd login:login_times 2 3 //當用戶登陸時,對該用戶的登陸次數自增1 ret = r.zincrby("login:login_times", 1, uid) //那麼如何得到登陸次數最多的用戶呢,逆序排列取得排名前N的用戶 ret = r.zrevrange("login:login_times", 0, N-1)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

好比在線遊戲的排行榜,根據得分你一般想要:

- 列出前100名高分選手

     - 列出某用戶當前的全球排名

這些操做對於Redis來講小菜一碟,即便你有幾百萬個用戶,每分鐘都會有幾百萬個新的得分。 
模式是這樣的,每次得到新得分時,咱們用這樣的代碼:

ZADD leaderboard <score> <username>
  • 1

你可能用userID來取代username,這取決於你是怎麼設計的。 
獲得前100名高分用戶很簡單:

ZREVRANGE leaderboard 0 99
  • 1

用戶的全球排名也類似,只須要:

ZRANK leaderboard <username>
  • 1

須要精準設定過時時間的應用 
好比你能夠把上面說到的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值:

redis 127.0.0.1:6379> zadd ranges 10 A_start 1 redis 127.0.0.1:6379> zadd ranges 20 A_end 1 redis 127.0.0.1:6379> zadd ranges 30 B_start 1 redis 127.0.0.1:6379> zadd ranges 40 B_end 1
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

這樣數據在插入sorted set後,至關因而將這些起始位置按順序排列好了。 
如今我須要查找15這個值在哪個範圍中,只須要進行以下的zrangbyscore查找:

redis 127.0.0.1:6379> zrangebyscore ranges (15 +inf LIMIT 0 1 1) "A_end"
  • 1
  • 2

這個命令的意思是在Sorted Sets中查找大於15的第一個值。(+inf在Redis中表示正無窮大,15前面的括號表示>15而非>=15) 
查找的結果是A_end,因爲全部值是按順序排列的,因此能夠斷定15是在A_start到A_end區間上,也就是說15是在A這個範圍裏。至此大功告成。 
固然,若是你查找到的是一個start,好比我們用25,執行下面的命令:

redis 127.0.0.1:6379> zrangebyscore ranges (25 +inf LIMIT 0 1 1) "B_start"
  • 1
  • 2

返回結果代表其下一個節點是一個start節點,也就是說25這個值不處在任何start和end之間,不屬於任何範圍。 
固然,這個例子僅適用於相似上面的IP範圍查找的案例,由於這些值範圍之間沒有重合。若是是有重合的狀況,這個問題自己也就變成了一個一對多的問題。

Pub/Sub

Pub/Sub 從字面上理解就是發佈(Publish)與訂閱(Subscribe),在Redis中,你能夠設定對某一個key值進行消息發佈及消息訂閱,當一個key值上進行了消息發佈後,全部訂閱它的客戶端都會收到相應的消息。這一功能最明顯的用法就是用做實時消息系統,好比普通的即時聊天,羣聊等功能。

使用場景

Pub/Sub構建實時消息系統

Redis的Pub/Sub系統能夠構建實時的消息系統 
好比不少用Pub/Sub構建的實時聊天系統的例子。

參考: 
http://www.redis.net.cn/tutorial/3501.html 
http://www.cnblogs.com/markhe/p/5689356.html 
http://www.cnblogs.com/ggjucheng/p/3349102.html

相關文章
相關標籤/搜索