Redis使用情境

來源:互聯網
上載者:User

標籤:

一.Redis開創了一種新的資料存放區思路,使用Redis,我們不用在面對功能單調的資料庫時,把精力放在如何把大象放進冰箱這樣的問題上,而是利用Redis靈活多變的資料結構和資料操作,為不同的大象構建不同的冰箱。

Redis常用資料類型

Redis最為常用的資料類型主要有以下五種:

String
Hash
List
Set
Sorted set

下面我們先來逐一的分析下這五種資料類型的使用和內部實現方式:

String
常用命令:

set,get,decr,incr,mget 等。

應用情境:

String是最常用的一種資料類型,普通的key/value儲存都可以歸為此類,這裡就不所做解釋了。

實現方式:

String在redis內部儲存預設就是一個字串,被redisObject所引用,當遇到incr,decr等操作時會轉成數值型進行計算,此時redisObject的encoding欄位為int。

Hash
常用命令:

hget,hset,hgetall 等。

應用情境:

我們簡單舉個執行個體來描述下Hash的應用情境,比如我們要儲存一個使用者資訊對象資料,包含以下資訊:

使用者ID為尋找的key,儲存的value使用者物件包含姓名,年齡,生日等資訊,如果用普通的key/value結構來儲存,主要有以下2種儲存方式:

 

第一種方式將使用者ID作為尋找key,把其他資訊封裝成一個對象以序列化的方式儲存,這種方式的缺點是,增加了序列化/還原序列化的開銷,並且在需要修改其中一項資訊時,需要把整個對象取回,並且修改操作需要對並發進行保護,引入CAS等複雜問題。

 

第二種方法是這個使用者資訊對象有多少成員就存成多少個key-value對兒,用使用者ID+對應屬性的名稱作為唯一標識來取得對應屬性的值,雖然省去了序列化開銷和並發問題,但是使用者ID為重複儲存,如果存在大量這樣的資料,記憶體浪費還是非常可觀的。

那麼Redis提供的Hash很好的解決了這個問題,Redis的Hash實際是內部儲存的Value為一個HashMap,並提供了直接存取這個Map成員的介面,如:

 

也就是說,Key仍然是使用者ID, value是一個Map,這個Map的key是成員的屬性名稱,value是屬性值,這樣對資料的修改和存取都可以直接通過其內部Map的Key(Redis裡稱內部Map的key為field), 也就是通過 key(使用者ID) + field(屬性標籤) 就可以操作對應屬性資料了,既不需要重複儲存資料,也不會帶來序列化和並發修改控制的問題。很好的解決了問題。

這裡同時需要注意,Redis提供了介面(hgetall)可以直接取到全部的屬性資料,但是如果內部Map的成員很多,那麼涉及到遍曆整個內部Map的操作,由於Redis單執行緒模式的緣故,這個遍曆操作可能會比較耗時,而另其它用戶端的請求完全不響應,這點需要格外注意。

實現方式:

上面已經說到Redis Hash對應Value內部實際就是一個HashMap,實際這裡會有2種不同實現,這個Hash的成員比較少時Redis為了節省記憶體會採用類似一維數組的方式來緊湊儲存,而不會採用真正的HashMap結構,對應的value redisObject的encoding為zipmap,當成員數量增大時會自動轉成真正的HashMap,此時encoding為ht。

List
常用命令:

lpush,rpush,lpop,rpop,lrange等。

應用情境:

Redis list的應用情境非常多,也是Redis最重要的資料結構之一,比如twitter的關注列表,粉絲列表等都可以用Redis的list結構來實現,比較好理解,這裡不再重複。

實現方式:

Redis list的實現為一個雙向鏈表,即可以支援反向尋找和遍曆,更方便操作,不過帶來了部分額外的記憶體開銷,Redis內部的很多實現,包括髮送緩衝隊列等也都是用的這個資料結構。

Set
常用命令:

sadd,spop,smembers,sunion 等。

應用情境:

Redis set對外提供的功能與list類似是一個列表的功能,特殊之處在於set是可以自動排重的,當你需要儲存一個列表資料,又不希望出現重複資料時,set是一個很好的選擇,並且set提供了判斷某個成員是否在一個set集合內的重要介面,這個也是list所不能提供的。

實現方式:

set 的內部實現是一個 value永遠為null的HashMap,實際就是通過計算hash的方式來快速排重的,這也是set能提供判斷一個成員是否在集合內的原因。

