主從復(fù)制的常用相關(guān)配置
-
Slaveof
slaveof <masterip> <masterport>
slave實(shí)例需要配置該項(xiàng),指向master的(ip,port)
-
masterauth
masterauth <master-password>
如果master實(shí)例啟用了密碼保護(hù)吊档,則該配置項(xiàng)需要填master的啟動(dòng)密碼庸推;
如果未啟用茫虽,需要將該配置項(xiàng)注視掉。
-
slave-serve-stale-data
指定slave與master連接中斷時(shí)的動(dòng)作。默認(rèn)為yes浑槽,表明slave會(huì)繼續(xù)應(yīng)答來(lái)自client的請(qǐng)求,但這些數(shù)據(jù)可能已經(jīng)過(guò)期(因?yàn)檫B接中斷導(dǎo)致無(wú)法從master同步)返帕。若配置為no桐玻,則slave除正常應(yīng)答“INFO”和“SLAVEOF”命令外,其余來(lái)自客戶端的請(qǐng)求命令均會(huì)得到“SYNC with master in progress"的應(yīng)答荆萤,直到該slave與master連接重建成功或該slave被提升為master镊靴。
-
slave-read-only
指定slave是否只讀,默認(rèn)為yes链韭。若配置為no偏竟,表示slave是可寫的,但寫的內(nèi)容在主從同步完成后會(huì)被刪除掉敞峭。
-
repl-disable-tcp-nodelay
指定向slave同步數(shù)據(jù)時(shí)踊谋,是否禁用socket的NO_DELAY選項(xiàng)。若配置為yes旋讹,則禁用NO_DELAY殖蚕,則TCP協(xié)議棧會(huì)合并小包統(tǒng)一發(fā)送,這樣可以減少主從節(jié)點(diǎn)間的包數(shù)量并節(jié)省寬帶骗村,但會(huì)增加數(shù)據(jù)同步到slave的時(shí)間嫌褪。若配置為no,表明啟用NO_DELAY胚股,則TCP協(xié)議棧不會(huì)延遲小包的發(fā)送時(shí)間笼痛,這樣數(shù)據(jù)同步的延時(shí)會(huì)減少,但需要更大的寬帶琅拌。
-
slave-priority
指定slave的優(yōu)先級(jí)缨伊。在不只1個(gè)slave存在的部署環(huán)境下,當(dāng)master宕機(jī)時(shí)进宝,Redis Sentinel 會(huì)將priority值最小的slave提升為master刻坊。需要注意的是,若該配置項(xiàng)為0党晋,則對(duì)應(yīng)的slave永遠(yuǎn)不會(huì)被Redis Sentinel 自動(dòng)提升為master谭胚。
讀寫分離
復(fù)制數(shù)據(jù)延遲
Redis復(fù)制數(shù)據(jù)的延遲由于異步復(fù)制特性是無(wú)法避免的徐块,延遲取決于網(wǎng)絡(luò)寬帶和命令阻塞情況,比如剛在主節(jié)點(diǎn)寫入數(shù)據(jù)后立刻在從節(jié)點(diǎn)上讀取可能獲取不到灾而。需要業(yè)務(wù)場(chǎng)景允許短時(shí)間內(nèi)的數(shù)據(jù)延遲胡控。對(duì)于無(wú)法容忍大量延遲場(chǎng)景,可以編寫外部監(jiān)控程序監(jiān)聽主從節(jié)點(diǎn)的復(fù)制偏移量旁趟,當(dāng)延遲較大時(shí)觸發(fā)報(bào)警或通知客戶端避免讀取延遲過(guò)高的從節(jié)點(diǎn)昼激。
具體實(shí)現(xiàn)邏輯:
- 監(jiān)控程序定期檢查主從節(jié)點(diǎn)的偏移量,主節(jié)點(diǎn)偏移量在
info replication
的master_repl_offset
指標(biāo)記錄锡搜,從節(jié)點(diǎn)偏移量可以查詢主節(jié)點(diǎn)的slave0
字段的offset
指標(biāo)橙困,它們的差值就是主從節(jié)點(diǎn)延遲的字節(jié)量。 - 對(duì)于無(wú)法容忍大量延遲場(chǎng)景耕餐,可以編寫外部監(jiān)控程序監(jiān)聽主從節(jié)點(diǎn)的復(fù)制偏移量凡傅,當(dāng)延遲較大時(shí)觸發(fā)報(bào)警或者通知客戶端避免讀取延遲過(guò)高的從節(jié)點(diǎn),同時(shí)從節(jié)點(diǎn)的
slave-serve-stable-data
參數(shù)也與此有關(guān)蛾方,它控制這種情況下從節(jié)點(diǎn)的表現(xiàn)像捶,當(dāng)從庫(kù)同主機(jī)失去連接或者復(fù)制正在進(jìn)行,從機(jī)庫(kù)有兩種運(yùn)行方式桩砰。
讀取過(guò)期數(shù)據(jù)
當(dāng)主節(jié)點(diǎn)存儲(chǔ)大量設(shè)置超時(shí)的數(shù)據(jù)時(shí)拓春,redis內(nèi)部需要維護(hù)過(guò)期數(shù)據(jù)刪除策略,刪除策略主要有兩種:
-
惰性刪除
主節(jié)點(diǎn)每次處理讀取命令時(shí)亚隅,都會(huì)檢查健是否超時(shí)硼莽,如果超時(shí)則執(zhí)行·
del
命令刪除鍵對(duì)象,之后del
命令也會(huì)異步發(fā)給從節(jié)點(diǎn)煮纵。因?yàn)楸3謴?fù)制的一致性懂鸵,從節(jié)點(diǎn)自身永遠(yuǎn)不會(huì)主動(dòng)刪除超時(shí)數(shù)據(jù)。 -
定時(shí)刪除
Redis主節(jié)點(diǎn)在內(nèi)部定時(shí)任務(wù)會(huì)循環(huán)采樣一定數(shù)據(jù)量的鍵行疏,當(dāng)發(fā)現(xiàn)采用的鍵過(guò)期時(shí)會(huì)執(zhí)行
del
命令匆光,之后再同步給從節(jié)點(diǎn)。
從節(jié)點(diǎn)故障問(wèn)題
對(duì)于從節(jié)點(diǎn)的故障問(wèn)題酿联,需要在客戶端維護(hù)一個(gè)可用從節(jié)點(diǎn)可用列表终息,當(dāng)從節(jié)點(diǎn)故障時(shí),立刻切換到其他從節(jié)點(diǎn)或主節(jié)點(diǎn)贞让,redis Cluster可以解決這個(gè)問(wèn)題周崭。
配置不一致
主節(jié)點(diǎn)和從節(jié)點(diǎn)不同,經(jīng)常導(dǎo)致主節(jié)點(diǎn)和從節(jié)點(diǎn)的配置不同喳张,并帶來(lái)問(wèn)題续镇。
主從配置不一致是一個(gè)容易忽視的問(wèn)題。對(duì)于有些配置主從之間是可以不一致销部,比如:主節(jié)點(diǎn)關(guān)閉AOF摸航,從節(jié)點(diǎn)開啟AOF制跟。但對(duì)于內(nèi)存相關(guān)的配置必須要一致,比如maxmemory
,hash-max-ziplist-entries
等參數(shù)酱虎。
數(shù)據(jù)丟失:主機(jī)和從機(jī)有時(shí)候發(fā)生配置不一致的情況凫岖,例如maxmemory
不一致。假如主機(jī)配置maxmemory
為8G逢净,從機(jī)設(shè)置為4G,這個(gè)時(shí)候是可以用的歼指,而且不會(huì)報(bào)錯(cuò)爹土。但如果要做高可用,讓從節(jié)點(diǎn)變成主節(jié)點(diǎn)的時(shí)候踩身,就會(huì)發(fā)現(xiàn)數(shù)據(jù)已經(jīng)丟失胀茵,而且無(wú)法挽回。
規(guī)避全量復(fù)制
全量復(fù)制指的是當(dāng)slave斷開并重啟后挟阻,runid產(chǎn)生變化而導(dǎo)致需要在master主機(jī)里拷貝全部數(shù)據(jù)琼娘。這種拷貝全部數(shù)據(jù)的過(guò)程非常耗資源。
全量復(fù)制是不可避免的附鸽,例如第一次的全量復(fù)制就不可避免脱拼,這時(shí)我們需要選擇小主節(jié)點(diǎn),且maxmemory
值不要過(guò)大坷备,這樣就會(huì)比較快熄浓。同時(shí)選擇在低峰值的時(shí)候做全量復(fù)制。
造成全量復(fù)制的原因:
- 主從機(jī)的運(yùn)行runid不匹配省撑。解釋一下赌蔑,主節(jié)點(diǎn)如果重啟,runid將會(huì)發(fā)生變化竟秫。如果從節(jié)點(diǎn)監(jiān)控到runid不是同一個(gè)娃惯,它就會(huì)認(rèn)為你的節(jié)點(diǎn)不安全。當(dāng)發(fā)生故障轉(zhuǎn)移的時(shí)候肥败,如果主節(jié)點(diǎn)發(fā)生故障趾浅,那么從節(jié)點(diǎn)就會(huì)變成主節(jié)點(diǎn)(哨兵和集群)。
- 復(fù)制緩沖區(qū)空間不足拙吉,比如默認(rèn)值為1M潮孽,可以部分復(fù)制,但如果緩沖區(qū)不夠大的話筷黔,首先需要網(wǎng)絡(luò)中斷往史,部分復(fù)制將無(wú)法滿足。其次需要增大復(fù)制緩沖區(qū)配置
repl-backlog-size
佛舱,對(duì)網(wǎng)絡(luò)的緩沖增強(qiáng)椎例。
怎么解決:
- 在一些場(chǎng)景下挨决,可能希望對(duì)主節(jié)點(diǎn)進(jìn)行重啟,例如主節(jié)點(diǎn)內(nèi)存碎片率過(guò)高订歪,或者希望調(diào)整一些只能在啟動(dòng)時(shí)調(diào)整的參數(shù)脖祈。如果使用普通的手段重啟主節(jié)點(diǎn),會(huì)使得runid發(fā)生變化刷晋,可能導(dǎo)致不必要的全量復(fù)制盖高。
- 為了解決這個(gè)問(wèn)題,Redis提供了debug reload的重啟方式:重啟后眼虱,主節(jié)點(diǎn)的runid和offset都不受影響喻奥,避免了全量復(fù)制。
規(guī)避復(fù)制風(fēng)暴
復(fù)制風(fēng)暴是指大量從節(jié)點(diǎn)對(duì)同一主節(jié)點(diǎn)或者對(duì)同一臺(tái)機(jī)器的多個(gè)主節(jié)點(diǎn)短時(shí)間內(nèi)發(fā)起全量復(fù)制的過(guò)程捏悬。復(fù)制風(fēng)暴對(duì)發(fā)起復(fù)制的主節(jié)點(diǎn)或者機(jī)器造成大量開銷撞蚕,導(dǎo)致 CPU、內(nèi)存过牙、帶寬消耗甥厦。因此我們應(yīng)該分析出復(fù)制風(fēng)暴發(fā)生的場(chǎng)景,提前采用合理的方式規(guī)避寇钉。規(guī)避方式有如下幾個(gè)刀疙。
單節(jié)點(diǎn)復(fù)制風(fēng)暴
當(dāng)一個(gè)主機(jī)下面掛了很多個(gè) slave從機(jī)的時(shí)候,主機(jī) master 掛了扫倡,這時(shí) master 主機(jī)重啟后庙洼,因?yàn)?runid 發(fā)生了變化,所有的 slave 從機(jī)都要做一次全量復(fù)制镊辕。這將引起單節(jié)點(diǎn)和單機(jī)器的復(fù)制風(fēng)暴油够,開銷會(huì)非常大。
解決:
- 可以采用樹狀結(jié)構(gòu)降低多個(gè)從節(jié)點(diǎn)對(duì)主節(jié)點(diǎn)的消耗征懈。
- 從節(jié)點(diǎn)采用樹狀樹非常有用石咬,網(wǎng)絡(luò)開銷交給位于中間層的從節(jié)點(diǎn),而不必消耗頂層的主節(jié)點(diǎn)卖哎。但是這種樹狀結(jié)構(gòu)也帶來(lái)了運(yùn)維的復(fù)雜性鬼悠,增加了手動(dòng)和自動(dòng) 處理故障轉(zhuǎn)移的難度。
單機(jī)器復(fù)制風(fēng)暴
由于 Redis 的單線程架構(gòu)亏娜,通常單臺(tái)機(jī)器會(huì)部署多個(gè) Redis 實(shí)例焕窝。當(dāng)一臺(tái)機(jī)器(machine)上同時(shí)部署多個(gè)主節(jié)點(diǎn)(master)時(shí),如果每個(gè) master 主機(jī)只有一臺(tái) slave 從機(jī)维贺,那么當(dāng)機(jī)器宕機(jī)以后它掂,會(huì)產(chǎn)生大量全量復(fù)制。這種情況是非常危險(xiǎn)的情況,帶寬?cǎi)R上會(huì)被占用虐秋,會(huì)導(dǎo)致不可用榕茧。
解決:
- 應(yīng)該把主節(jié)點(diǎn)盡量分散在多臺(tái)機(jī)器上,避免在單臺(tái)機(jī)器上部署過(guò)多的主節(jié)點(diǎn)客给。
- 當(dāng)主節(jié)點(diǎn)所在機(jī)器故障后提供故障轉(zhuǎn)移機(jī)制用押,避免機(jī)器恢復(fù)后進(jìn)行密集的全量復(fù)制。
補(bǔ)充
###########從庫(kù)##############
#設(shè)置該數(shù)據(jù)庫(kù)為其他數(shù)據(jù)庫(kù)的從數(shù)據(jù)庫(kù)
slaveof <masterip> <masterport>
#主從復(fù)制中靶剑,設(shè)置連接master服務(wù)器的密碼(前提master啟用了認(rèn)證)
masterauth <master-password>
# 當(dāng)從庫(kù)同主庫(kù)失去連接或者復(fù)制正在進(jìn)行蜻拨,從庫(kù)有兩種運(yùn)行方式:
# 1) 如果slave-serve-stale-data
設(shè)置為yes(默認(rèn)設(shè)置),從庫(kù)會(huì)繼續(xù)相應(yīng)客戶端的請(qǐng)求
# 2) 如果slave-serve-stale-data
設(shè)置為no桩引,除了INFO和SLAVOF命令之外的任何請(qǐng)求都會(huì)返回一個(gè)錯(cuò)誤"SYNC with master in progress"
slave-serve-stale-data yes
#當(dāng)主庫(kù)發(fā)生宕機(jī)時(shí)候官觅,哨兵會(huì)選擇優(yōu)先級(jí)最高的一個(gè)稱為主庫(kù),從庫(kù)優(yōu)先級(jí)配置默認(rèn)100阐污,數(shù)值越小優(yōu)先級(jí)越高
slave-priority 100
#從節(jié)點(diǎn)是否只讀;默認(rèn)yes只讀咱圆,為了保持?jǐn)?shù)據(jù)一致性笛辟,應(yīng)保持默認(rèn)。
slave-read-only yes
########主庫(kù)配置##############
#在slave和master同步后(發(fā)送psync/sync)序苏,后續(xù)的同步是否設(shè)置成TCP_NODELAY假如設(shè)置成yes手幢,則redis會(huì)合并小的TCP包從而節(jié)省帶寬,但會(huì)增加同步延遲(40ms)忱详,造成master與slave數(shù)據(jù)不一致假如設(shè)置成no围来,則redis master會(huì)立即發(fā)送同步數(shù)據(jù),沒有延遲匈睁。
#前者關(guān)注性能监透,后者關(guān)注一致性
repl-disable-tcp-nodelay no
#從庫(kù)會(huì)按照一個(gè)時(shí)間間隔向主庫(kù)發(fā)送PING命令來(lái)判斷主服務(wù)器是否在線,默認(rèn)是10秒
repl-ping-slave-period 10
#復(fù)制積壓緩沖區(qū)大小設(shè)置
repl-backlog-size 1mb
#master沒有slave一段時(shí)間會(huì)釋放復(fù)制緩沖區(qū)的內(nèi)存航唆,repl-backlog-ttl
用來(lái)設(shè)置該時(shí)間長(zhǎng)度胀蛮。單位為秒。
repl-backlog-ttl 3600
#redis提供了可以讓master停止寫入的方式糯钙,如果配置了min-slaves-to-write
粪狼,健康的slave的個(gè)數(shù)小于N,mater就禁止寫入任岸。master最少得有多少個(gè)健康的slave存活才能執(zhí)行寫命令再榄。這個(gè)配置雖然不能保證N個(gè)slave都一定能接收到master的寫操作,但是能避免沒有足夠健康的slave的時(shí)候享潜,master不能寫入來(lái)避免數(shù)據(jù)丟失困鸥。設(shè)置為0是關(guān)閉該功能。
min-slaves-to-write 3
min-slaves-max-lag 10