原文地址:http://redis.io/topics/partitioning
分區(qū):如何在多個(gè)redis實(shí)例之間分割數(shù)據(jù)
分區(qū)就是把你的數(shù)據(jù)分割到多個(gè)redis實(shí)例的過程,以便每個(gè)實(shí)例只包含你所擁有的key的子集。文檔的第一部分將向你介紹分區(qū)的概念,第二部分將向你展示區(qū)分可選擇的策略。
為什么分區(qū)是有用的
在redis服務(wù)器中的分區(qū)主要包含兩個(gè)目標(biāo):
分區(qū)基礎(chǔ)知識(shí)
這里有不同的分區(qū)標(biāo)準(zhǔn)。設(shè)想我們有4個(gè)redis實(shí)例R0,R1,R2,R3,很多 key表現(xiàn)為user:0,user:1,......等等,我們可以找到不同的方式來定位一個(gè)給定的key存儲(chǔ)在哪臺(tái)實(shí)例上。換句話說就是有不同的系統(tǒng)用來映射給定的key與給定的redis實(shí)例。
一種最簡(jiǎn)單的分區(qū)方式是范圍分區(qū),它是通過把范圍內(nèi)的對(duì)象映射到特定的redis實(shí)例來實(shí)現(xiàn)的。例如,我可以定義id 0-10000將進(jìn)入R0,而id10001-20000進(jìn)入R1等等。
這種系統(tǒng),在實(shí)踐中確實(shí)被采用,然而,它存在不足,它需要一個(gè)表用來映射范圍與redis實(shí)例。這個(gè)表是需要管理的,并且對(duì)于每種類型的對(duì)象,我們都需要一個(gè)表。通常來講,這對(duì)于redis不是個(gè)好主意。
范圍分區(qū)的一個(gè)替代方案就是hash分區(qū)。
不同的分區(qū)實(shí)現(xiàn)
由客戶端直接選擇正確的節(jié)點(diǎn)來讀寫key。
客戶端發(fā)送請(qǐng)求給代理,代理能夠通過redis協(xié)議與redis會(huì)話。代理通過配置的分區(qū)方案,確保把我們的請(qǐng)求轉(zhuǎn)發(fā)到正確的redis實(shí)例上,并且把響應(yīng)返回給客戶端。redis和memcached代理Twemproxy實(shí)現(xiàn)了代理輔助分區(qū)。
你可以發(fā)送你的請(qǐng)求到一個(gè)隨機(jī)的實(shí)例,這個(gè)實(shí)例將確保把你的請(qǐng)求轉(zhuǎn)發(fā)到正確的實(shí)例。在客戶端的幫助下,redis集群實(shí)現(xiàn)了混合形式的查詢路由(請(qǐng)求不是直接從一個(gè)redis實(shí)例轉(zhuǎn)發(fā)到另外一個(gè)實(shí)例,而是客戶端獲得重定向后,訪問正確的節(jié)點(diǎn))
分區(qū)的不足
redis的一些特性在分區(qū)方面表現(xiàn)的不是很好:
-
涉及多個(gè)key的操作通常是不被支持的。舉例來說,當(dāng)兩個(gè)set映射到不同的redis實(shí)例上時(shí),你就不能對(duì)這兩個(gè)set執(zhí)行交集操作。
-
涉及多個(gè)key的redis事務(wù)不能使用。
-
當(dāng)使用分區(qū)時(shí),數(shù)據(jù)處理較為復(fù)雜,比如你需要處理多個(gè)rdb/aof文件,并且從多個(gè)實(shí)例和主機(jī)備份持久化文件。
-
增加或刪除容量也比較復(fù)雜。redis集群大多數(shù)支持在運(yùn)行時(shí)增加、刪除節(jié)點(diǎn)的透明數(shù)據(jù)平衡的能力,但是類似于客戶端分區(qū)、代理等其他系統(tǒng)則不支持這項(xiàng)特性。然而,一種叫做presharding的技術(shù)對(duì)此是有幫助的。
數(shù)據(jù)是要存儲(chǔ)還是緩存?
當(dāng)使用redis作為數(shù)據(jù)存儲(chǔ)和緩存時(shí),分區(qū)在概念上是相同的,然而這里還是有很大的不同。當(dāng)redis作為數(shù)據(jù)存儲(chǔ)使用時(shí),你必須確定,一個(gè)給定的key應(yīng)該總是映射到同一個(gè)實(shí)例上,當(dāng)redis被用作緩存使用時(shí),如果我們使用了不同的節(jié)點(diǎn),即使給定的一個(gè)節(jié)點(diǎn)是無法獲得的,這也不是一個(gè)大問題。當(dāng)我們希望提供系統(tǒng)的可用性時(shí),可以通過改變key到實(shí)例的映射來實(shí)現(xiàn)這一點(diǎn)。
如果對(duì)于一個(gè)給定的key,其首選節(jié)點(diǎn)不可用,一致性hash實(shí)現(xiàn)通常能夠把key切換到其他節(jié)點(diǎn)。同樣,如果添加一個(gè)新節(jié)點(diǎn),部分新key也將被存儲(chǔ)到新節(jié)點(diǎn)中,主要概念如下:
-
如果redis被用作cache scale up 、scale down時(shí),使用一致性hash比較容易。
-
如果redis被用作存儲(chǔ),我們需要固定key與節(jié)點(diǎn)之間的映射,并且固定節(jié)點(diǎn)的數(shù)量。否則在增加或者刪減節(jié)點(diǎn)時(shí),我們需要一個(gè)有能力再平衡key與節(jié)點(diǎn)的系統(tǒng)。而且目前只有redis集群能夠做到這一點(diǎn),但目前redis集群仍是beta版,還沒有考慮生產(chǎn)環(huán)境的準(zhǔn)備。
Presharding
我們知道,分區(qū)面臨的問題是,除非我們使用redis作為緩存,否則增加、刪除節(jié)點(diǎn)可能是棘手的,并且使用固定的key到實(shí)例的映射是比較簡(jiǎn)單的。
然而,數(shù)據(jù)存儲(chǔ)的需求可能會(huì)隨時(shí)間而變化的。今天,我可能需要10個(gè)節(jié)點(diǎn),但是明天,我可能需要50個(gè)節(jié)點(diǎn)。
由于redis占用空間較小且是輕量級(jí)的,一個(gè)解決該問題的簡(jiǎn)單方法就是,一開始的時(shí)候就啟動(dòng)大量實(shí)例。即使你開始只啟動(dòng)一臺(tái)服務(wù)器,自第一天起,你可以決定生活在一個(gè)分布式的世界里,在你唯一的服務(wù)器上運(yùn)行多個(gè)redis實(shí)例,使用分區(qū)。
你可以在啟動(dòng)時(shí)選擇足夠數(shù)量的實(shí)例,比如,32或者64個(gè)實(shí)例可能是大多數(shù)用戶的常見做法,同時(shí)這種做法也提供了足夠的增長(zhǎng)空間。
這樣,當(dāng)你的數(shù)據(jù)存儲(chǔ)需要增加或者需要更多的redis服務(wù)器時(shí),你所需要做的就是把實(shí)例從一臺(tái)服務(wù)器遷移到另外一臺(tái)。一旦你增加第一個(gè)額外的服務(wù)器,你就需要把半數(shù)的redis實(shí)例從第一臺(tái)服務(wù)器遷移第二臺(tái),依此類推。
使用redis復(fù)制技術(shù),你就有可能非停機(jī)或者最小數(shù)據(jù)量遷移實(shí)施。
-
在新服務(wù)器上啟動(dòng)空實(shí)例。
-
移動(dòng)數(shù)據(jù),配置這些新實(shí)例為源實(shí)例的從庫。
-
停止client。
-
更改被移動(dòng)的實(shí)例的配置為新服務(wù)器ip。
-
向新服務(wù)器上的從庫發(fā)送SLAVEOF NO ONE命令。
-
按更新的配置,重啟client。
-
最后關(guān)閉老的服務(wù)器上不再使用的實(shí)例。
redis分區(qū)實(shí)現(xiàn)
到目前為止,我們從理論上討論了redis分區(qū),但應(yīng)如何實(shí)踐?我們?cè)摬捎檬裁聪到y(tǒng)?
redis 集群
redis集群是獲得自動(dòng)切分和高可用性的首選方法。它現(xiàn)在還不具備實(shí)施到生產(chǎn)環(huán)境,但已經(jīng)進(jìn)入到最后的測(cè)試階段,所以我們建議你開始嘗試它。你可以在 Cluster tutorial.獲得過多redis集群信息。
一旦redis集群可用,且如果對(duì)于你使用的語言,有配套的redis集群客戶端,那么redis集群將成為redis分區(qū)的事實(shí)標(biāo)準(zhǔn)。
redis集群是介于查詢路由與客戶端分區(qū)的混合體。
Twemproxy
Twemproxy是由Twitter開發(fā)的支持Memcached ASCII和Redis協(xié)議的一個(gè)代理。它是單線程的,C語言實(shí)現(xiàn),且相當(dāng)?shù)目臁K窃?/span>Apache 2許可條款下開源的。
Twemproxy支持多個(gè)redis實(shí)例之間的自動(dòng)分區(qū),并支持不可用節(jié)點(diǎn)彈出的功能(這將改變key到實(shí)例的映射,如果你把redis作為緩存使用,可以利用這個(gè)特性)。
Twemproxy是非單點(diǎn)故障的,因?yàn)槟憧梢詥?dòng)過個(gè)代理,并且通知客戶端連接到第一個(gè)可接受連接的代理。
Twemproxy是客戶端與redis實(shí)例之間的中間層,它能以最小的額外復(fù)雜度為我們處理分區(qū)。從目前來看,它是建議的redis分區(qū)處理方式。
你可以從這里獲得更多關(guān)于Twemproxy的信息。
Twemproxy介紹:http://www.cnblogs.com/yuxingfirst/archive/2013/02/05/2892947.html
支持一致性hash的客戶端
另外一種替代Twemproxy的方案,就是使用實(shí)現(xiàn)分區(qū)(一致性hash或者其他算法)的客戶端。有不少客戶端都支持一致性hash特別是Redis-rb 和Predis。請(qǐng)查看完整的redis客戶端列表,檢查是否存在使用你的語言實(shí)現(xiàn)了一致性hash的成熟的客戶端。
posted on 2014-07-14 12:17
zhangxl 閱讀(692)
評(píng)論(1) 編輯 收藏 所屬分類:
nosql