《從Redis分區(qū)的優(yōu)缺點來看適合的應(yīng)用場景》要點:
本文介紹了從Redis分區(qū)的優(yōu)缺點來看適合的應(yīng)用場景,希望對您有用。如果有疑問,可以聯(lián)系我們。
Redis Partitioning即Redis分區(qū),簡單的說就是將數(shù)據(jù)分布到不同的redis實例中,因此對于每個redis實例所存儲的內(nèi)容僅僅是所有內(nèi)容的一個子集.分區(qū)(Partitioning)不僅僅是Redis中的概念,幾乎是所有數(shù)據(jù)存儲系統(tǒng)都會涉及到的概念,這篇文章將會在理解分區(qū)基本概念的基礎(chǔ)之上進一步了解Redis對分區(qū)的支持.
我們?yōu)槭裁匆謪^(qū)?分區(qū)的動機是什么?通常來說,Redis分區(qū)的好處大致有如下兩個方面:
總的來說,分區(qū)使得我們本來受限于單臺計算機硬件資源的問題不再是問題,存儲不夠?計算資源不夠?帶寬不夠?我們都可以通過增加機器來解決這些問題.
實際應(yīng)用中有很多分區(qū)的具體策略,舉個例子,假設(shè)我們已經(jīng)有了一組四個Redis實例分別為R0、R1、R2、R3,另外我們有一批代表用戶的鍵,如:user:1,user:2,……等等,其中“user:”后面的數(shù)字代表的是用戶的ID,我們要做的事情是把這些鍵分散存儲在這四個不同的Redis實例上.怎么做呢?最簡單的一種方式是范圍分區(qū)(range partitioning),下面我們來看看基于范圍分區(qū)怎么做.
所謂范圍分區(qū),就是將一個范圍內(nèi)的key都映射到同一個Redis實例中,加入數(shù)據(jù)集還是上面提到的用戶數(shù)據(jù),具體做法如下:
我們可以將用戶ID從0到10000的用戶數(shù)據(jù)映射到R0實例,而將用戶ID從10001到20000的對象映射到R1實例,依次類推.
這種方法雖然簡單,但是在實際應(yīng)用中是很有效的,不過還是有問題:
因此,在實際應(yīng)用中,范圍分區(qū)并不是很好的選擇,不用擔(dān)心,我們還有更好的方法,接下來認(rèn)識下哈希分區(qū).
哈希分區(qū)跟范圍分區(qū)相比一個明顯的優(yōu)點是哈希分區(qū)適合任何形式的key,而不像范圍分區(qū)一樣需要key的形式為object_name:<id>,而且分區(qū)方法也很簡單,一個公式就可以表達(dá):
id=hash(key)%N
其中id代表Redis實例的編號,公式描述的是首先根據(jù)key和一個hash函數(shù)(如crc32函數(shù))計算出一個數(shù)值型的值.接著上面的例子,我們的第一個要處理的key是user:1,hash(user:1)的結(jié)果是93024922.
然后哈希結(jié)果進行取模,取模的目的是計算出一個介于0到3之間的值,因此這個值才可以被映射到我們的一臺Redis實例上面.比如93024922%4結(jié)果是2,我們就會知道foobar將要被存儲在R2上面.
當(dāng)然除了上面提到的兩種分區(qū)方法,還有很多其他的方法.比如一種從哈希分區(qū)演進而來的consistent hashing分區(qū),相信信息可以參考我的另一篇文章《memcached分布式實現(xiàn)原理》,其已經(jīng)被redis client和proxies實現(xiàn)了.
分區(qū)可以在redis軟件棧的不同部分被實現(xiàn),我們來看看下面幾種:
客戶端實現(xiàn)即key在redis客戶端就決定了要被存儲在那臺Redis實例中,見下圖:
客戶端實現(xiàn)分區(qū)示意圖
代理實現(xiàn)即客戶端將請求發(fā)往代理服務(wù)器,代理服務(wù)器實現(xiàn)了Redis協(xié)議,因此代理服務(wù)器可以代理客戶端和Redis服務(wù)器通信.代理服務(wù)器通過配置的分區(qū)schema來將客戶端的請求轉(zhuǎn)發(fā)到正確的Redis實例中,同時將反饋消息返回給客戶端.代理實現(xiàn)Redis分區(qū)示意圖如下:
代理實現(xiàn)Redis分區(qū)示意圖
Redis和Memcached代理Twemoroxy都實現(xiàn)了代理分區(qū).
查詢路由是Redis Cluster實現(xiàn)的一種Redis分區(qū)方式:
查詢路由Redis分區(qū)示意圖
查詢路由的過程中,我們可以將查詢請求隨機的發(fā)送到任意一個Redis實例,這個Redis實例負(fù)責(zé)將請求轉(zhuǎn)發(fā)至正確的Redis實例中.Redis集群實現(xiàn)了一個通過和客戶端協(xié)作的hybrid來做查詢路由.
盡管Redis分區(qū)到現(xiàn)在為止,so far so good,但是Redis分區(qū)有一些致命的缺點,這導(dǎo)致一些Redis功能在分區(qū)的環(huán)境下并不能很好地工作,我們來看看:
既然有問題,那么就需要解決方案,這個時候Pre-sharding來了,后面我們會介紹Pre-Sharding.
盡管數(shù)據(jù)分區(qū)對于Redis來說無論是數(shù)據(jù)持久化存儲還是緩存,在概念上都是一樣的,然而對于數(shù)據(jù)持久化存儲還是有一個很大的限制.當(dāng)我們使用Redis來作為持久化存儲的時候,每一個key必須一直被映射到同一個Redis實例.而當(dāng)Redis被當(dāng)做緩存使用的時候,對于這個key,如果一個實例不能用了,這個key還可以被映射到其他的實例中.
Consistent hashing實現(xiàn)通常使得當(dāng)一個key被映射到的實例不能用的時候?qū)⑦@個key映射到其他實例成為可能.類似,如果增加了一臺機器,一部分的key將會被映射到這臺新的機器上,我們需要了解的兩點如下:
通過上面的介紹,我們知道Redis分區(qū)應(yīng)用起來是有問題的,除非我們只是使用Redis當(dāng)做緩存,否則對于增加機器或刪除機器是非常麻煩的.
然而,通常我們Redis容量變動在實際應(yīng)用中是非常常見的,比如今天我需要10臺Redis機器,明天可能就需要50臺機器了.
鑒于Redis是很輕量級的服務(wù)(每個實例僅僅占用1M),對于上面的問題一種簡單的解決辦法是:
我們可以開啟多個Redis實例,盡管是一臺物理機器,我們在剛開始的時候也可以開啟多個實例.我們可以從中選擇一些實例,比如32或64個實例來作為我們的工作集群.當(dāng)一臺物理機器存儲不夠的時候,我們可以將一般的實例移動到我們的第二臺物理機上,依次類對,我們可以保證集群中Redis的實例數(shù)不變,又可以達(dá)到擴充機器的目的.
怎么移動Redis實例呢?當(dāng)需要將Redis實例移動到獨立的機器上的時候,我們可以通過下面步驟實現(xiàn):
這篇文章在理解Redis分區(qū)概念的基礎(chǔ)之上又介紹了Redis分區(qū)常見的幾種實現(xiàn)方式及原理,最后根據(jù)實現(xiàn)中遇到的問題引入了Pre-Sharding解決方案.
《Redis官方文檔》
文/陸晨
原文出處——http://my.oschina.net/andylucc技術(shù)博客
轉(zhuǎn)載請注明本頁網(wǎng)址:
http://www.fzlkiss.com/jiaocheng/4516.html