1. 程式人生 > >Redis 主從複製原理

Redis 主從複製原理

為什麼要主從複製:

    如果使用redis 的時候只使用一個數據庫服務,那是不存在什麼主從複製的。當redis 服務在兩個以上時才會有主從複製。為了讀寫分離和減輕壓力,在實際生產中一般會用到多個redis 服務。多個服務那就存在資料同步的問題,主從複製就是解決redis 資料同步的問題。

主從複製如何實現:

    從master 複製資料到 slave 有兩種複製方式,一種是全量複製,一種是部分複製。

    全量複製:主節點資料一次性全部發送給從節點。首先這種方式傳送的資料量大,耗費時間和空間是肯定的。

    部分複製:主節點資料可以有選擇地傳送給從節點。像在傳送過程中出現網路閃斷的情況下,原先已將部分資料傳送給從節點了,那麼在網路連通好之後再將另外部分發送給從節點。

    資料同點命令:psync(老版本是sync 不支援部分複製)

    psync 命令相關機制:

        1.主從節點各自複製偏移量;

        2.主節點複製積壓緩衝區;

        3.主節點執行ID;

        4.複製偏移量;

        5.參與複製的主從節點都會維護自身複製偏移量;

    psync {ID} {offset}

    ID:主節點執行ID ,無則為?

    offset:當前從節點已複製的資料的偏移量 ,-1表示第一次複製

    主節點執行ID:該ID是40位十六進位制字元,它的作用是唯一識別redis 節點。該ID是動態分配的,所以它是完全隨機的,在服務重啟或變更整體資料集後原ID將被替換。可以用 info server 命令檢視當前節點的執行ID。

    在主節點收到從節點的psync命令後,將會回覆:

        1.+FULLRESYNC {runID} {offset} 全量複製;

        2.+continue 部分複製 ;

        3.+ERR 無法識別命令,版本低於2.8,得用sync;

    主從複製步驟:

        1.從節點第一次複製時肯定是全量複製,因為並不知道主服務的ID,所以執行psync ? -1 命令;

        2.主節點收到命令,分析出為全量複製,返回 +FULLRESYNC {runID} {offset};

        3.從節點接收到響應,儲存執行ID,下次傳送請求時就可以把ID給寫上了;

        4.主節點執行bgsave ,儲存RDB檔案到本地;

        5.主節點將RDB檔案傳送給從節點,從節點接收到檔案後,直接將其作為資料檔案。該過程涉及檔案傳輸,耗時並且受網路的影響。

        redis 的預設複製時間rel-timeout為60秒,超時則複製失敗。

        在傳輸RDB檔案時,主節點是可以進行寫操作的,此時就會有新產生的資料,那麼這個資料從節點按理說也是應該行到的,但RDB檔案已生成正在傳輸,不能再修改了,怎麼辦呢。實際上此時的操作命令會儲存在複製積壓緩衝區中。在從節點載入完RDB檔案後,主節點再把緩衝區內的資料發給從節點。

        積壓緩衝區預設只有1M,如果在RDB檔案傳輸的這60秒過程中,寫的資料超過1M,那是會發生緩衝區溢位的。所以在傳輸RDB的時候寫的量是不能太大的。

        6.在接收完RDB檔案後,從節點將清空自身的舊資料:flush old data ,然後載入RDB檔案,該載入操作也是個耗時操作。此時從節點的讀操作還是可以繼續的,那麼就有可能發生這些情況:讀到舊的也就是過期的資料、或是剛好資料清空了讀到錯誤資料。這個是可以不讓它讀的:slave-server-stale-data 引數設定開關可讀,預設是開的。

    無盤複製:

        一般的主從複製,主節點是先將RDB檔案儲存到本地的磁碟中,再發送給從節點。無盤複製的意思就是,不儲存在本地的磁碟中,而是直接傳送給從節點。這種情況對網路的要求是比較高的。主要用在機器磁碟情能較差但是網路頻寬充裕的情況下。