標籤:
記憶體資料庫Redis --主要是為瞭解決實現熱點資料區塊的加速。
毫無疑問,Redis開創了一種新的資料存放區思路,使用Redis,我們不用在面對功能單調的資料庫時,把精力放在如何把大象放進冰箱這樣的問題上,而是利用Redis靈活多變的資料結構和資料操作,為不同的大象構建不同的冰箱。希望你喜歡這個比喻。
下面是一篇新鮮出爐的文章,其作者是Redis作者@antirez,他描述了Redis比較適合的一些應用情境,NoSQLFan簡單列舉在這裡,供大家一覽:
1.取最新N個資料的操作
比如典型的取你網站的最新文章,通過下面方式,我們可以將最新的5000條評論的ID放在Redis的List集合中,並將超出集合部分從資料庫擷取
- 使用LPUSH latest.comments<ID>命令,向list集合中插入資料
- 插入完成後再用LTRIM latest.comments 0 5000命令使其永遠只儲存最近5000個ID
- 然後我們在用戶端擷取某一頁評論時可以用下面的邏輯(虛擬碼)
FUNCTION get_latest_comments(start,num_items): id_list = redis.lrange("latest.comments",start,start+num_items-1) IF id_list.length < num_items id_list = SQL_DB("SELECT ... ORDER BY time LIMIT ...") END RETURN id_listEND
如果你還有不同的篩選維度,比如某個分類的最新N條,那麼你可以再建一個按此分類的List,只存ID的話,Redis是非常高效的。
2.熱門排行榜應用,取TOP N操作
這個需求與上面需求的不同之處在於,前面操作以時間為權重,這個是以某個條件為權重,比如按頂的次數排序,這時候就需要我們的sorted set出馬了,將你要排序的值設定成sorted set的score,將具體的資料設定成相應的value,每次只需要執行一條ZADD命令即可。
3.需要精準設定到期時間的應用
比如你可以把上面說到的sorted set的score值設定成到期時間的時間戳記,那麼就可以簡單地通過到期時間排序,定時清除到期資料了,不僅是清除Redis中的到期資料,你完全可以把Redis裡這個到期時間當成是對資料庫中資料的索引,用Redis來找出哪些資料需要到期刪除,然後再精準地從資料庫中刪除相應的記錄。
4.計數器應用
Redis的命令都是原子性的,你可以輕鬆地利用INCR,DECR命令來構建計數器系統。
5.Uniq操作,擷取某段時間所有資料排重值
這個使用Redis的set資料結構最合適了,只需要不斷地將資料往set中扔就行了,set意為集合,所以會自動排重。
6.即時系統,反垃圾系統
通過上面說到的set功能,你可以知道一個終端使用者是否進行了某個操作,可以找到其操作的集合并進行分析統計對比等。沒有做不到,只有想不到。
7.Pub/Sub構建即時訊息系統
Redis的Pub/Sub系統可以構建即時的訊息系統,比如很多用Pub/Sub構建的即時聊天系統的例子。
8.構建隊列系統
使用list可以構建隊列系統,使用sorted set甚至可以構建有優先順序的隊列系統。
9.緩衝
這個不必說了,效能優於Memcached,資料結構更多樣化。
REDIS 在電商中的實際應用情境
話說使用Redis已經有好一段時間,趁有點時間,結合Guang.com 使用經驗,總結一下Redis 在社會化電商網站的實際應用情境。文筆較差,各位看官,湊合著看下吧。
1. 各種計數,商品維度計數和使用者維度計數
說起電商,肯定離不開商品,而附帶商品有各種計數(喜歡數,評論數,評鑑數,瀏覽數,etc),Redis的命令都是原子性的,你可以輕鬆地利用INCR,DECR等命令來計數。
- 商品維度計數(喜歡數,評論數,評鑑數,瀏覽數,etc)
採用Redis 的類型: Hash
. 如果你對redis資料類型不太熟悉,可以參考 http://redis.io/topics/data-types-intro
為product定義個key product:
,為每種數值定義hashkey, 譬如喜歡數xihuan
redis> HSET product:1231233 xihuan 5(integer) 1redis> HINCRBY product:1231233 xihuan 1 //喜歡數+1(integer) 6 redis> HGETALL product:1231233 //擷取這key hashkey 和value1) "xihuan"2) "6"
- 使用者維度計數(動態數、關注數、粉絲數、喜歡商品數、發帖數 等)
使用者維度計數同商品維度計數都採用 Hash
. 為User定義個key user:
,為每種數值定義hashkey, 譬如關注數follow
redis> HSET user:100000 follow 5(integer) 1redis> HINCRBY user:100000 follow 1 //關注數+1(integer) 6 redis> HGETALL user:100000 //擷取這key hashkey 和value1) "follow"2) "6"
2. 儲存社交關係
譬如將用戶的好友/粉絲/關注,可以存在一個sorted set
中,score可以是timestamp,這樣求兩個人的共同好友的操作,可能就只需要用求交集命令即可。
redis> ZADD user:100000:follow 61307510400000 "100001" //score 為timestamp(integer) 1redis> ZADD user:100000:follow 61307510402300 "100002"(integer) 1redis> ZADD user:100000:follow 61307510405600 "100003"(integer) 1redis> ZADD user:200000:follow 61307510400000 "100001"(integer) 1redis> ZADD user:200000:follow 61307510402300 "100005"(integer) 1redis> ZADD user:200000:follow 61307510405600 "100004"(integer) 1redis> ZINTERSTORE out:100000:200000 1 user:100000:follow user:200000:follow //交集命令,獲得共同關注(integer) 2redis> ZRANGE out:100000:200000 0 -11) "100001"
3. 用作緩衝代替memcached(商品列表,評論列表,@提示列表,etc)
相對memcached 簡單的key-value儲存來說,redis眾多的資料結構(list,set,sorted set,hash, etc)可以更方便cache各種業務資料,效能也不亞於memcached。
NOTE: RPUSH pagewviews.user: EXPIRE pagewviews.user: 60 //注意要update timeout
4. 反spam系統(評論,發布商品,論壇發貼,etc)
作為一個電商網站被各種spam攻擊是少不免(垃圾評論、發布垃圾商品、廣告、刷自家商品排名等),針對這些spam制定一系列anti-spam規則,其中有些規則可以利用redis做即時分析,譬如:1分鐘評論不得超過2次、5分鐘評論少於5次等(更多機制/規則需要結合drools )。 採用sorted set
將最近一天使用者操作記錄起來(為什麼不全部記錄?節省memory,全部操作會記錄到log,後續利用hadoop進行更全面分析統計),通過ZRANGEBYSCORE user:200000:operation:comment 61307510405600 +inf
獲得1分鐘內的操作記錄, redis> ZADD user:200000:operation:comment 61307510402300 "這是一條評論" //score 為timestamp (integer) 1 redis> ZRANGEBYSCORE user:200000:operation:comment 61307510405600 +inf//獲得1分鐘內的操作記錄 1) "這是一條評論"
BTW, 更複雜一點的即時計算可以採用Storm。
5. 使用者Timeline/Feeds
在逛 有個類似微博的欄目我關注,裡麵包括關注的人、主題、品牌的動態。redis在這邊主要當作cache使用。
redis> ZADD user:100000:feed:topic 61307510400000 <feedId> //score 為timestamp(integer) 1redis> EXPIRE user:100000:feed:topic 24*60*60 //set timeout to one day(integer) 1redis> ZADD user:100000:feed:friend 61307510400000 <feedId> //不同類型feed(integer) 1redis> EXPIRE user:100000:feed:friend 24*60*60 //set timeout(integer) 1
6. 最新列表&熱門排行榜(使用者剛剛喜歡的商品,etc)
這裡採用Redis的List
資料結構或sorted set
結構, 方便實現最新列表or熱門排行榜 等業務情境。
7. 訊息通知
其實這業務情境也可以算在計數上,也是採用Hash
。如下:
redis> HSET user:<userId>:message:ur system 1//1條未讀系統訊息(integer) 1redis> HINCRBY user:<userId>:message:ur system 1 //未讀系統訊息+1(integer) 2redis> HINCRBY user:<userId>:message:ur comment 1 //未讀評論訊息+1(integer) 1redis> HSET user:<userId>:message:ur system 0//設為系統訊息已讀(integer) 1redis> HGETALL user:<userId>:message:ur //擷取這key hashkey 和value1) "system"2) "0"3) "comment"4) "1"
8. 將Redis用作訊息佇列
當在叢集環境時候,java ConcurrentLinkedQueue
就無法滿足我們需求,此時可以採用Redis的List資料結構實現分布式的訊息佇列。
Redis中5種資料結構的使用情境介紹這篇文章主要介紹了Redis中5種資料結構的使用情境介紹,本文對Redis中的5種資料類型String、Hash、List、Set、Sorted Set做了講解,需要的朋友可以參考下
一、redis 資料結構使用情境
原來看過 redisbook 這本書,對 redis 的準系統都已經熟悉了,從上周開始看 redis 的源碼。目前目標是吃透 redis 的資料結構。我們都知道,在 redis 中一共有5種資料結構,那每種資料結構的使用情境都是什麼呢?
String——字串
Hash——字典
List——列表
Set——集合
Sorted Set——有序集合
下面我們就來簡單說明一下它們各自的使用情境:
1. String——字串
String 資料結構是簡單的 key-value 類型,value 不僅可以是 String,也可以是數字(當數字類型用 Long 可以表示的時候encoding 就是整型,其他都儲存在 sdshdr 當做字串)。使用 Strings 類型,可以完全實現目前 Memcached 的功能,並且效率更高。還可以享受 Redis 的定時持久化(可以選擇 RDB 模式或者 AOF 模式),動作記錄及 Replication 等功能。除了提供與 Memcached 一樣的 get、set、incr、decr 等操作外,Redis 還提供了下面一些操作:
複製代碼代碼如下:
1.LEN niushuai:O(1)擷取字串長度
2.APPEND niushuai redis:往字串 append 內容,而且採用智能分配記憶體(每次2倍)
3.設定和擷取字串的某一段內容
4.設定及擷取字串的某一位(bit)
5.大量設定一系列字串的內容
6.原子計數器
7.GETSET 命令的妙用,請於清空舊值的同時設定一個新值,配合原子計數器使用
2. Hash——字典
在 Memcached 中,我們經常將一些結構化的資訊打包成 hashmap,在用戶端序列化後儲存為一個字串的值(一般是 JSON 格式),比如使用者的暱稱、年齡、性別、積分等。這時候在需要修改其中某一項時,通常需要將字串(JSON)取出來,然後進行還原序列化,修改某一項的值,再序列化成字串(JSON)儲存回去。簡單修改一個屬性就幹這麼多事情,消耗必定是很大的,也不適用於一些可能並行作業的場合(比如兩個並發的操作都需要修改積分)。而 Redis 的 Hash 結構可以使你像在資料庫中 Update 一個屬性一樣只修改某一項屬性值。
複製代碼代碼如下:
儲存、讀取、修改使用者屬性
3. List——列表
List 說白了就是鏈表(redis 使用雙端鏈表實現的 List),相信學過資料結構知識的人都應該能理解其結構。使用 List 結構,我們可以輕鬆地實現最新訊息排行等功能(比如新浪微博的 TimeLine )。List 的另一個應用就是訊息佇列,可以利用 List 的 *PUSH 操作,將任務存在 List 中,然後背景工作執行緒再用 POP 操作將任務取出進行執行。Redis 還提供了操作 List 中某一段元素的 API,你可以直接查詢,刪除 List 中某一段的元素。
複製代碼代碼如下:
1.微博 TimeLine
2.訊息佇列
4. Set——集合
Set 就是一個集合,集合的概念就是一堆不重複值的組合。利用 Redis 提供的 Set 資料結構,可以儲存一些集合性的資料。比如在微博應用中,可以將一個使用者所有的關注人存在一個集合中,將其所有粉絲存在一個集合。因為 Redis 非常人性化的為集合提供了求交集、並集、差集等操作,那麼就可以非常方便的實現如共同關注、共同喜好、二度好友等功能,對上面的所有集合操作,你還可以使用不同的命令選擇將結果返回給用戶端還是存集到一個新的集合中。
1.共同好友、二度好友
2.利用唯一性,可以統計訪問網站的所有獨立 IP
3.好友推薦的時候,根據 tag 求交集,大於某個 threshold 就可以推薦
5. Sorted Set——有序集合
和Sets相比,Sorted Sets是將 Set 中的元素增加了一個權重參數 score,使得集合中的元素能夠按 score 進行有序排列,比如一個儲存全班同學成績的 Sorted Sets,其集合 value 可以是同學的學號,而 score 就可以是其考試得分,這樣在資料插入集合的時候,就已經進行了天然的排序。另外還可以用 Sorted Sets 來做帶權重的隊列,比如普通訊息的 score 為1,重要訊息的 score 為2,然後背景工作執行緒可以選擇按 score 的倒序來擷取工作任務。讓重要的任務優先執行。
1.帶有權重的元素,比如一個遊戲的使用者得分熱門排行榜
2.比較複雜的資料結構,一般用到的情境不算太多
二、redis 其他功能使用情境
1. 訂閱-發布系統
Pub/Sub 從字面上理解就是發布(Publish)與訂閱(Subscribe),在 Redis 中,你可以設定對某一個 key 值進行訊息發布及訊息訂閱,當一個 key 值上進行了訊息發布後,所有訂閱它的用戶端都會收到相應的訊息。這一功能最明顯的用法就是用作即時訊息系統,比如普通的即時聊天,群聊等功能。
2. 事務——Transactions
誰說 NoSQL 都不支援事務,雖然 Redis 的 Transactions 提供的並不是嚴格的 ACID 的事務(比如一串用 EXEC 提交執行的命令,在執行中伺服器宕機,那麼會有一部分命令執行了,剩下的沒執行),但是這個 Transactions 還是提供了基本的命令打包執行的功能(在伺服器不出問題的情況下,可以保證一連串的命令是順序在一起執行的,中間有會有其它用戶端命令插進來執行)。Redis 還提供了一個 Watch 功能,你可以對一個 key 進行 Watch,然後再執行 Transactions,在這過程中,如果這個 Watched 的值進行了修改,那麼這個 Transactions 會發現並拒絕執行。
Redis應用情境