什么是主從復(fù)制
redis的主從復(fù)制機制是指可以讓從服務(wù)器(slave)能精確復(fù)制主服務(wù)器(master)的數(shù)據(jù),如下圖所示:
上面的圖表示的是一臺master服務(wù)器與slave服務(wù)器的情況,其實一臺master服務(wù)器也可以對應(yīng)多臺slave服務(wù)器,如下圖所示:
另外,slave服務(wù)器也可以有自己的slave服務(wù)器,這樣的服務(wù)器稱為sub-slave,而這些sub-slave通過主從復(fù)制最終數(shù)據(jù)也能與master保持一致,如下圖所示:
主從復(fù)制的方式和工作原理
Redis的主從復(fù)制是異步復(fù)制,異步分為兩個方面,一個是master服務(wù)器在將數(shù)據(jù)同步到slave時是異步的,因此master服務(wù)器在這里仍然可以接收其他請求,一個是slave在接收同步數(shù)據(jù)也是異步的。
復(fù)制方式
Redis主從復(fù)制分為以下三種方式:
一、當master服務(wù)器與slave服務(wù)器正常連接時,master服務(wù)器會發(fā)送數(shù)據(jù)命令流給slave服務(wù)器,將自身數(shù)據(jù)的改變復(fù)制到slave服務(wù)器。
二、當因為各種原因master服務(wù)器與slave服務(wù)器斷開后,slave服務(wù)器在重新連上master服務(wù)器時會嘗試重新獲取斷開后未同步的數(shù)據(jù)即部分同步,或者稱為部分復(fù)制。
三、如果無法部分同步(比如初次同步),則會請求進行全量同步,這時master服務(wù)器會將自己的rdb文件發(fā)送給slave服務(wù)器進行數(shù)據(jù)同步,并記錄同步期間的其他寫入,再發(fā)送給slave服務(wù)器,以達到完全同步的目的,這種方式稱為全量復(fù)制。
工作原理
master服務(wù)器會記錄一個replicationId的偽隨機字符串,用于標識當前的數(shù)據(jù)集版本,還會記錄一個當數(shù)據(jù)集的偏移量offset,不管master是否有配置slave服務(wù)器,replication Id和offset會一直記錄并成對存在,我們可以通過以下命令查看replication Id和offset:
> info repliaction
通過redis-cli在master或slave服務(wù)器執(zhí)行該命令會打印類似以下信息(不同服務(wù)器數(shù)據(jù)不同,打印信息不同):
connected_slaves:1 slave0:ip=127.0.0.1,port=6380,state=online,offset=9472,lag=1 master_replid:2cbd65f847c0acd608c69f93010dcaa6dd551cee master_repl_offset:9472
當master與slave正常連接時,slave使用PSYNC命令向master發(fā)送自己記錄的舊master的replication id和offset,而master會計算與slave之間的數(shù)據(jù)偏移量,并將緩沖區(qū)中的偏移數(shù)量同步到slave,此時master和slave的數(shù)據(jù)一致。
而如果slave引用的replication太舊了,master與slave之間的數(shù)據(jù)差異太大,則master與slave之間會使用全量復(fù)制的進行數(shù)據(jù)同步。
配置主從復(fù)制
Redis的主從配置非常簡單,我們可以使用兩種方式來配置主從服務(wù)器,在這時我們先假設(shè)Redis的master服務(wù)器地址為192.168.0.101。
客戶端發(fā)送同步命令
# 向客戶端 saveof 192.168.1.101 6379
slave服務(wù)器配置主服務(wù)器
在這里slave服務(wù)器的redis.conf通過saveof選項,可以指定master服務(wù)器,如下:
slaveof 192.168.1.101 6379
通過上面兩種方式的配置,master服務(wù)器與slave服務(wù)器便已經(jīng)可以開始進行數(shù)據(jù)同步了。
master要求驗證
上面配置的是master服務(wù)器沒有設(shè)置密碼的情況,如果master設(shè)置了密碼,則可以在連接到slave服務(wù)器的redis-cli執(zhí)行下面的命令:
# <password>指代實際的密碼 config set masterauth <password>
或者在slave服務(wù)器的redis.conf中配置下面的選項:
# <password>指代實際的密碼 masterauth <password>
避免slave被清空
slave會被清空?slave不用同步了master的數(shù)據(jù)嗎?備份的數(shù)據(jù)怎么會清空了呢?
當master服務(wù)器關(guān)閉了持久化時,如果發(fā)生故障后自動重啟時,由本地沒有保存持久化的數(shù)據(jù),重啟的Redis內(nèi)存數(shù)據(jù)為空,而slave會自動同步master的數(shù)據(jù),這時候,slave服務(wù)器的數(shù)據(jù)也會被清空。
如何避免slave被清空呢?
如果條件允許(一般都可以的),master服務(wù)器還是要開啟持久化,這樣master故障重啟時,可以快速恢復(fù)數(shù)據(jù),而同步這臺master的slave數(shù)據(jù)也不會被清空。
如果master不能開啟持久化,則不應(yīng)該設(shè)置讓master發(fā)生故障后重啟(有些機器會配置自動重啟),而是將某個slave服務(wù)器升級為master服務(wù)器,對外繼續(xù)提供服務(wù)。
slave默認為只讀的
在Redis2.6以后,slave只讀模式是默認開啟的,我們可以通過配置文件中的slave-read-only選項配置是否開啟只讀模式:
# 默認是yes slave-read-only yes/no
或者在客戶端中通過config set命令設(shè)置是否開啟只讀模式:
config set slave-read-only no
上面將slave服務(wù)器設(shè)置為可以寫入,但是要注意,如果slave也配置了自己的從服務(wù)器(sub-slave),那么sub-slave只會同步從master服務(wù)器同步到slave的數(shù)據(jù),而并會同步我們直接寫入slave服務(wù)器的數(shù)據(jù)。
主從復(fù)制中的key過期問題
我們都知道Redis可以通過設(shè)置key的過期時間來限制key的生存時間,Redis處理key過期有惰性刪除和定期刪除兩種機制,而在配置主從復(fù)制后,slave服務(wù)器就沒有權(quán)限處理過期的key,這樣的話,對于在master上過期的key,在slave服務(wù)器就可能被讀取,所以master會累積過期的key,積累一定的量之后,發(fā)送del命令到slave,刪除slave上的key。
如果slave服務(wù)器升級為master服務(wù)器 ,則它將開始獨立地計算key過期時間,而不需要通過master服務(wù)器的幫助。
主從復(fù)制的作用
保存Redis數(shù)據(jù)副本
當我們只是通過RDB或AOF把Redis的內(nèi)存數(shù)據(jù)持久化畢竟只是在本地,并不能保證絕對的安全,而通過將數(shù)據(jù)同步slave服務(wù)器上,可以保留多一個數(shù)據(jù)備份,更好地保證數(shù)據(jù)的安全。
讀寫分離
在配置了主從復(fù)制之后,如果master服務(wù)器的讀寫壓力太大,可以進行讀寫分離,客戶端向master服務(wù)器寫入數(shù)據(jù),在讀數(shù)據(jù)時,則訪問slave服務(wù)器,從而減輕master服務(wù)器的訪問壓力。
高可用性與故障轉(zhuǎn)移
服務(wù)器的高可用性是指服務(wù)器能提供7*24小時不間斷的服務(wù),Redis可以通過Sentinel系統(tǒng)管理多個Redis服務(wù)器,當master服務(wù)器發(fā)生故障時,Sentineal系統(tǒng)會根據(jù)一定的規(guī)則將某臺slave服務(wù)器升級為master服務(wù)器,繼續(xù)提供服務(wù),實現(xiàn)故障轉(zhuǎn)移,保證Redis服務(wù)不間斷。
小結(jié)
Redis的主從復(fù)制可以讓我們把Redis中的數(shù)據(jù)同步到其他服務(wù)器上,為數(shù)據(jù)安全提供更加安全的保障,也可以讓我們的服務(wù)器在發(fā)生故障時而無法重啟時,可以更加快速地切換服務(wù)器,繼續(xù)對外提供服務(wù)。
作者:張君鴻
鏈接:https://juejin.im/post/5d14bb8ff265da1b602915c5