天天看點

Redis主從複制原理及配置一、Redis高可用二、Redis持久化二、部署Redis主從複制總結

文章目錄

    • 引言
  • 一、Redis高可用
    • 1、在Redis中,實作高可用的技術主要包括持久化、主從複制、哨兵和 Cluster叢集
    • 2、Redis的簡單架構
  • 二、Redis持久化
    • 1、redis提供兩種方式進行持久化
    • 2、RDB持久化
  • 二、部署Redis主從複制
    • 2、三台主機都需要部署Redis、關閉防火牆、關閉增強功能
    • 3、修改Master節點配置檔案
    • 4.修改Slave1節點配置檔案
    • 5.修改Slave2節點配置檔案
    • 6、驗證主從效果
  • 總結

引言

Redis主從複制是指:将一台 Redis 伺服器的資料複制到其它的 Redis 伺服器,前者所在的 Redis 伺服器也被稱為 “主節點”(Master / Leader),後者則被稱為 “從節點”(Slave / Follower)。資料從主節點複制到從節點,主節點的主要任務是實作寫如資料的任務(也有讀資料的權限),而從節點則隻負責讀取資料。在 Redis 的預設配置中,每個啟動的 Redis 服務都是主節點

一、Redis高可用

在web伺服器中,高可用是指伺服器可以正常通路的時間,衡量的标準是在多長時間内可以提供正常服務(99.9%、99.99%、99.999%等等)。

但是在Redis語境中,高可用的含義似乎要寬泛一些,除了保證提供正常服務(如主從分離、快速容災技術),還需要考慮資料容量的擴充、資料安全不會丢失等。

1、在Redis中,實作高可用的技術主要包括持久化、主從複制、哨兵和 Cluster叢集

下面分别說明它們的作用,以及解決了什麼樣的問題。

持久化:持久化是最簡單的高可用方法(有時甚至不被歸為高可用的手段),主要作用是資料備份,即将資料存儲在硬碟,保證資料不會因程序退出而手失。

主從複制:主從複制是高可用Redis的基礎,哨兵和叢集都是在主從複制基礎上實作高可用的。主從複制主要實作了資料的多機備份,以及對于讀操作的負載均衡和簡單的故障恢複。缺陷;故障恢複無法自動化:可操作無法負裁均衡:存儲能力受到單機的限制。

哨兵:在主從複制的基礎上,哨兵實作了自動化的故障恢複。缺陷:寫操作無法負載均衡:存儲能力受到單機的限制。

Cluster叢集:通過叢集,Redis解決了寫操作無法負載均衡,以及存儲能力受到單機限制的問題,實作了較為完善的高可用方案。

主從複制是高可用Redis的基礎,哨兵和叢集都是在主從複制基礎上實作高可用的。

2、Redis的簡單架構

Redis主從複制原理及配置一、Redis高可用二、Redis持久化二、部署Redis主從複制總結

二、Redis持久化

持久化的功能:Redis是記憶體資料庫,資料都是存儲在記憶體中,為了避免伺服器斷電等原因導緻Redis程序異常退出後資料的永久丢失,需要定期将Redis中的資料以某種形式(資料或指令)從記憶體儲存到硬碟:當下次Redis重新開機時,利用持久化檔案實作資料恢複。除此之外,為了進行災難備份,可以将持久化檔案拷貝到一個遠端位置。

1、redis提供兩種方式進行持久化

(1)RDB持久化:原理是将Reids在記憶體中的資料庫記錄定時儲存在磁盤上

(2)AOF持久化:原理是将Reids的記錄檔以追加的方式寫入檔案,類似于MySQL的binlog

由于AOF持久化的實用性更好,即當程序意外退出時丢失的資料更少,是以AOF是目前主流的持久化方式,不過RDB持久化仍然有其用武之地

2、RDB持久化

RBD持久化是指在指定的時間間隔内将記憶體中目前程序中的資料生成快照儲存到硬碟(是以也稱為快照持久性),用二進制壓縮存儲,儲存的檔案字尾是rdb;當Redis重新啟動時,可以讀取快照檔案恢複資料。

(1)觸發條件

RDB持久化的觸發分為手動觸發和自動觸發兩種。

  1. 手動觸發

    save指令和bgsave指令都可以生成RDB檔案。

    save指令會阻塞Redis伺服器程序,直到RDB檔案建立完畢為止,在Redis伺服器阻塞期間,伺服器不能處理任何指令請求。

save

而bgsave指令會建立一個子程序,由子程序來負責建立RDB檔案,父程序(即Redis主程序)則繼續處理請求。

