1. 程式人生 > 其它 >聊聊redis的主從複製吧

聊聊redis的主從複製吧

  • 聊聊基礎概念

主從複製與主從替換

主從複製不同於主從替換,主從複製是正常情況下主節點同步資料到從節點;主從替換是主節點掛了之後,把從節點替換為主節點;

從節點存在的意義:備份主節點資料+負載均衡(對外提供可讀操作)

從節點配置主節點的資訊(兩種方式)

1、臨時配置:啟動從節點的redis-cli執行命令【slaveof host port】,host是主節點的ip,port是主節點的埠號,結果總是返回ok

2、永久配置:進入redis.conf,新增【slaveof host port】到檔案中

runid和offset

runid:每個redis在啟動或重啟時都會生成一個唯一的runid;

offset:主從節點都有自己的主從複製偏移量,主節點複製資料到從節點時,從節點的偏移量的offset=原始offset+命令資料長度,同時從節點會把'從offset'發給主節點,所以主節點會同時儲存'主offset'和'從offset',主節點可以通過判斷'主offset'是否等於'從offset'來判斷主從是否一致

backlog:是一個複製積壓緩衝區,最大1M,主從同步的整個過程中主節點還會被外界寫入資料,所以在主從同步進行時,主節點會把這些外部寫入的'命令資料'儲存一份備份到backlog,在主從同步完rdb檔案後,主節點還需要同步快取中的這些'命令資料'給到從節點(或者在'命令資料'因網路問題丟失後,主節點也可以從backlog中複製備份的資料重新同步到從節點)

主從複製的過程

  • 主從複製預設使用rdb檔案的原因?

    (1)rdb檔案是二進位制檔案比較小,所以主節點向磁碟寫入rdb的I/O效率以及主節點傳輸rdb檔案給從節點的效率都比aof檔案高

    (2)rdb檔案是二進位制檔案比較小,所以從節點寫入rdb檔案恢復資料的效率也比aof檔案高

  • 全量複製的過程?

    (1) 一開始從節點執行【slaveof host port】命令,查詢網路上的主節點,找到後傳送ping給主節點,主節點返回pong,這樣雙方就建立了連線關係,建立了連線關係後就可以進行資料的複製了

    (2) 從節點發送【psync ? -1】給主節點,'?'是因為從節點第一次不知道主節點的runid所以用?代替,-1表示從節點自己的偏移量(首次主從複製固定為-1)

    (3) 主節點收到-1後知道這是第一次主從複製,返回【funllresync 主runid 主offset】給從節點,從節點收到後儲存在自己的資訊中

    (4) 主節點發完fullresync命令後馬上執行bgsave命令生成rdb檔案(rdb儲存在磁碟中、由redis主執行緒分出一個子執行緒執行bgsave),然後把rdb檔案傳送給從節點

    (5) 主節點在執行bgsave命令和傳送rdb檔案給從節點的時候,還會被外界寫入資料(簡稱'命令資料'),主節點會將這些'命令資料'儲存一份到backlog緩衝區中,同步完rdb檔案後就會繼續同步緩衝區中的這些'命令資料'

    (6) 從節點收到rdb檔案後會先清空本地記憶體資料再載入rdb檔案資料到本節點,載入完後再執行主節點推過來的'命令資料'相應的命令('命令資料'其實就是一些寫命令)

  • 增量複製的過程?
    • 什麼時候才會需要增量複製:在主從同步的整個過程中,所有的命令都可能發生網路中斷的情況,這時候就需要增量同步。
    • 過程:
      不管在什麼時候主節點都會將'寫命令'記錄在一個叫 repl_backlog_buffer的緩衝區中,該緩衝區是一個環形陣列【在執行bgsave的時候寫命令也會寫入全量複製中的backlog,故此時會同時將寫命令記錄在這兩個緩衝區】
      -->

      主節點在repl_backlog_buffer上用偏移量'主offerset'記錄寫命令的偏移量(上面全量複製中的'主offerset'就是這個值,理論上應為repl_backlog_buffer中最新的資料位置)

      -->

      從節點也有自己主從同步過程中最新資料的位置偏移'從offerset',理論上這兩個偏移值是相同的,但是在網路中斷時,可能'主offerset'>'從offerset'

      -->

      此時進行增量複製:從節點先發送【psync 主runid 從offset】給主節點,主節點收到後先判斷該'主runid'是否是自身,若是則再去"repl_backlog_buffer緩衝區"中判斷'從offset'偏移量之後的'寫命令'資料是否存在,存在則先發送【continue】命令給從節點,然後傳送 '從offset'~'主offset' 之間的寫命令資料同步給從節點