Sorted set

常用命令:

zadd,zrange,zrem,zcard等

使用情境:

Redis sorted set的使用情境與set類似,區別是set不是自動有序的,而sorted set可以通過使用者額外提供一個優先順序(score)的參數來為成員排序,並且是插入有序的,即自動排序。當你需要一個有序的並且不重複的集合列表,那麼可以選擇sorted set資料結構,比如twitter 的public timeline可以以發表時間作為score來儲存,這樣擷取時就是自動按時間排好序的。

實現方式:

Redis sorted set的內部使用HashMap和跳躍表(SkipList)來保證資料的儲存和有序,HashMap裡放的是成員到score的映射,而跳躍表裡存放的是所有的成員,排序依據是HashMap裡存的score,使用跳躍表的結構可以獲得比較高的尋找效率,並且在實現上比較簡單。

http://www.cnblogs.com/shanyou/archive/2012/09/04/2670972.html


二.新浪微博:史上最大的Redis叢集

Tape is Dead,Disk is Tape,Flash is Disk,RAM Locality is King. — Jim Gray

Redis不是比較成熟的memcache或者Mysql的替代品,是對於大型互連網類應用在架構上很好的補充。現在有越來越多的應用也在紛紛基於Redis做架構的改造。首先簡單公布一下Redis平台實際情況:

2200+億 commands/day 5000億Read/day 500億Write/day
18TB+ Memory
500+ Servers in 6 IDC 2000+instances
應該是國內外比較大的Redis使用平台,今天主要從應用角度談談Redis服務平台。


Pinterest:Reids維護上百億的相關性

Pinterest已經成為矽谷最瘋故事之一,在2012年,他們基於PC的業務增加1047%,移動端採用增加1698%, 該年3月其獨立訪問數量更飆升至533億。在Pinterest,人們關注的事物以百億記——每個使用者介面都會查詢某個board或者是使用者是否關注的行為促成了異常複雜的工程問題。這也讓Redis獲得了用武之地。經過數年的發展,Pinterest已經成為媒體、社交等多個領域的佼佼者,其輝煌戰績如下:

獲得的推薦流量高於Google+、YouTube及LinkedIn三者的總和
與Facebook及Twitter一起成為最流行的三大社交網路
參考Pinterest進行購買的使用者比其它網站更高( 更多詳情)
如您所想,基於其獨立訪問數,Pinterest的高規模促成了一個非常高的IT基礎設施需求。

通過緩衝來最佳化使用者體驗

近日,Pinterest工程經理Abhi Khune對其公司的使用者體驗需求及Redis的使用經驗 進行了分享。即使是滋生的應用程式打造者,在分析網站的細節之前也不會理解這些特性,因此先大致的理解一下使用情境:首先,為每個粉絲進行提及到的預檢查;其次,UI將準確的顯示使用者的粉絲及關注列表分頁。高效的執行這些操作,每次點擊都需要非常高的效能架構。

不能免俗,Pinterest的軟體工程師及架構師已經使用了MySQL及memcache,但是緩衝解決方案仍然達到了他們的瓶頸;因此為了擁有更好的使用者體驗,緩衝必須被擴充。而在實際操作過程中,工程團隊已然發現緩衝只有當使用者sub-graph已經在緩衝中時才會起到作用。因此。任何使用這個系統的人都需要被緩衝,這就導致了整個圖的緩衝。同時,最常見的查詢“使用者A是否關注了使用者B”的答案經常是否定的,然而這卻被作為了緩衝丟失,從而促成一個資料庫查詢,因此他們需要一個新的方法來擴充緩衝。最終,他們團隊決定使用Redis來儲存整個圖,用以服務眾多的列表。

使用Redis儲存大量的Pinterest列表

Pinterest使用了Redis作為解決方案,並將效能推至了記憶體資料庫等級,為使用者儲存多種類型列表:

粉絲列表
你所關注的board列表
粉絲列表
關注你board的使用者列表
某個使用者中board中你沒有關注的列表
每個board的粉絲及非粉絲
Redis為其7000萬使用者儲存了以上的所有列表,本質上講可以說是儲存了所有粉絲圖,通過使用者ID分區。鑒於你可以通過類型來查看以上列表的資料,分析概要資訊被用看起來更像事務的系統儲存及訪問。Pinterest當下的使用者like被限制為10萬,初略進行統計:如果每個使用者關注25個board,將會在使用者及board間產生17.5億的關係。同時更加重要的是,這些關係隨著系統的使用每天都會增加。