bgsave

bgsave指令執行過程中,隻有fork子程序時會阻塞伺服器,而對于save指令,整個過程都會阻塞伺服器,是以save已基本被廢棄,線上環境要杜絕save的使用;後文中也将隻介紹bgsave指令。此外,在自動觸發RDB持久化時,Redis也會選擇bgsave而不是save來進行持久化;下面介紹自動觸

2)自動觸發

save m n

自動觸發最常見的情況是在配置檔案中通過save m n,指定當m秒内發生n次變化時,會觸發bgsave。

(2)bgsave指令執行流程圖

Redis主從複制原理及配置一、Redis高可用二、Redis持久化二、部署Redis主從複制總結

圖檔中的5個步驟所進行的操作如下:

  1. Redis父程序首先判斷:目前是否在執行save,或bgsave/bgrewriteaof(後面會詳細介紹該指令)的子程序,如果在執行則bgsave指令直接傳回。bgsave/bgrewriteaof 的子程序不能同時執行,主要是基于性能方面的考慮:兩個并發的子程序同時執行大量的磁盤寫操作,可能引起嚴重的性能問題。
  2. 父程序執行fork操作建立子程序,這個過程中父程序是阻塞的,Redis不能執行來自用戶端的任何指令
  3. 父程序fork後,bgsave指令傳回”Background saving started”資訊并不再阻塞父程序,并可以響應其他指令(主程序又能繼續他的對外提供服務,二者互不影響。)
  4. 子程序建立RDB檔案,根據父程序記憶體快照生成臨時快照檔案,完成後對原有檔案進行原子替換
  5. 子程序發送信号給父程序表示完成,父程序更新統計資訊

    3、AOF持久化

    (1)開啟AOF

    Redis伺服器預設開啟RDB,關閉AOF;要開啟AOF,需要在配置檔案中配置:

appendonly yes
           

(2)執行流程

由于需要記錄Redis的每條寫指令,是以AOF不需要觸發,下面介紹AOF的執行流程。

AOF的執行流程包括:

指令追加(append):将Redis的寫指令追加到緩沖區aof_buf;

檔案寫入(write)和檔案同步(sync):根據不同的同步政策将aof_buf中的内容同步到硬碟;

檔案重寫(rewrite):定期重寫AOF檔案,達到壓縮的目的。

  1. 指令追加(append)

Redis先将寫指令追加到緩沖區,而不是直接寫入檔案,主要是為了避免每次有寫指令都直接寫入硬碟,導緻硬碟IO成為Redis負載的瓶頸。

指令追加的格式是Redis指令請求的協定格式,它是一種純文字格式,具有相容性好、可讀性強、容易處理、操作簡單避免二次開銷等優點;具體格式略。在AOF檔案中,除了用于指定資料庫的select指令(如select 0 為選中0号資料庫)是由Redis添加的,其他都是用戶端發送來的寫指令。

  1. 檔案寫入(write)和檔案同步(sync)

Redis提供了多種AOF緩存區的同步檔案政策,政策涉及到作業系統的write函數和fsync函數,說明如下:

為了提高檔案寫入效率,在現代作業系統中,當使用者調用write函數将資料寫入檔案時,作業系統通常會将資料暫存到一個記憶體緩沖區裡,當緩沖區被填滿或超過了指定時限後,才真正将緩沖區的資料寫入到硬碟裡。這樣的操作雖然提高了效率,但也帶來了安全問題:如果計算機停機,記憶體緩沖區中的資料會丢失;是以系統同時提供了fsync、fdatasync等同步函數,可以強制作業系統立刻将緩沖區中的資料寫入到硬碟裡,進而確定資料的安全性。

AOF緩存區的同步檔案政策由參數appendfsync控制,各個值的含義如下:

always:指令寫入aof_buf後立即調用系統fsync操作同步到AOF檔案,fsync完成後線程傳回。這種情況下,每次有寫指令都要同步到AOF檔案,硬碟IO成為性能瓶頸,Redis隻能支援大約幾百TPS寫入,嚴重降低了Redis的性能;即便是使用固态硬碟(SSD),每秒大約也隻能處理幾萬個指令,而且會大大降低SSD的壽命。

no:指令寫入aof_buf後調用系統write操作,不對AOF檔案做fsync同步;同步由作業系統負責,通常同步周期為30秒。這種情況下,檔案同步的時間不可控,且緩沖區中堆積的資料會很多,資料安全性無法保證。

