Redis具備高可靠性,體如今兩方面:數據庫
今天咱們學習的就是經過主從複製實現副本冗餘,從而實現Redis的高可靠性。網絡
Redis提供主從庫模式,保證數據副本的一致,主從庫之間採用的是讀寫分離的方式。socket
若是容許全部節點可以處理讀寫請求,就須要解決加鎖、實例間協商、數據同步等操做,會帶來鉅額的開銷。性能
所以採用主從庫模式時,要配置主庫只寫,從庫只讀。學習
當設置了主從庫模式,此時從庫是空的,如何進行主從庫的第一次同步呢?3d
Redis採用全量複製來進行第一次同步,具體有三個步驟,以下圖所示:日誌
第一步,主從庫創建鏈接,協商同步。code
第二步:主庫同步數據給從庫。blog
從庫收到數據後,在本地完成數據加載。這過程依賴於RDB快照。get
第三步,主庫發送新寫命令給從庫
主庫在數據同步過程當中,會記錄全部寫操做,避免丟失同步過程接收的新的寫命令。
關於replication buffer的更多內容,下面再介紹。
若是有多個從庫,每一個從庫都要跟主庫進行全量同步,這樣主庫的壓力會很大。
Redis提供「主-從-從」模式將主庫生成RDB和傳輸RDB的壓力,以級聯的方式分散到從庫上。
簡單來講,構建父子從庫結構,子從庫的數據同步從父從庫獲取。以下圖所示:
在從庫上執行命令:replicaof 所選從庫的IP 6379
,就能夠設置從庫的父從庫了。
至此,主從庫完成了第一次同步,那後續如何保持同步呢?
當主從庫完成同步後,會維護一個網絡鏈接,主庫會經過這個鏈接將後續的命令同步給從庫。
可是這裏有潛在的風險點:若是網絡斷連或者出現阻塞了,那怎麼辦呢?
在Redis 2.8以前,網絡斷了後要從新進行全量複製。但在Redis 2.8以後,Redis提供了增量複製的方式。
當創建了主從結構後,主庫會把寫命令寫入repl_backlog_buffer緩衝區裏,當網絡斷開並從新鏈接後,從庫會發送同步命令,而後主庫再把未同步的命令發送給從庫,從庫執行這些命令就恢復數據一致了。具體流程以下圖所示:
repl_backlog_buffer是一個環形緩衝區,以下圖所示:
因爲其環形結構,當由於網絡問題影響從庫讀取命令的速度,會出現寫滿後繼續寫入命令時,會覆蓋掉從庫還沒讀的內容,從而形成數據不一致,須要從新全量複製。
所以要根據狀況來設置repl_backlog_buffer的大小,經過配置repl_backlog_size來調整緩衝區大小。配置公式爲:緩衝空間大小 = 主庫寫入命令速度 * 操做大小 - 主從庫間網絡傳輸命令速度 * 操做大小。而repl_backlog_size= 緩衝空間 * 2。
例如主庫寫操做2000/秒,每一個操做大小2KB,網絡傳輸1000個操做/秒,那緩衝空間大小=2000*2 - 1000*2=2MB,那repl_backlog_size就設置爲4MB。
爲何主庫間的數據複製同步不使用AOF?
有三方面緣由:
關於replication buffer
每一個與Redis通訊的客戶端(從庫也算client),都會分配一個buffer,全部數據交互都是經過這個buffer進行的。
Redis先把數據寫到這個buffer中,而後再把buffer中的數據發到client的socket中,經過網絡發送出去,完成數據交互。
而主從同步的這個buffer,是用於保證主從數據一致的,因此才叫它replication buffer。
能夠經過配置項client-output-buffer-limit
來配置這個buffer的大小。當保存到buffer裏的內容超過限制,主庫會強制斷開這個client的鏈接。這樣會有潛在風險。
若是從庫處理主庫傳輸的命令很是慢,就會把這個buffer撐滿,而後主庫會斷開鏈接。中斷後,從庫再次發起複製請求,可能會致使惡性循環,引起復制風暴。