您好,登錄后才能下訂單哦!
Redis分區(qū)實(shí)現(xiàn)原理是什么?為什么要分區(qū)?很多人都不太了解,今天小編為了讓大家更加了解 Redis分區(qū)實(shí)現(xiàn)原理,所以給大家總結(jié)了以下內(nèi)容,一起往下看吧
Redis Partitioning即Redis分區(qū),簡(jiǎn)單的說(shuō)就是將數(shù)據(jù)分布到不同的redis實(shí)例中,因此對(duì)于每個(gè)redis實(shí)例所存儲(chǔ)的內(nèi)容僅僅是所有內(nèi)容的一個(gè)子集。
我們?yōu)槭裁匆謪^(qū)?分區(qū)的動(dòng)機(jī)是什么?通常來(lái)說(shuō),Redis分區(qū)的好處大致有如下兩個(gè)方面:
1、性能的提升,單機(jī)Redis的網(wǎng)絡(luò)I/O能力和計(jì)算資源是有限的,將請(qǐng)求分散到多臺(tái)機(jī)器,充分利用多臺(tái)機(jī)器的計(jì)算能力可網(wǎng)絡(luò)帶寬,有助于提高Redis總體的服務(wù)能力。
2、存儲(chǔ)的橫向擴(kuò)展,即使Redis的服務(wù)能力能夠滿足應(yīng)用需求,但是隨著存儲(chǔ)數(shù)據(jù)的增加,單臺(tái)機(jī)器受限于機(jī)器本身的存儲(chǔ)容量,將數(shù)據(jù)分散到多臺(tái)機(jī)器上存儲(chǔ)使得Redis服務(wù)可以橫向擴(kuò)展。
總的來(lái)說(shuō),分區(qū)使得我們本來(lái)受限于單臺(tái)計(jì)算機(jī)硬件資源的問(wèn)題不再是問(wèn)題,存儲(chǔ)不夠?計(jì)算資源不夠?帶寬不夠?我們都可以通過(guò)增加機(jī)器來(lái)解決這些問(wèn)題。
Redis分區(qū)基礎(chǔ)
實(shí)際應(yīng)用中有很多分區(qū)的具體策略,舉個(gè)例子,假設(shè)我們已經(jīng)有了一組四個(gè)Redis實(shí)例分別為R0、R1、R2、R3,另外我們有一批代表用戶的鍵,如:user:1,user:2,……等等,其中“user:”后面的數(shù)字代表的是用戶的ID,我們要做的事情是把這些鍵分散存儲(chǔ)在這四個(gè)不同的Redis實(shí)例上。怎么做呢?最簡(jiǎn)單的一種方式是范圍分區(qū)(range partitioning),下面我們來(lái)看看基于范圍分區(qū)怎么做。
范圍分區(qū)
所謂范圍分區(qū),就是將一個(gè)范圍內(nèi)的key都映射到同一個(gè)Redis實(shí)例中,加入數(shù)據(jù)集還是上面提到的用戶數(shù)據(jù),具體做法如下:
我們可以將用戶ID從0到10000的用戶數(shù)據(jù)映射到R0實(shí)例,而將用戶ID從10001到20000的對(duì)象映射到R1實(shí)例,依次類推。
這種方法雖然簡(jiǎn)單,但是在實(shí)際應(yīng)用中是很有效的,不過(guò)還是有問(wèn)題:
我們需要一張表,這張表用來(lái)存儲(chǔ)用戶ID范圍到Redis實(shí)例的映射關(guān)系,比如用戶ID0-10000的是映射到R0實(shí)例……。
我們不僅需要對(duì)這張表進(jìn)行維護(hù),而且對(duì)于每種對(duì)象類型我們都需要一個(gè)這樣的表,比如我們當(dāng)前存儲(chǔ)的是用戶信息,如果存儲(chǔ)的是訂單信息,我們就需要再建一張映射關(guān)系表。
如果我們想要存儲(chǔ)的數(shù)據(jù)的key并不能按照范圍劃分怎么辦,比如我們的key是一組uuid,這個(gè)時(shí)候就不好用范圍分區(qū)了。
因此,在實(shí)際應(yīng)用中,范圍分區(qū)并不是很好的選擇,不用擔(dān)心,我們還有更好的方法,接下來(lái)認(rèn)識(shí)下哈希分區(qū)。
哈希分區(qū)
哈希分區(qū)跟范圍分區(qū)相比一個(gè)明顯的優(yōu)點(diǎn)是哈希分區(qū)適合任何形式的key,而不像范圍分區(qū)一樣需要key的形式為object_name:<id>,而且分區(qū)方法也很簡(jiǎn)單,一個(gè)公式就可以表達(dá):
id=hash(key)%N
其中id代表Redis實(shí)例的編號(hào),公式描述的是首先根據(jù)key和一個(gè)hash函數(shù)(如crc32函數(shù))計(jì)算出一個(gè)數(shù)值型的值。接著上面的例子,我們的第一個(gè)要處理的key是user:1,hash(user:1)的結(jié)果是93024922。
然后哈希結(jié)果進(jìn)行取模,取模的目的是計(jì)算出一個(gè)介于0到3之間的值,因此這個(gè)值才可以被映射到我們的一臺(tái)Redis實(shí)例上面。比如93024922%4結(jié)果是2,我們就會(huì)知道foobar將要被存儲(chǔ)在R2上面。
不同的分區(qū)實(shí)現(xiàn)
分區(qū)可以在redis軟件棧的不同部分被實(shí)現(xiàn),我們來(lái)看看下面幾種:
客戶端實(shí)現(xiàn)
客戶端實(shí)現(xiàn)即key在redis客戶端就決定了要被存儲(chǔ)在那臺(tái)Redis實(shí)例中,見(jiàn)下圖:
上面為客戶端實(shí)現(xiàn)Redis分區(qū)的示意圖。
代理實(shí)現(xiàn)
代理實(shí)現(xiàn)即客戶端將請(qǐng)求發(fā)往代理服務(wù)器,代理服務(wù)器實(shí)現(xiàn)了Redis協(xié)議,因此代理服務(wù)器可以代理客戶端和Redis服務(wù)器通信。代理服務(wù)器通過(guò)配置的分區(qū)schema來(lái)將客戶端的請(qǐng)求轉(zhuǎn)發(fā)到正確的Redis實(shí)例中,同時(shí)將反饋消息返回給客戶端。代理實(shí)現(xiàn)Redis分區(qū)示意圖如下:
Redis和Memcached代理Twemoroxy都實(shí)現(xiàn)了代理分區(qū)。
查詢路由
查詢路由是Redis Cluster實(shí)現(xiàn)的一種Redis分區(qū)方式:
查詢路由的過(guò)程中,我們可以將查詢請(qǐng)求隨機(jī)的發(fā)送到任意一個(gè)Redis實(shí)例,這個(gè)Redis實(shí)例負(fù)責(zé)將請(qǐng)求轉(zhuǎn)發(fā)至正確的Redis實(shí)例中。Redis集群實(shí)現(xiàn)了一個(gè)通過(guò)和客戶端協(xié)作的hybrid來(lái)做查詢路由。
Redis分區(qū)的缺點(diǎn)
盡管Redis分區(qū)到現(xiàn)在為止,so far so good,但是Redis分區(qū)有一些致命的缺點(diǎn),這導(dǎo)致一些Redis功能在分區(qū)的環(huán)境下并不能很好地工作,我們來(lái)看看:
多鍵操作是不被支持的,比如我們將要批量操作的鍵被映射到了不同的Redis實(shí)例中。
多鍵的Redis事務(wù)是不被支持的。
分區(qū)的最小粒度是鍵,因此我們不能將關(guān)聯(lián)到一個(gè)鍵的很大的數(shù)據(jù)集映射到不同的實(shí)例。
當(dāng)應(yīng)用分區(qū)的時(shí)候,數(shù)據(jù)的處理是非常復(fù)雜的,比如我們需要處理多個(gè)rdb/aof文件,將分布在不同實(shí)例的文件聚集到一起備份。
添加和刪除機(jī)器是很復(fù)雜的,例如Redis集群支持幾乎運(yùn)行時(shí)透明的因?yàn)樵黾踊驕p少機(jī)器而需要做的rebalancing,然而像客戶端和代理分區(qū)這種方式是不支持這種功能的。
持久存儲(chǔ)用還是緩存
盡管數(shù)據(jù)分區(qū)對(duì)于Redis來(lái)說(shuō)無(wú)論是數(shù)據(jù)持久化存儲(chǔ)還是緩存,在概念上都是一樣的,然而對(duì)于數(shù)據(jù)持久化存儲(chǔ)還是有一個(gè)很大的限制。當(dāng)我們使用Redis來(lái)作為持久化存儲(chǔ)的時(shí)候,每一個(gè)key必須一直被映射到同一個(gè)Redis實(shí)例。而當(dāng)Redis被當(dāng)做緩存使用的時(shí)候,對(duì)于這個(gè)key,如果一個(gè)實(shí)例不能用了,這個(gè)key還可以被映射到其他的實(shí)例中。
Consistent hashing實(shí)現(xiàn)通常使得當(dāng)一個(gè)key被映射到的實(shí)例不能用的時(shí)候?qū)⑦@個(gè)key映射到其他實(shí)例成為可能。類似,如果增加了一臺(tái)機(jī)器,一部分的key將會(huì)被映射到這臺(tái)新的機(jī)器上,我們需要了解的兩點(diǎn)如下:
1、如果Redis被用來(lái)當(dāng)做緩存,且要求容易增加或刪除機(jī)器,使用consistent hashing是非常簡(jiǎn)單的。
2、如果Redis被用來(lái)當(dāng)做(持久)存儲(chǔ),一個(gè)固定的key到實(shí)例的映射是需要的,因此我們不能夠再靈活的添加或刪除機(jī)器。否則,我們需要在增加或刪除機(jī)器的時(shí)候系統(tǒng)能夠rebalace,當(dāng)前Redis Cluster已經(jīng)支持。
Pre-Sharding
通過(guò)上面的介紹,我們知道Redis分區(qū)應(yīng)用起來(lái)是有問(wèn)題的,除非我們只是使用Redis當(dāng)做緩存,否則對(duì)于增加機(jī)器或刪除機(jī)器是非常麻煩的。
然而,通常我們Redis容量變動(dòng)在實(shí)際應(yīng)用中是非常常見(jiàn)的,比如今天我需要10臺(tái)Redis機(jī)器,明天可能就需要50臺(tái)機(jī)器了。
鑒于Redis是很輕量級(jí)的服務(wù)(每個(gè)實(shí)例僅僅占用1M),對(duì)于上面的問(wèn)題一種簡(jiǎn)單的解決辦法是:
我們可以開(kāi)啟多個(gè)Redis實(shí)例,盡管是一臺(tái)物理機(jī)器,我們?cè)趧傞_(kāi)始的時(shí)候也可以開(kāi)啟多個(gè)實(shí)例。我們可以從中選擇一些實(shí)例,比如32或64個(gè)實(shí)例來(lái)作為我們的工作集群。當(dāng)一臺(tái)物理機(jī)器存儲(chǔ)不夠的時(shí)候,我們可以將一般的實(shí)例移動(dòng)到我們的第二臺(tái)物理機(jī)上,依次類對(duì),我們可以保證集群中Redis的實(shí)例數(shù)不變,又可以達(dá)到擴(kuò)充機(jī)器的目的。
怎么移動(dòng)Redis實(shí)例呢?當(dāng)需要將Redis實(shí)例移動(dòng)到獨(dú)立的機(jī)器上的時(shí)候,我們可以通過(guò)下面步驟實(shí)現(xiàn):
1、在新的物理機(jī)上啟動(dòng)一個(gè)新的Redis實(shí)例。
2、將新的物理機(jī)作為要移動(dòng)的那臺(tái)的slave機(jī)器。
3、停止客戶端。
4、更新將要被移動(dòng)的那臺(tái)Redis實(shí)例的IP地址。
5、對(duì)于slave機(jī)器發(fā)送SLAVEOF ON ONE命令。
6、使用新的IP啟動(dòng)Redis客戶端。
7、關(guān)閉不再使用的那個(gè)Redis實(shí)例。
總結(jié)
這篇文章在理解Redis分區(qū)概念的基礎(chǔ)之上又介紹了Redis分區(qū)常見(jiàn)的幾種實(shí)現(xiàn)方式及原理,最后根據(jù)實(shí)現(xiàn)中遇到的問(wèn)題引入了Pre-Sharding解決方案。
關(guān)于Redis分區(qū)實(shí)現(xiàn)原理是什么?為什么要分區(qū)就分享到這里了,當(dāng)然并不止以上和大家分析的辦法,不過(guò)小編可以保證其準(zhǔn)確性是絕對(duì)沒(méi)問(wèn)題的。希望以上內(nèi)容可以對(duì)大家有一定的參考價(jià)值,可以學(xué)以致用。如果喜歡本篇文章,不妨把它分享出去讓更多的人看到。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。