Redis分区/分片详解
分區(qū)/分片詳解
分區(qū)是分割數(shù)據(jù)到多個(gè)Redis實(shí)例的處理過程,因此每個(gè)實(shí)例只保存key的一個(gè)子集。
如果只使用一個(gè)redis實(shí)例時(shí),其中保存了服務(wù)器中全部的緩存數(shù)據(jù),這樣會(huì)有很大風(fēng)險(xiǎn),如果單臺(tái)redis服務(wù)宕機(jī)了將會(huì)影響到整個(gè)服務(wù)。解決的方法就是我們可以采用分片/分區(qū)的技術(shù),將原來一臺(tái)服務(wù)器維護(hù)的整個(gè)緩存,現(xiàn)在換為由多臺(tái)服務(wù)器共同維護(hù)內(nèi)存空間。
為什么要分區(qū)?
-
在大數(shù)據(jù)高并發(fā)場景下,單個(gè)redis實(shí)例往往不足以應(yīng)付。首先體現(xiàn)在內(nèi)存上,單個(gè)redis的內(nèi)存不宜過大,內(nèi)存太大會(huì)導(dǎo)致rdb文件過大,進(jìn)一步導(dǎo)致主從同步時(shí)全量同步時(shí)間過長,在實(shí)例重啟恢復(fù)時(shí)也會(huì)消耗很長的數(shù)據(jù)加載時(shí)間,特別是在云環(huán)境下,單個(gè)實(shí)例內(nèi)存大小往往都是受限的。其次體現(xiàn)在CPU的利用率上,單個(gè)redis實(shí)例只能利用單個(gè)核心,單個(gè)核心要完成海量數(shù)據(jù)的存取和管理工作,壓力會(huì)非常大。
-
正是在這樣的大數(shù)據(jù)高并發(fā)的需求之下,redis集群方案應(yīng)運(yùn)而生。它可以將眾多小內(nèi)存的redis實(shí)例整合起來,將分布在多臺(tái)機(jī)器上的眾多CPU核心的計(jì)算能力聚集在一起,完成海量數(shù)據(jù)存儲(chǔ)和高并發(fā)讀寫操作。
Redis的分區(qū)方案
-
客戶端分區(qū)
在客戶端就已經(jīng)決定數(shù)據(jù)會(huì)被存儲(chǔ)到哪個(gè)redis節(jié)點(diǎn)或者從哪個(gè)redis節(jié)點(diǎn)讀取。大多數(shù)客戶端已經(jīng)實(shí)現(xiàn)了客戶端分區(qū)。
系統(tǒng)架構(gòu)
實(shí)現(xiàn)方案
客戶端分區(qū)方案 的代表為 Redis Sharding,Redis Sharding 是 Redis Cluster 出來之前,業(yè)界普遍使用的 Redis 多實(shí)例集群 方法。Java 的 Redis 客戶端驅(qū)動(dòng)庫 Jedis,支持 Redis Sharding 功能,即 ShardedJedis 以及 結(jié)合緩存池 的 ShardedJedisPool。
優(yōu)點(diǎn):
客戶端分片的好處就是所有的邏輯都是可控的,不依賴于第三方分布式中間件。開發(fā)人員清除怎么實(shí)現(xiàn)分片、路由的規(guī)則,不用擔(dān)心踩坑。
缺點(diǎn):
-
這是一種靜態(tài)的分片方案,需要增加或者減少redis實(shí)例的數(shù)量,需要手動(dòng)調(diào)整分片的程序
-
可運(yùn)維性差。集群的數(shù)據(jù)出了任何問題都需要運(yùn)維人員和開發(fā)人員一起合作,減緩了解決問題的速度,增加了跨部門溝通的成本
-
在不同的客戶端程序中,維護(hù)相同的分片邏輯成本巨大。比如,系統(tǒng)中有兩套業(yè)務(wù)系統(tǒng)共用一套redis集群,一套業(yè)務(wù)系統(tǒng)用java實(shí)現(xiàn),另一套業(yè)務(wù)系統(tǒng)用php實(shí)現(xiàn)。為了保持分片邏輯的一致性,在java客戶端中實(shí)現(xiàn)的分片邏輯也需要在php客戶端實(shí)現(xiàn)一次。相同的邏輯在不同的系統(tǒng)中分別實(shí)現(xiàn),這種設(shè)備本來就非常糟糕,而且需要耗費(fèi)巨大的開發(fā)成本保證兩套業(yè)務(wù)系統(tǒng)分片邏輯的一致性
-
-
范圍分區(qū)
映射一定范圍的對象到特定的Redis實(shí)例。比如,ID從0到10000的用戶會(huì)保存到實(shí)例R0,ID從10001到 20000的用戶會(huì)保存到R1,以此類推
hash一致算法實(shí)現(xiàn)分區(qū)
hash一致算法實(shí)現(xiàn)分區(qū),對key值進(jìn)行hash一致性計(jì)算后得到結(jié)果,最終將數(shù)據(jù)保存到某一臺(tái)redis實(shí)例中 -
代理分區(qū)
實(shí)現(xiàn)方案:
Twemproxy 也叫 nutcraker,是 twitter 開源的一個(gè) redis 和 memcache 的 中間代理服務(wù)器 程序。Twemproxy 作為 代理,可接受來自多個(gè)程序的訪問,按照 路由規(guī)則,轉(zhuǎn)發(fā)給后臺(tái)的各個(gè) Redis 服務(wù)器,再原路返回。Twemproxy 存在 單點(diǎn)故障 問題,需要結(jié)合 Lvs 和 Keepalived 做 高可用方案。
基本原理:
-
redis客戶端把請求發(fā)送到Twemproxy
-
Twemproxy根據(jù)路由規(guī)則發(fā)送到正確的redis實(shí)例
-
最后Twemproxy把結(jié)果匯集返回給客戶端
客戶端將請求發(fā)送給代理,然后代理決定去哪個(gè)節(jié)點(diǎn)寫數(shù)據(jù)或者讀數(shù)據(jù)。根據(jù)分區(qū)規(guī)則決定請求哪些Redis實(shí)例,然后根據(jù)Redis的響應(yīng)結(jié)果返回給客戶端。redis和memcached的一種代理實(shí)現(xiàn)就是Twemproxy
-
-
查詢路由
是客戶端隨機(jī)地請求任意一個(gè)redis實(shí)例,然后由Redis將請求轉(zhuǎn)發(fā)給正確的Redis節(jié)點(diǎn)。Redis Cluster實(shí)現(xiàn)了一種混合形式的查詢路由,但并不是直接將請求從一個(gè)redis節(jié)點(diǎn)轉(zhuǎn)發(fā)到另一個(gè)redis節(jié)點(diǎn),而是在客戶端的幫助下直接redirected到正確的redis節(jié)點(diǎn)
Redis分區(qū)不足:
分區(qū)是多臺(tái)redis共同作用,如果一臺(tái)宕機(jī),其實(shí)是整個(gè)分片故障。雖然緩解了內(nèi)存壓力,但是沒有實(shí)現(xiàn)高可用。
涉及多個(gè)key的操作就會(huì)不支持。比如當(dāng)兩個(gè)set映射到不同的redis實(shí)例時(shí),因?yàn)樗麄兛赡鼙淮鎯?chǔ)到不同的實(shí)例上,所有就無法完成交集操作。
涉及到多個(gè)key的redis事務(wù)就不被支持。
分區(qū)對于動(dòng)態(tài)擴(kuò)容,其實(shí)是非常復(fù)雜的。因?yàn)樾枰薷目蛻舳舜a。
當(dāng)兩個(gè)set映射到不同的redis實(shí)例上時(shí),因?yàn)樗麄兛赡鼙淮鎯?chǔ)到不同的Redis實(shí)例,你就不能對這兩個(gè)set執(zhí)行交集操作
Redis一種推薦做法:
例子:
我們Redis容量變動(dòng)在實(shí)際應(yīng)用中是非常常見的,比如今天我需要10臺(tái)Redis機(jī)器,明天可能就需要50臺(tái)機(jī)器了。
-
我們可以開啟多個(gè)Redis實(shí)例,盡管是一臺(tái)物理機(jī)器,我們在剛開始的時(shí)候也可以開啟多個(gè)實(shí)例。
-
我們可以從中選擇一些實(shí)例,比如32或64個(gè)實(shí)例來作為我們的工作集群。
-
當(dāng)一臺(tái)物理機(jī)器存儲(chǔ)不夠的時(shí)候,我們可以將一般的實(shí)例移動(dòng)到我們的第二臺(tái)物理機(jī)上,依次類對,我們可以保證集群中Redis的實(shí)例數(shù)不變,又可以達(dá)到擴(kuò)充機(jī)器的目的。
怎么移動(dòng)Redis實(shí)例呢?當(dāng)需要將Redis實(shí)例移動(dòng)到獨(dú)立的機(jī)器上的時(shí)候,我們可以通過下面步驟實(shí)現(xiàn):
-
在新的物理機(jī)上啟動(dòng)一個(gè)新的Redis實(shí)例。
-
將新的物理機(jī)作為要移動(dòng)的那臺(tái)的slave機(jī)器。
-
停止客戶端。
-
更新將要被移動(dòng)的那臺(tái)Redis實(shí)例的IP地址。
-
對于slave機(jī)器發(fā)送SLAVEOF ON ONE命令。
-
使用新的IP啟動(dòng)Redis客戶端。
-
關(guān)閉不再使用的那個(gè)Redis實(shí)例。
Redis集群
數(shù)據(jù)分區(qū)是集群的實(shí)現(xiàn)基礎(chǔ)。集群是數(shù)據(jù)分區(qū)的具體實(shí)現(xiàn)。
-
由于redis出眾的性能,其在眾多的移動(dòng)互聯(lián)網(wǎng)企業(yè)中得到廣泛的應(yīng)用。
-
redis在3.0版本前只支持單實(shí)例模式,雖然現(xiàn)在的服務(wù)器內(nèi)存可以到100GB、200GB的規(guī)模,但是單實(shí)例模式限制了redis沒法滿足業(yè)務(wù)的需求(比如新浪微博就曾經(jīng)用redis存儲(chǔ)了超過1TB的數(shù)據(jù))。
-
redis的開發(fā)者Antrres早在博客上就提出在redis3.0版本中加入集群的功能,但3.0版本等到2015年才發(fā)布正式版。
-
各大企業(yè)在3.0版本還沒有發(fā)布前為了解決redis的存儲(chǔ)瓶頸,紛紛推出了各自的redis集群方案。這些方案的核心思想就是把數(shù)據(jù)分片(sharding)存儲(chǔ)在多個(gè)redis實(shí)例中,每一片就是一個(gè)redis實(shí)例。
實(shí)現(xiàn)案例:
Redis cluster是redis作者自己提供的集群化方案
總結(jié)
以上是生活随笔為你收集整理的Redis分区/分片详解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 2d有限元计算机仿真,平面铣削加工过程计
- 下一篇: 自动驾驶感知——激光雷达物体检测算法