Redis基礎篇(六)數據同步:主從複製

Redis具備高可靠性,體如今兩方面:數據庫

  • 一是數據儘可能少丟失,經過前面介紹的持久化方式AOF和RDB,在宕機時能夠恢復數據。
  • 二是服務儘可能少中斷,經過副本冗餘來實現。

今天咱們學習的就是經過主從複製實現副本冗餘,從而實現Redis的高可靠性。網絡

什麼是主從複製

Redis提供主從庫模式,保證數據副本的一致,主從庫之間採用的是讀寫分離的方式。socket

爲何要讀寫分離?

若是容許全部節點可以處理讀寫請求,就須要解決加鎖、實例間協商、數據同步等操做,會帶來鉅額的開銷。性能

所以採用主從庫模式時,要配置主庫只寫,從庫只讀。學習

主從庫如何進行第一次同步?

當設置了主從庫模式,此時從庫是空的,如何進行主從庫的第一次同步呢?3d

Redis採用全量複製來進行第一次同步,具體有三個步驟,以下圖所示:日誌

image

第一步,主從庫創建鏈接,協商同步。code

  1. 從庫發送psync命令,表示進行數據同步。其中runID表示主庫ID,第一次不知道主庫的runID,就設置爲"?"
  2. 主庫收到psync命令後,用FULLRESYNC響應,返回runID(主庫ID)和offset(主庫目前的複製進度)。
  3. 從庫收到響應後,記錄這兩個參數

第二步:主庫同步數據給從庫。blog

從庫收到數據後,在本地完成數據加載。這過程依賴於RDB快照。get

  1. 主庫執行bgsave命令,生成RDB文件,再把文件發強從庫。
  2. 從庫收到RDB文件後,先清空當前數據庫,而後加載RDB文件。

第三步,主庫發送新寫命令給從庫

主庫在數據同步過程當中,會記錄全部寫操做,避免丟失同步過程接收的新的寫命令。

  1. 主庫使用replication buffer來新的寫命令。
  2. 當從庫加載RDB文件完成後,主庫再把replication buffer的內容發送給從庫,從庫再執行這些操做實現同步。

關於replication buffer的更多內容,下面再介紹。

若是有多個從庫,每一個從庫都要跟主庫進行全量同步,這樣主庫的壓力會很大。

主從級聯模式

Redis提供「主-從-從」模式將主庫生成RDB和傳輸RDB的壓力,以級聯的方式分散到從庫上。

簡單來講,構建父子從庫結構,子從庫的數據同步從父從庫獲取。以下圖所示:

image

在從庫上執行命令:replicaof 所選從庫的IP 6379,就能夠設置從庫的父從庫了。

至此,主從庫完成了第一次同步,那後續如何保持同步呢?

如何保持同步?

當主從庫完成同步後,會維護一個網絡鏈接,主庫會經過這個鏈接將後續的命令同步給從庫。

可是這裏有潛在的風險點:若是網絡斷連或者出現阻塞了,那怎麼辦呢?

主從庫間網絡斷了怎麼辦?

在Redis 2.8以前,網絡斷了後要從新進行全量複製。但在Redis 2.8以後,Redis提供了增量複製的方式。

當創建了主從結構後,主庫會把寫命令寫入repl_backlog_buffer緩衝區裏,當網絡斷開並從新鏈接後,從庫會發送同步命令,而後主庫再把未同步的命令發送給從庫,從庫執行這些命令就恢復數據一致了。具體流程以下圖所示:

增量複製流程

repl_backlog_buffer是一個環形緩衝區,以下圖所示:

image

因爲其環形結構,當由於網絡問題影響從庫讀取命令的速度,會出現寫滿後繼續寫入命令時,會覆蓋掉從庫還沒讀的內容,從而形成數據不一致,須要從新全量複製。

所以要根據狀況來設置repl_backlog_buffer的大小,經過配置repl_backlog_size來調整緩衝區大小。配置公式爲:緩衝空間大小 = 主庫寫入命令速度 * 操做大小 - 主從庫間網絡傳輸命令速度 * 操做大小。而repl_backlog_size= 緩衝空間 * 2

例如主庫寫操做2000/秒,每一個操做大小2KB,網絡傳輸1000個操做/秒,那緩衝空間大小=2000*2 - 1000*2=2MB,那repl_backlog_size就設置爲4MB。

拓展

爲何主庫間的數據複製同步不使用AOF?

有三方面緣由:

  1. RDB文件是通過二進制壓縮的,文件很小,這樣主從庫間傳輸就很快。
  2. 從庫加載RDB文件速度很快,而AOF日誌還要逐行命令執行,速度很慢。
  3. 假設使用AOF,那就必須打開AOF,Redis默認是不開啓AOF的,可能會影響Redis性能。

關於replication buffer

每一個與Redis通訊的客戶端(從庫也算client),都會分配一個buffer,全部數據交互都是經過這個buffer進行的。

Redis先把數據寫到這個buffer中,而後再把buffer中的數據發到client的socket中,經過網絡發送出去,完成數據交互。

而主從同步的這個buffer,是用於保證主從數據一致的,因此才叫它replication buffer。

能夠經過配置項client-output-buffer-limit來配置這個buffer的大小。當保存到buffer裏的內容超過限制,主庫會強制斷開這個client的鏈接。這樣會有潛在風險。

若是從庫處理主庫傳輸的命令很是慢,就會把這個buffer撐滿,而後主庫會斷開鏈接。中斷後,從庫再次發起複製請求,可能會致使惡性循環,引起復制風暴。

小結

  • 主從庫模式是採用RDB快照的全量複製 + 基於長鏈接的網絡通訊實現主從複製的。
  • 經過「主-從-從」模式,將主庫生成RDB和傳輸RDB的壓力,以級聯的方式分散到從庫上。
  • 當網絡中斷,經過主庫的repl_backlog_buffer,實現增量複製,無須從新全量複製。
  • repl_backlog_buffer是環形緩衝區,要根據網絡情況,合理配置其大小。
  • 一個Redis實例的數據庫不要太大,在幾GB比較合適,這樣能夠減小RDB文件生成、傳輸和從新加載的開銷。

參考資料

相關文章
相關標籤/搜索