Pinterest的Reids架構及運營

通過Pinterest的一個創始人瞭解到,Pinterest開始使用Python及訂製的Django編寫應用程式,並一直持續到其擁有1800萬使用者級日410TB使用者資料的時候。雖然使用了多個儲存對資料進行儲存,工程師根據使用者id使用了8192個虛擬分區,每個分區都運行在一個Redis DB之上,同時1個Redis執行個體將運行多個Redis DB。為了對CPU核心的充分使用,同一台主機上同時使用多線程和單線程Redis執行個體。

鑒於整個資料集運行在記憶體當中,Redis在Amazon EBS上對每秒傳輸進來的寫入都會進行持久化。擴充主要通過兩個方面進行:第一,保持50%的利用率,通過主從轉換,機器上啟動並執行Redis執行個體一半會轉譯到一個新機器上;第二,擴充節點和分區。整個Redis叢集都會使用一個主從配置,從部分將被當做一個熱備份。一旦主節點失敗,從部分會立刻完成主的轉換,同時一個新的從部分將會被添加,ZooKeeper將完成整個過程。同時他們每個小時都會在Amazon S3上運行BGsave做更持久的儲存——這項Reids操作會在後端進行,之後Pinterest會使用這些資料做MapReduce和分析作業。(更多內容見原文)

國內外三個不同領域巨頭分享的Redis實戰經驗及使用情境, http://www.csdn.net/article/2013-10-07/2817107-three-giant-share-redis-experience/1


三.Redis的一個很大好處就是可以不用整個轉入到這個資料庫,而是可以沿用之前的MySQL等資料庫,而僅在一些特定的應用情境通過Redis的特性提高效率。本文列出了11個這樣的Web應用情境,如顯示最新的項目列表、刪除和過濾、熱門排行榜等相關需求。

下面列出11種Web應用情境,在這些情境下可以充分的利用Redis的特性,大大提高效率。

1.在首頁中顯示最新的項目列表。

Redis使用的是常駐記憶體的緩衝,速度非常快。LPUSH用來插入一個內容ID,作為關鍵字儲存在列表頭部。LTRIM用來限制列表中的項目數最多為5000。如果使用者需要的檢索的資料量超越這個緩衝容量,這時才需要把請求發送到資料庫。

2.刪除和過濾。

如果一篇文章被刪除,可以使用LREM從緩衝中徹底清除掉。

3.熱門排行榜及相關問題。

熱門排行榜(leader board)按照得分進行排序。ZADD命令可以直接實現這個功能,而ZREVRANGE命令可以用來按照得分來擷取前100名的使用者,ZRANK可以用來擷取使用者排名,非常直接而且操作容易。

4.按照使用者投票和時間排序。

這就像Reddit的熱門排行榜,得分會隨著時間變化。LPUSH和LTRIM命令結合運用,把文章添加到一個列表中。一項背景工作用來擷取列表,並重新計算資料行表的排序,ZADD命令用來按照新的順序填充產生列表。列表可以實現非常快速的檢索,即使是負載很重的網站。

5.到期項目處理。

使用unix時間作為關鍵字,用來保持列表能夠按時間排序。對current_time和time_to_live進行檢索,完成尋找到期項目的艱巨任務。另一項背景工作使用ZRANGE...WITHSCORES進行查詢,刪除到期的條目。

6.計數。

進行各種資料統計的用途是非常廣泛的,比如想知道什麼時候封鎖一個IP地址。INCRBY命令讓這些變得很容易,通過原子遞增保持計數;GETSET用來重設計數器;到期屬性用來確認一個關鍵字什麼時候應該刪除。

7.特定時間內的特定項目。

這是特定訪問者的問題,可以通過給每次頁面瀏覽使用SADD命令來解決。SADD不會將已經存在的成員添加到一個集合。

8.即時分析正在發生的情況,用於資料統計與防止垃圾郵件等。

使用Redis原語命令,更容易實施垃圾郵件過濾系統或其他即時跟蹤系統。

9.Pub/Sub。

在更新中保持使用者對資料的映射是系統中的一個普遍任務。Redis的pub/sub功能使用了SUBSCRIBE、UNSUBSCRIBE和PUBLISH命令,讓這個變得更加容易。

10.隊列。

在當前的編程中隊列隨處可見。除了push和pop類型的命令之外,Redis還有阻塞隊列的命令,能夠讓一個程式在執行時被另一個程式添加到隊列。你也可以做些更有趣的事情,比如一個旋轉更新的RSS feed隊列。

11.緩衝。

Redis緩衝使用的方式與memcache相同。

網路應用不能無休止地進行模型的戰爭,看看這些Redis的原語命令,儘管簡單但功能強大,把它們加以組合,所能完成的就更無法想象。當然,你可以專門編寫代碼來完成所有這些操作,但Redis實現起來顯然更為輕鬆。

http://os.51cto.com/art/201107/278292.htm


四.Redis 的 5 個常見使用情境

在這篇文章中,我們將闡述 Redis 最常用的使用情境,以及那些影響我們選擇的不同特性。

1、會話緩衝(Session Cache)

最常用的一種使用Redis的情景是會話緩衝(session cache)。用Redis緩衝會話比其他儲存(如Memcached)的優勢在於:Redis提供持久化。當維護一個不是嚴格要求一致性的緩衝時,如果使用者的購物車資訊全部丟失,大部分人都會不高興的,現在,他們還會這樣嗎?

幸運的是,隨著 Redis 這些年的改進,很容易找到怎麼恰當的使用Redis來緩衝會話的文檔。甚至廣為人知的商業平台Magento也提供Redis的外掛程式。

2、全頁緩衝(FPC)

除基本的會話token之外,Redis還提供很簡便的FPC平台。回到一致性問題,即使重啟了Redis執行個體,因為有磁碟的持久化,使用者也不會看到頁面載入速度的下降,這是一個極大改進,類似PHP本地FPC。

再次以Magento為例,Magento提供一個外掛程式來使用Redis作為全頁緩衝後端。

此外,對WordPress的使用者來說,Pantheon有一個非常好的外掛程式 wp-redis,這個外掛程式能協助你以最快速度載入你曾瀏覽過的頁面。

3、隊列

Reids在記憶體儲存引擎領域的一大優點是提供 list 和 set 操作,這使得Redis能作為一個很好的訊息佇列平台來使用。Redis作為隊列使用的操作,就類似於本地程式語言(如Python)對 list 的 push/pop 操作。

如果你快速的在Google中搜尋“Redis queues”,你馬上就能找到大量的開源項目,這些項目的目的就是利用Redis建立非常好的後端工具,以滿足各種隊列需求。例如,Celery有一個後台就是使用Redis作為broker,你可以從這裡去查看。

4.熱門排行榜/計數器

Redis在記憶體中對數字進行遞增或遞減的操作實現的非常好。集合(Set)和有序集合(Sorted Set)也使得我們在執行這些操作的時候變的非常簡單,Redis只是正好提供了這兩種資料結構。所以,我們要從排序集合中擷取到排名最靠前的10個使用者–我們稱之為“user_scores”,我們只需要像下面一樣執行即可:

當然,這是假定你是根據你使用者的分數做遞增的排序。如果你想返回使用者及使用者的分數,你需要這樣執行:

ZRANGE user_scores 0 10 WITHSCORES

Agora Games就是一個很好的例子,用Ruby實現的,它的熱門排行榜就是使用Redis來儲存資料的,你可以在這裡看到。

5、發布/訂閱

最後(但肯定不是最不重要的)是Redis的發布/訂閱功能。發布/訂閱的使用情境確實非常多。我已看見人們在社交網路串連中使用,還可作為基於發布/訂閱的指令碼觸發器,甚至用Redis的發布/訂閱功能來建立聊天系統!(不,這是真的,你可以去核實)。

Redis提供的所有特性中,我感覺這個是喜歡的人最少的一個,雖然它為使用者提供如果此多功能。

等等?

親愛的讀者,你是怎麼認為的呢?你會在什麼情況使用Redis呢?

http://blog.jobbole.com/88383/


五.Redis作者談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_list
END
如果你還有不同的篩選維度,比如某個分類的最新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,資料結構更多樣化。

http://blog.nosqlfan.com/html/2235.html

 

延伸閱讀:
Redis複製與可擴充叢集搭建, http://www.infoq.com/cn/articles/tq-redis-copy-build-scalable-cluster
Redis應用情境, http://blog.csdn.net/hguisu/article/details/8836819

http://www.baidu.com/s?wd=redis使用情境
http://www.sogou.com/web?query=redis使用情境
https://www.so.com/s?q=redis使用情境
http://blog.nosqlfan.com/topics/redis

Redis使用情境

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.