everysec:指令寫入aof_buf後調用系統write操作,write完成後線程傳回;fsync同步檔案操作由專門的線程每秒調用一次。everysec是前述兩種政策的折中,是性能和資料安全性的平衡,是以是Redis的預設配置,也是我們推薦的配置。

  1. 檔案重寫(rewrite)

随着時間流逝,Redis伺服器執行的寫指令越來越多,AOF檔案也會越來越大;過大的AOF檔案不僅會影響伺服器的正常運作,也會導緻資料恢複需要的時間過長。

檔案重寫是指定期重寫AOF檔案,減小AOF檔案的體積。需要注意的是,AOF重寫是把Redis程序内的資料轉化為寫指令,同步到新的AOF檔案;不會對舊的AOF檔案進行任何讀取、寫入操作!

關于檔案重寫需要注意的另一點是:對于AOF持久化來說,檔案重寫雖然是強烈推薦的,但并不是必須的;即使沒有檔案重寫,資料也可以被持久化并在Redis啟動的時候導入;是以在一些實作中,會關閉自動的檔案重寫,然後通過定時任務在每天的某一時刻定時執行。

檔案重寫之是以能夠壓縮AOF檔案,原因在于:

過期的資料不再寫入檔案

無效的指令不再寫入檔案:如有些資料被重複設值(set mykey v1, set mykey v2)、有些資料被删除了(sadd myset v1, del myset)等等

多條指令可以合并為一個:如sadd myset v1, sadd myset v2, sadd myset v3可以合并為sadd myset v1 v2 v3。不過為了防止單條指令過大造成用戶端緩沖區溢出,對于list、set、hash、zset類型的key,并不一定隻使用一條指令;而是以某個常量為界将指令拆分為多條。這個常量在redis.h/REDIS_AOF_REWRITE_ITEMS_PER_CMD中定義,不可更改,3.0版本中值是64。

(3)AOF持久化流程圖

Redis主從複制原理及配置一、Redis高可用二、Redis持久化二、部署Redis主從複制總結

關于檔案重寫的流程,有兩點需要特别注意:

(1)重寫由父程序fork子程序進行;

(2)重寫期間Redis執行的寫指令,需要追加到新的AOF檔案中,為此Redis引入了aof_rewrite_buf緩存。

對照上圖,檔案重寫的流程如下:

  1. Redis父程序首先判斷目前是否存在正在執行 bgsave/bgrewriteaof的子程序,如果存在則bgrewriteaof指令直接傳回,如果存在bgsave指令則等bgsave執行完成後再執行。
  2. 父程序執行fork操作建立子程序,這個過程中父程序是阻塞的。

3.1) 父程序fork後,bgrewriteaof指令傳回”Background append only file rewrite started”資訊并不再阻塞父程序,并可以響應其他指令。Redis的所有寫指令依然寫入AOF緩沖區,并根據appendfsync政策同步到硬碟,保證原有AOF機制的正确。

3.2) 由于fork操作使用寫時複制技術,子程序隻能共享fork操作時的記憶體資料。由于父程序依然在響應指令,是以Redis使用AOF重寫緩沖區(圖中的aof_rewrite_buf)儲存這部分資料,防止新AOF檔案生成期間丢失這部分資料。也就是說,bgrewriteaof執行期間,Redis的寫指令同時追加到aof_buf和aof_rewirte_buf兩個緩沖區。

  1. 子程序根據記憶體快照,按照指令合并規則寫入到新的AOF檔案。

5.1) 子程序寫完新的AOF檔案後,向父程序發信号,父程序更新統計資訊,具體可以通過info persistence檢視。

5.2) 父程序把AOF重寫緩沖區的資料寫入到新的AOF檔案,這樣就保證了新AOF檔案所儲存的資料庫狀态和伺服器目前狀态一緻。

5.3) 使用新的AOF檔案替換老檔案,完成AOF重寫。

二、部署Redis主從複制

主機 系統 IP位址 安裝包

Master節點 CentOS 7 192.168.154.19 redis-5.0.7.tar. gz

Master節點 CentOS 7 192.168.154.20 redis-5.0.7.tar. gz

Master節點 CentOS 7 192.168.154.21 redis-5.0.7.tar. gz

2、三台主機都需要部署Redis、關閉防火牆、關閉增強功能

#三台主機都關閉防火牆和SELINUX
systemctl stop firewalld
systemctl disable firewalld
setenforce 0
           

3、修改Master節點配置檔案

