redis 主從同步原理


1.為什么需要主從同步

  在使用redis服務的時候如果時單機服務,一旦單機服務宕機了,那么可能導致我們整個系統處於不可用狀態,或者當系統的訪問量大了以后單機的redis服務成功了整個系統的瓶頸,這時候就到了主從復制展示伸手的時候了.主從復制可以幫我們完成以下功能.

  1.1 數據冗余:主從復制實現了數據的熱備份,是持久化之外的一種數據冗余方式。

  1.2 故障恢復:當主節點出現問題時,可以由從節點提供服務,實現快速的故障恢復;實際上是一種服務的冗余。

  1.3 負載均衡:在主從復制的基礎上,配合讀寫分離,可以由主節點提供寫服務,由從節點提供讀服務(即寫Redis數據時應用連接主節點,讀Redis數據時應用連接從節點),分擔服務器負載;尤其是在寫少讀多的場景下,通過多個從節點分擔讀負載,可以大大提高Redis服務器的並發量。

  1.4 高可用基石:主從復制還是哨兵和集群能夠實施的基礎,因此說主從復制是Redis高可用的基礎。

 

2.相關配置

  1.replicaof 

    在5.0之前redis可以通過在從服務器上執行slaveof ip port來執行主服務器,在5.0之后可以通過replicaof ip port來指定主服務器.

  2.slave-read-only

    redis的主從只能是主服務器的寫命令同步到從服務器,而不能反過來,所以為了保證數據一致性,從服務器只能接收讀請求,而不接收寫和修改請求.redis提供了slave-read-only參數進行控制,

  3.min-slaves-to-write

    當一個主服務器有多個從服務器的時候,為了保證數據的可靠性,需要在有超過n個從服務器的時候才允許主服務器執行寫操作命令.為此redis提供了min-slaves-to-write參數進行控制,min-slaves-max-lag來確定從服務器的延遲

  4.client-output-buffer-limit

    設置生成rdb文件的時候緩沖區(replication_buffer)的大小

    語法:client-output-buffer-limit <class> <hard limit> <soft limit> <soft seconds>

    class可選值有三個,Normal,Slaves和Pub/Sub;hard limit: 緩沖區大小的硬性限制。soft limit: 緩沖去大小的軟性限制。soft seconds: 緩沖區大小達到了(超過)soft limit值的持續時間。

  5.repl-backlog-size

    設置增量同步的時候寫命令緩沖區(repl_backlog_buffer)的大小

3.原理分析

  3.1 主從同步流程

    3.1.1.建立連接

      a).當從庫執行了replicaof ip port命令之后從服務器保存主服務器的ip和porti信息,

      b).從服務器和主服務器建立socket連接,

      c).從服務器發送ping命令,並且接收主服務器的pong命令,如果沒有接收到pong命令則從新建立連接

      d).如果主服務器設置了訪問密碼則進行權限校驗,如果權限校驗通過則開始進行數據同步

    2.確定同步方式

      a).從服務器發送psync runid offset命令到主服務器,第一次同步的時候由於還沒有主服務器的runid,所以使用?代替

      b).主服務器收到psync命令之后首先判斷runid是否和自己的runid一致,如果不一致或者為?,則進行全量同步,主服務器返回給從服務器fullresync響應,如果runid和主服務器一致則判斷offset是否還在repl-backlong_buffer緩沖區的范圍內,如果不在該緩沖區的范圍內了,則進行全量同步,主服務器返回給從服務器fullresync響應,如果在緩沖區范圍內則進行增量同步,主服務器返回給從服務器continue響應.如果主服務器詳情的是fullresync則還會帶上當前服務器runid和目前主庫的復制進度offset

 

  3.2 全量同步

    當主服務器響應給從服務器fullresync響應之后,主服務器開始執行bgsave命令,生成RDB文件,並且在rdb文件生成完之后會把整個rdb文件發送給從服務器,從服務器接收到rdb文件之后會清空自己的數據庫,然后把rdb文件讀取到自己的數據庫中.由於主服務器在生成rdb文件的時候是不阻塞的,主服務器還可以繼續向外提供服務,這時候為了保證主從服務器的數據一致性,主服務器需要把從開始執行bgsave命令到發送rdb文件到從服務器和從服務器把rdb文件恢復到內存中這段時候的所有寫命令保存下來然后發給從服務器執行,保存這些寫命令的空間就是replication_buffer.他是專門用來保存主服務器在生成rdb文件的時候的寫命令的.

    如果在主服務器生成rbd到從服務器根據rdb文件把數據恢復到內存中這段時間產生的寫命令太多導致replication_buffer保存不了會導致主服務器主動斷開主從連接,主服務器會釋放掉相關數據,這時候會重新開始主從復制.如果replication_buffer太小會導致這個過程無限循環.所以推薦把replication_buffer設置的大一些,防止出現這種情況

  3.3 增量同步

    當全量同步完成之后,由於從服務器已經拿到了主服務器的runid和offset,這時候主從服務器之間開始進行增量復制.增量復制的時候主服務器並不是同步的把所有的寫命令直接發送給從服務器而是把寫命令緩存到一個交repl_backlog_buffer的空間中,然后集中把寫命令和offset發送給從服務器,從服務器在接收到命令執行完成之后會把執行了的命令的offset發送給主服務器,這樣主服務器可以根據從服務器返回的offset判斷哪些命令還沒有執行,然后決定下次發送給從服務器的命令和offset.

    repl_backlog_buffer是一個環形空間,時間久了新寫入的數據會把之前寫入的數據覆蓋掉,如果從服務器返回的offset不在這個環形空間中,則主服務器會判定數據不一致,然后觸發一次全量同步.

    repl_backlog_buffer還用在了當主從服務器之間斷開連接重新連接之后,從服務器發送psync命令,並且帶了runid和offset參數,如果主服務器返現offset還在環形空間中,則不會進行全量服務,而是返回continue繼續增量復制.

  3.4無盤復制

    通常來講,一個完全重新同步需要在磁盤上創建一個RDB文件,然后加載這個文件以便為從服務器發送數據。如果使用比較低速的磁盤,這種操作會給主服務器帶來較大的壓力。特別是當系統正在進行 AOF 的 fsync 操作時如果發生快照,fsync 將會被推遲執行,這就會嚴重影響主節點的服務效率。所以從 Redis 2.8.18 版開始支持無盤復制。所謂無盤復制是指主服務器直接通過套接字將快照內容發送到從節點,生成快照是一個遍歷的過程,主節點會一邊遍歷內存,一遍將序列化的內容發送到從節點,從節點還是跟之前一樣,先將接收到的內容存儲到磁盤文件中,再進行一次性加載。

    


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM