redis的主從(master-slave)
-
單點redis服務器的弊端
單個服務器的情況下,如果這個服務器發(fā)生故障,那數(shù)據(jù)肯定就GG了。整個服務器要承受所有的請求負載(畢竟我們還是要做負載均衡嘛)
所以redis提供了復制功能(replication)功能。將數(shù)據(jù)庫復制多個副本,然后放在不同的服務器上(放在一個服務器上,就是不同的redis實例咯)。這樣即使一臺數(shù)據(jù)庫出現(xiàn)故障,其他的還是能提供服務。
redis復制中,數(shù)據(jù)庫有兩種,一種就做主數(shù)據(jù)庫(可讀可寫),另一種叫做從數(shù)據(jù)庫(一般就是只讀的,但是可以接受從主數(shù)據(jù)庫同步過來的數(shù)據(jù))。就像這個樣子:
redis主從.png windows下配置多個redis實例
首先進入redis的安裝目錄,復制redis.windows-service.conf文件,改名為例如redis.windows-service-6380.conf,修改里面的port和logfile(一定要修改,總不能所有的redis要一份日志文件吧?),在然后進入win32控制臺,執(zhí)行下面這條命令(E:\redis1是我的安裝目錄):

將這個redis實例配置成服務,下次你就可以直接啟動該項服務了。
然后嘗試連接新配置的redis實例:

接下來配置主從:修改配置文件,在配置文件中加上slaveof參數(shù)執(zhí)行主數(shù)據(jù)庫就好了或者在運行的時候直接通過命令行配置。
如果當前從數(shù)據(jù)庫已經和一個主數(shù)據(jù)庫同步了,slaveof命令會停止與先前的主數(shù)據(jù)庫同步,轉而與新的主數(shù)據(jù)庫同步。還可以使用slaveof no one使得當前數(shù)據(jù)庫升級為主數(shù)據(jù)庫。
Master-Slave的原理
當一個從數(shù)據(jù)庫啟動后,會向主數(shù)據(jù)庫發(fā)送sync命令。主數(shù)據(jù)庫接收到命令之后會在后臺(fork當前進程)進行RDB快照,以及緩存執(zhí)行快照期間執(zhí)行的命令,當快照完成之后,將數(shù)據(jù)發(fā)送給從數(shù)據(jù)庫。從數(shù)據(jù)庫接收到數(shù)據(jù)之后,將數(shù)據(jù)寫入臨時文件中,寫入完成之后,用新的RDB文件替換舊的RDB文件,接下來RDB持久化啟動恢復,再接著執(zhí)行緩存的命令。至此,復制初始化的過程完成。從此以后,主數(shù)據(jù)庫每當執(zhí)行寫命令時,會將該命令發(fā)送給它的所有從數(shù)據(jù)庫,從而完成數(shù)據(jù)同步。
注意:即使主從數(shù)據(jù)庫同步,在一定時間窗口,還是存在主從數(shù)據(jù)庫不一致。
redis主從配置完成之后,這樣即使一臺服務器崩潰之后,還是有其他服務器提供服務(提高系統(tǒng)整體的容災能力),同時做到了讀寫分離。-
redis的增量復制
在master-slave模式中,如果從數(shù)據(jù)庫與主數(shù)據(jù)庫掉線,那么就要重新發(fā)送sync命令進行數(shù)據(jù)同步。這時主數(shù)據(jù)庫就不得不重新進行快照(I/O操作)并重傳,仔細想想還怪費時的,這個時候只重傳在此期間執(zhí)行的命令就好了。所以redis2.8提供了增量復制的功能。
增量復制實現(xiàn):
- 1.從數(shù)據(jù)庫會存儲主數(shù)據(jù)庫的run id。每個redis實例都有一個,重啟之后就會又生成一個新的run id
- 2.在復制同步階段,主數(shù)據(jù)庫每將一個命令發(fā)送給從數(shù)據(jù)庫時,都會同時把命令放進一個積壓隊列中(backlog)中,并記錄存放的命令的偏移量范圍。
- 3.從數(shù)據(jù)庫接收到命令之后,會記錄該命令的偏移量。
首先主數(shù)據(jù)庫判斷從數(shù)據(jù)庫傳過來的run id是否和自己相同,相同的話再判斷從數(shù)據(jù)庫最后同步成功的命令偏移量是否在積壓隊列中,在就執(zhí)行增量復制。兩個條件不同時滿足的話就進行一次全部同步。
執(zhí)行info replication會顯示積壓隊列相關信息:
積壓隊列信息.png