(1)#修改master主配置檔案
vim /etc/redis/6379.conf
bind 0.0.0.0         			   #70行,注釋掉bind項,或修改為0.0.0.0,預設監聽所有網卡
daemonize yes         			   #137行,開啟守護程序
logfile /var/log/redis_6379.log    #172行,指定日志檔案目錄
dir /var/lib/redis/6379            #264行,指定工作目錄
appendonly yes       			   #700行,開啟AOF持久化功能
 
(2)#重新開機redis
/etc/init.d/redis_6379 restart


           
Redis主從複制原理及配置一、Redis高可用二、Redis持久化二、部署Redis主從複制總結
Redis主從複制原理及配置一、Redis高可用二、Redis持久化二、部署Redis主從複制總結
Redis主從複制原理及配置一、Redis高可用二、Redis持久化二、部署Redis主從複制總結

4.修改Slave1節點配置檔案

(1)#修改slave1節點配置檔案
vim /etc/redis/6379.conf
bind 0.0.0.0        				 #70行,修改監聽位址為0.0.0.0
daemonize yes       				 #137行,開啟守護程序
logfile /var/log/redis_6379.log      #172行,指定日志檔案目錄
dir /var/lib/redis/6379              #264行,指定工作目錄
replicaof 192.168.154.19 6379         #287行,取消注釋并指定要同步的Master節點IP和端口
appendonly yes       				 #700行,開啟AOF持久化功能
 
(2)#重新開機slave1節點和slave2節點redis服務
/etc/init.d/redis_6379 restart
           
Redis主從複制原理及配置一、Redis高可用二、Redis持久化二、部署Redis主從複制總結
Redis主從複制原理及配置一、Redis高可用二、Redis持久化二、部署Redis主從複制總結
Redis主從複制原理及配置一、Redis高可用二、Redis持久化二、部署Redis主從複制總結

重新開機slave1服務

Redis主從複制原理及配置一、Redis高可用二、Redis持久化二、部署Redis主從複制總結

5.修改Slave2節點配置檔案

(1)#修改slave2節點配置檔案,slave1和slave2修改步驟相同
vim /etc/redis/6379.conf
bind 0.0.0.0        				 #70行,修改監聽位址為0.0.0.0
daemonize yes       				 #137行,開啟守護程序
logfile /var/log/redis_6379.log      #172行,指定日志檔案目錄
dir /var/lib/redis/6379              #264行,指定工作目錄
replicaof 192.168.154.19 6379         #287行,取消注釋并指定要同步的Master節點IP和端口
appendonly yes       				 #700行,開啟AOF持久化功能
 
(2)#重新開機slave2節點redis服務
/etc/init.d/redis_6379 restart
           
Redis主從複制原理及配置一、Redis高可用二、Redis持久化二、部署Redis主從複制總結
Redis主從複制原理及配置一、Redis高可用二、Redis持久化二、部署Redis主從複制總結
Redis主從複制原理及配置一、Redis高可用二、Redis持久化二、部署Redis主從複制總結

重新開機slave2服務

Redis主從複制原理及配置一、Redis高可用二、Redis持久化二、部署Redis主從複制總結

6、驗證主從效果

#在Master節點上看日志:
tail -f /var/log/redis_6379.log
 
#在Master節點上驗證從節點:
redis-cli
127.0.0.1:6379> info replication
 
#建立資料驗證
##在master建立資料
set name yxp
 
##在從節點上檢視
get name
           

在Master節點上看日志

Redis主從複制原理及配置一、Redis高可用二、Redis持久化二、部署Redis主從複制總結

在Master節點上驗證從節點

Redis主從複制原理及配置一、Redis高可用二、Redis持久化二、部署Redis主從複制總結

建立資料驗證

Redis主從複制原理及配置一、Redis高可用二、Redis持久化二、部署Redis主從複制總結
Redis主從複制原理及配置一、Redis高可用二、Redis持久化二、部署Redis主從複制總結
Redis主從複制原理及配置一、Redis高可用二、Redis持久化二、部署Redis主從複制總結

總結

主從複制适用于資料的多機備份,以及對于讀操作的負載均衡和簡單的故障恢複。

哨兵模式基于主從複制,部署哨兵模式必須先部署主從複制,其在主從複制基礎上提供了自動化的故障恢複。但是其寫操作無法負載均衡,存儲能力受到單機的限制。

Redis叢集提供了分布式存儲方案解決了寫操作無法負載均衡,以及存儲能力受到單機限制的問題,實作了較為完善的高可用方案,其叢集最低需要6個節點,三主三從,實作Redis高可用