241_Redis_集群_主從架構(gòu)(redis主從與集群)
一 分布式理論基石CAP
C? consistent 一致性
A? availability? 可用性
P? Partition tolerance 分區(qū)容忍性
分布式的前提:分布式節(jié)點(diǎn)在不同機(jī)器上做網(wǎng)絡(luò)隔離,意味著必然有網(wǎng)絡(luò)斷開的風(fēng)險, 這種場景叫 網(wǎng)絡(luò)分區(qū)
當(dāng)網(wǎng)絡(luò)分區(qū)時 發(fā)生網(wǎng)絡(luò)故障時, 一致性和可用性二選一
1 分布式節(jié)點(diǎn)之間無法進(jìn)行通信,對A 節(jié)點(diǎn)操作無法同步到另一個節(jié)點(diǎn)B,一致性無法進(jìn)行滿足
2 暫停服務(wù)修復(fù) A –B 之間的通信, 這就是犧牲了可用性
最終一致性
Redis 主從數(shù)據(jù)時異步同步的,Redis在定義上不滿足一致性的要求,客戶端在Redis上修改數(shù)據(jù)后, 立即返回,不考慮slave是否接收到, 即使主從斷開,主依舊對外提供服務(wù)。但是Redis保證最終一致性, slave在網(wǎng)絡(luò)恢復(fù)后 采用多種策略追趕, 保持與主節(jié)點(diǎn)一致
二 BASE理論
BASE是對CAP中一致性和可用性權(quán)衡的結(jié)果,其來源于對大規(guī)模互聯(lián)網(wǎng)分布式系統(tǒng)實(shí)踐的總結(jié),是基于CAP定律逐步演化而來。 其核心思想是即使無法做到強(qiáng)一致性,但每個應(yīng)用都可以根據(jù)自身業(yè)務(wù)特點(diǎn),采用適當(dāng)?shù)姆绞絹硎瓜到y(tǒng)達(dá)到最終一致性 BASE就是為了解決關(guān)系數(shù)據(jù)庫強(qiáng)一致性引起的問題而引起的可用性降低而提出的解決方案 BASE其實(shí)是下面三個術(shù)語的縮寫: 基本可用(Basically Available): 基本可用是指分布式系統(tǒng)在出現(xiàn)故障的時候,允許損失部分可用性,即保證核心可用。 電商大促時,為了應(yīng)對訪問量激增,部分用戶可能會被引導(dǎo)到降級頁面,服務(wù)層也可能只提供降級服務(wù)。這就是損失部分可用性的體現(xiàn)。 軟狀態(tài)(Soft State): 軟狀態(tài)是指允許系統(tǒng)存在中間狀態(tài),而該中間狀態(tài)不會影響系統(tǒng)整體可用性。 分布式存儲中一般一份數(shù)據(jù)至少會有三個副本,允許不同節(jié)點(diǎn)間副本同步的延時就是軟狀態(tài)的體現(xiàn)。MySQL Replication 的異步復(fù)制也是一種體現(xiàn)。 最終一致性(Eventual Consistency): 最終一致性是指系統(tǒng)中的所有數(shù)據(jù)副本經(jīng)過一定時間后,最終能夠達(dá)到一致的狀態(tài)。 弱一致性和強(qiáng)一致性相反,最終一致性是弱一致性的一種特殊情況。 它的思想是通過讓系統(tǒng)放松對某一時刻數(shù)據(jù)一致性的要求來換取系統(tǒng)整體伸縮性和性能上改觀。就在于大型系統(tǒng)往往由于地域分布和極高性能的要求,不可能采用分布式事務(wù)來完成這些指標(biāo),要想獲得這些指標(biāo),我們必須采用另外一種方式來完成
Redis主從命令
配置slave redis-cli -p 6381 -a 123 SLAVEOF 127.0.0.1 6380 redis-cli -p 6382 -a 123 SLAVEOF 127.0.0.1 6380 查看master slave redis-cli -p 6382 -a 123 info replication 停止主從 SLAVEOF NO ONE redis.conf replica-priority 100 # 數(shù)字越小級別越高,越優(yōu)先升級為主 舊版本slave-priority
Redis 主從原理
1 主從第一階段 同步(psync rdb snapshot) 1.1 slave 庫通過slaveof ip 6379命令,連接主庫,并發(fā)送PSYNC給主庫 (slave 執(zhí)行psync $master_runid $slave_offset) #master_runid是主庫redis實(shí)例的一個唯一標(biāo)識id,是redis實(shí)例創(chuàng)建的時候自動生成的。offset是指從節(jié)點(diǎn)的復(fù)制偏移量 1.2 master收到PSYNC,會立即觸發(fā)BGSAVE,后臺保存RDB,發(fā)送給slave Master fork一個bgsave子進(jìn)程生成一個RDB快照文件發(fā)送給從庫,由slave完成加載 #主庫收到這個請求后,把自己的runid和offset發(fā)送給從庫 (master執(zhí)行 FULLRESYNC $master_runid $master_offset) 1.3 副本庫接收后會應(yīng)用RDB快照 2 主從第二階段 命令傳播(commands propagation) 2.1主庫只要發(fā)生新的操作,保存并發(fā)送給slave都會以命令傳播的形式自動發(fā)送給副本庫 2.2 所有復(fù)制相關(guān)信息,從info replication信息中都可以查到.即使重啟任何節(jié)點(diǎn),他的主從關(guān)系依然都在 2.3 如果發(fā)生主從關(guān)系斷開時,從庫數(shù)據(jù)沒有任何損壞,在下次重連之后,從庫發(fā)送PSYNC給主庫 2.4 主庫只會將從庫缺失部分的數(shù)據(jù)同步給從庫應(yīng)用,達(dá)到快速恢復(fù)主從的目的
Redis 核心復(fù)制同步 快照同步&增量同步
1 快照同步
Master :主節(jié)點(diǎn)進(jìn)行bgsave,將內(nèi)存中數(shù)據(jù)落盤后 發(fā)送給 slave
Slave: ??收到快照后進(jìn)行全量加載,加載前要將自己內(nèi)存數(shù)據(jù)清空, 加載完畢后通知master 進(jìn)行增量同步
注意: 快照同步時,master的復(fù)制buffer不停前移,如果快照時間過長或者復(fù)制buffer過小, 會導(dǎo)致同步期間 復(fù)制buffer被覆蓋, 導(dǎo)致無法進(jìn)行增量復(fù)制,會再次發(fā)起快照同步,陷入死循環(huán). 合理配置buffer參數(shù)大小 (replication buffe)
replication buffer的作用 replication buffer里面存放的數(shù)據(jù)是下面三個時間內(nèi)master數(shù)據(jù)更新操作: master執(zhí)行rdb bgsave產(chǎn)生snapshot的時間內(nèi)master變更的數(shù)據(jù) master發(fā)送rdb到slave網(wǎng)絡(luò)傳輸時間內(nèi)master變更的數(shù)據(jù) slave load rdb文件把數(shù)據(jù)恢復(fù)到內(nèi)存的時間內(nèi) master變更的數(shù)據(jù) 主從全量同步過程中,主庫是不會阻塞的,這個時候還會繼續(xù)接收新的寫請求, 并寫入replication buffer redis server會為每一個連接到自己的客戶端創(chuàng)建一個replication buffer,用來緩存主庫執(zhí)行的命令。 等從庫加載完成RDB文件后,主庫就會把緩存的命令發(fā)送給從庫,完成全量最終的全量同步 如果replication buffer寫滿了,無論客戶端是普通客戶端還是從庫,只能斷開跟這個客戶端的連接了。這樣從庫全量同步失敗,只能再次嘗試全量同步 client-output-buffer-limit normal 0 0 0 client-output-buffer-limit slave 256mb 64mb 60 client-output-buffer-limit pubsub 32mb 8mb 60 client-output-buffer-limit
2 增量同步
Redis 同步的是指令流,
master: 將數(shù)據(jù)修改指令落到本地內(nèi)存的buffer中, 異步將buffer同步到slave節(jié)點(diǎn)
slave: 執(zhí)行同步過來的指令流 同時向master反饋同步的偏移量
redis從庫加載完成RDB文件后,就會繼續(xù)同步從庫的增量寫命令。如果從庫的讀取速度比較慢,就有可能導(dǎo)致從庫還未讀取的操作被主庫新寫的操作覆蓋了,這會導(dǎo)致主從庫間的數(shù)據(jù)不一致
解決方案 repl_backlog_buffer環(huán)形緩沖區(qū) (參數(shù) repl-backlog-size)
repl_backlog_buffer 是一個環(huán)形緩沖區(qū),主庫會記錄自己寫到的位置,從庫則會記錄自己 已經(jīng)讀到的位置
1 主庫的寫命令,除了傳給從庫后,還會寫入repl_backlog_buffer 2 當(dāng)主從斷開后,重新建立連接,從庫會發(fā)送之前的那個命令:psync $master_runid $offset (slave 發(fā)送slave_repl_offset 發(fā)給主庫) 3 主庫就會在repl_backlog_buffer中找到offset的位置,把之后的寫命令寫入replication buffer同步給從庫 (master 判斷master_repl_offset 和 slave_repl_offset 之間的差距) 4 如果repl_backlog_buffer已經(jīng)能被覆蓋, 則會觸發(fā)快照同步
備注 所有slave從庫共享一個 repl_backlog_buffer (環(huán)形結(jié)構(gòu))
其大小可以根據(jù) 估算積壓緩沖區(qū)的大小repl-backlog-size值不小于這兩者的乘積。 緩沖空間大小 =主庫更新 命令 *((master執(zhí)行rdb bgsave的時間)+ (master發(fā)送rdb到slave的時間) + (slave load rdb文件的時間) ) repl_backlog_size = 緩沖空間大小 * 2 如果主庫每秒寫入 2000 個操作,每個操作的大小為 2KB, 網(wǎng)絡(luò)每秒能傳輸 1000 個操作,那么有1000個操作需要緩沖起來,這就至少需要 2MB 的緩沖空間。 否則,新寫的命令就會覆蓋掉舊操作了。為了應(yīng)對可能的突發(fā)壓力,把 repl_backlog_size 設(shè)為 4MB
三 Sentinel
Redis從2.8開始正式提供了Sentinel(哨兵)來解決主從切換問題;根據(jù)投票數(shù)自動將從庫轉(zhuǎn)換為主庫, 類似zookeeper集群, 集群高可用心臟。
Sentinel 負(fù)責(zé)持續(xù)健康主節(jié)點(diǎn)的健康, 客戶端連接集群時,會首先連接Sentinel,
通過sentinel來尋址主節(jié)點(diǎn),然后再連接主節(jié)點(diǎn)進(jìn)行數(shù)據(jù)交互, 當(dāng)主down了, 客戶端重新向sentinel尋址, 完成主備切換,主修復(fù)后加入集群會成為從節(jié)點(diǎn)
如果主從延遲較大,sentinel無法保證切換時 主從數(shù)據(jù)狀態(tài)一致,但會盡可能通過配置參數(shù)來保證一致性
min-slaves-to-wirte 1 # 至少一個從節(jié)點(diǎn)在進(jìn)行正常復(fù)制, 否則停止對外服務(wù), 不可用 min-slaves-max-lag 10 # 10s內(nèi)沒有收到slave節(jié)點(diǎn)心跳,意味著slave節(jié)點(diǎn)不正常
Sentinel的使用
from redis.sentinel import Sentinel sentinel = Sentinel([('localhost', 26379)], socket_timeout=0.1) master = sentinel.master_for('mymaster', socket_timeout=0.1) slave = sentinel.slave_for ('mymaster', socket_timeout=0.1) master.set('k1','v1') slave.get('k1')
哨兵模式是一種特殊的模式,首先Redis提供了哨兵的命令,哨兵是一個獨(dú)立的進(jìn)程,作為進(jìn)程,它會獨(dú)立運(yùn)行
其原理是哨兵通過發(fā)送命令,等待Redis服務(wù)器響應(yīng),從而監(jiān)控運(yùn)行的多個Redis實(shí)例.
哨兵作用
1通過發(fā)送命令,讓Redis服務(wù)器返回監(jiān)控其運(yùn)行狀態(tài),包括主服務(wù)器和從服務(wù)器。
2當(dāng)哨兵監(jiān)測到master宕機(jī),會自動將slave切換成master,然后通過發(fā)布訂閱模式通知其他的從服務(wù)器,修改配置文件,讓它們切換主機(jī)。
使用多個哨兵進(jìn)行監(jiān)控,各個哨兵之間還會進(jìn)行監(jiān)控,這樣就形成了多哨兵模式。
假設(shè)主服務(wù)器宕機(jī),哨兵1先檢測到這個結(jié)果,系統(tǒng)并不會馬上進(jìn)行failover過程,僅僅是哨兵1主觀的認(rèn)為主服務(wù)器不可用,這個現(xiàn)象稱為主觀下線。
當(dāng)后面的哨兵也檢測到主服務(wù)器不可用,并且數(shù)量達(dá)到一定值時,那么哨兵之間就會進(jìn)行一次投票,投票的結(jié)果由一個哨兵發(fā)起,進(jìn)行failover[故障轉(zhuǎn)移]操作。
切換成功后,就會通過發(fā)布訂閱模式,讓各個哨兵把自己監(jiān)控的從服務(wù)器實(shí)現(xiàn)切換主機(jī),這個過程稱為客觀下線
哨兵配置 & 啟動
Redis-sentinel /myredis/sentinel.conf
# Example sentinel.conf port 26379 # 哨兵sentinel實(shí)例運(yùn)行的端口 默認(rèn)26379 dir /tmp # 哨兵sentinel的工作目錄 # 哨兵sentinel監(jiān)控的redis主節(jié)點(diǎn)的 ip port # master-name 可以自己命名的主節(jié)點(diǎn)名字 只能由字母A-z、數(shù)字0-9 、這三個字符".-_"組成。 # quorum 配置多少個sentinel哨兵統(tǒng)一認(rèn)為master主節(jié)點(diǎn)失聯(lián) 那么這時客觀上認(rèn)為主節(jié)點(diǎn)失聯(lián)了 # sentinel monitor
private static JedisSentinelPool jedisSentinelPool=null; public static Jedis getJedisFromSentinel(){ if(jedisSentinelPool==null){ Set
# SCRIPTS EXECUTION #配置當(dāng)某一事件發(fā)生時所需要執(zhí)行的腳本,可以通過腳本來通知管理員,例如當(dāng)系統(tǒng)運(yùn)行不正常時發(fā)郵件通知相關(guān)人員。 #對于腳本的運(yùn)行結(jié)果有以下規(guī)則: #若腳本執(zhí)行后返回1,那么該腳本稍后將會被再次執(zhí)行,重復(fù)次數(shù)目前默認(rèn)為10 #若腳本執(zhí)行后返回2,或者比2更高的一個返回值,腳本將不會重復(fù)執(zhí)行。 #如果腳本在執(zhí)行過程中由于收到系統(tǒng)中斷信號被終止了,則同返回值為1時的行為相同。 #一個腳本的最大執(zhí)行時間為60s,如果超過這個時間,腳本將會被一個SIGKILL信號終止,之后重新執(zhí)行。 #通知型腳本:當(dāng)sentinel有任何警告級別的事件發(fā)生時(比如說redis實(shí)例的主觀失效和客觀失效等 等),將會去調(diào)用這個腳本,這時這個腳本應(yīng)該通過郵件,SMS等方式去通知系統(tǒng)管理員關(guān)于系統(tǒng)不正常運(yùn)行的信息。 #調(diào)用該腳本時,將傳給腳本兩個參數(shù),一個是事件的類型,一個是事件的描述。如果sentinel.conf配置文件中配置了這個腳本路徑,那么必須保證這個腳本存在于這個路徑,并且是可執(zhí)行的,否則sentinel無法正常啟動成功。 #通知腳本 # sentinel notification-script
drop external table ext_redisparam_info CREATE EXTERNAL TABLE ext_redisparam_info (like sor.redisparam_info) LOCATION ( 'gpfdist://******:8100/redisParm.csv' ) FORMAT 'text' (delimiter E'|' null E'\\N' escape E'\\') SEGMENT REJECT LIMIT 1000 ROWS select *,round(t.diff/1024.0,2) as kb,round(t.diff/1024.0/1024.0,2) mb from( select *, param_value::bigint -( lead( param_value::bigint ) over( order by evt_timestamp desc )) as diff from sor.redisparam_info where port = '6384' ) t
Redis 分布式
版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時內(nèi)刪除侵權(quán)內(nèi)容。