Redis系列(四):Redis持久化和主從復制原理


一、持久化

  所謂的持久化就是把內存中的數據寫到磁盤中去,防止服務宕機后內存數據丟失。Redis4.0之前提供了兩種持久化方式:RDB(默認) 和AOF,Redis4.x之后新增了一種混合持久化(本文所用的Redis版本是redis‐5.0.2

  1、RDB

  RDB是Redis Database縮寫,在默認情況下,Redis將內存數據庫快照保存在名字為dump.rdb的二進制文件中。可以對Redis進行設置,讓它在 N秒內至少有M個鍵值改動這一條件被滿足時,自動保存一次數據。比如下圖,900秒內有1個鍵值或者300秒內有10個鍵值或者60秒內有10000個鍵值改動,自動保存一次數據;關閉RDB只需要將所有的save保存策略注釋掉即可。

   還可以手動執行命令生成RDB快照,進入Redis客戶端執行命令save或bgsave可以生成dump.rdb文件,每次命令執行都會將所有Redis內存快照到一個新的rdb文件里,並覆蓋原有rdb快照文件。save是同步命令,bgsave是異步命令,bgsave會從redis主進程fork(fork()是linux函數)出一個子進程專門用來生成rdb快照文件。Redis配置自動生成rdb文件后台使用的是bgsave方式。

save與bgsave對比
命令 save bgsave
IO類型 同步 異步
是否阻塞redis其它命令 否(在生成子進程執行調用fork函數時會短暫阻塞)
復雜度 O(n) O(n)
優點 不會消耗額外內存 不阻塞客戶端命令
缺點 阻塞客戶端命令 需要fork子進程,消耗內存

   2、AOF

  AOF是append-only file縮寫,RDB快照並不是非常耐久(durable):如果Redis因為某些原因而造成故障停機,那么服務器將丟失最近寫入、且仍未保存到快照中的那些數據。從Redis1.1版本開始,Redis增加了一種完全耐久的持久化方式:AOF持久化。可以通過修改如下配置文件來打開AOF功能:

   修改了配置文件,先執行bin/redis-cli shutdown停止Redis,然后執行bin/redis-server redis.conf啟動Redis,此時appendonly生效;從現在開始, 每當Redis執行一個改變鍵值的命令時(比如 SET),這個命令就會被追加到AOF文件的末尾。這樣的話,當 Redis重新啟動時,程序就可以通過重新執行AOF文件中的命令來達到重建數據的目的。你可以配置 Redis 多久才將數據 fsync到磁盤一次。

  ① appendfsync always:每次有新命令追加到AOF文件時就執行一次fsync,非常慢,也非常安全。

  ② appendfsync everysec:每秒fsync一次,足夠快(和使用 RDB 持久化差不多),並且在故障時只會丟失 1 秒鍾的數據。

  ③ appendfsync no:從不 fsync,將數據交給操作系統來處理。更快,也更不安全的選擇。

  推薦(並且也是默認)的措施為每秒fsync一次,這種fsync策略可以兼顧速度和安全性。配置文件如下:

  執行如下命令:

  (1)啟動客戶端,連接Redis bin/redis-cli 並執行set toby xu

   (2) 到dir(redis.conf這個配置文件里面的數據持久化的目錄屬性)所在的目錄下查看,如下圖:

   (3)vim appendonly.aof,文件的內容在后面的RESP(Redis序列化協議)中詳解講解,Redis序列化協議官網地址:https://redis.io/topics/protocol

   AOF重寫:

  (1)AOF文件里可能有太多沒用指令,所以AOF會定期根據內存的最新數據生成新的aof文件,當然可以手工執行bgrewriteaof命令也能重寫AOF,比如執行如下命令:

   (2)重寫后AOF文件里變成:

   如下兩個配置可以控制AOF自動重寫頻率:

  ① auto-aof-rewrite-min-size 64mb :aof文件至少要達到64M才會自動重寫。

  ② auto-aof-rewrite-percentage 100 :aof文件自上一次重寫后文件大小增長了100%則再次觸發重寫。

  當然AOF還可以手動重寫,進入redis客戶端執行如上圖命令bgrewriteaof重寫AOF注意,AOF重寫Redis會fork出一個子進程去做,不會對Redis正常命令處理有太多影響。

  3、RDB和AOF對比

  Redis啟動時如果既有RDB文件又有AOF文件則優先選擇AOF文件恢復數據,因為AOF一般來說數據更全一點。

持久化方式 RDB AOF
啟動優先級
文件大小
恢復速度
數據安全性 容易丟數據 根據策略決定

   4、Redis4.0混合持久化

  重啟Redis時,我們很少使用 RDB來恢復內存狀態,因為會丟失大量數據。我們通常使用AOF日志重放,但是重放AOF日志性能相對RDB來說要慢很多,這樣在 Redis 實例很大的情況下,啟動需要花費很長的時間。 Redis4.0為了解決這個問題,帶來了一個新的持久化選項——混合持久化。配置如下:

   如果開啟了混合持久化,AOF在重寫時,不再是單純將內存數據轉換為RESP命令寫入AOF文件,而是將重寫這一刻之前的內存做RDB快照處理,並且將RDB快照內容和增量的AOF修改內存數據的命令存在一起,都寫入新的AOF文件,新的文件一開始不叫appendonly.aof,等到重寫完新的AOF文件才會進行改名,原子的覆蓋原有的AOF文件,完成新舊兩個AOF文件的替換。於是在Redis重啟的時候,可以先加載RDB的內容,然后再重放增量AOF文件就可以完全替代之前的AOF全量文件重放,因此重啟效率大幅得到提升。

 二、Redis主從

   1、主從復制概念

  主從復制,是指將一台Redis服務器的數據,復制到其他的Redis服務器。前者稱為主節點(master),后者稱為從節點(slave),數據的復制是單向的,只能由主節點到從節點。

   2、主從復制的原理

  (1)全量復制

  將主節點中的所有數據都發送給從節點,是一個非常重型的操作,當數據量較大時,會對主從節點和網絡造成很大的開銷。全量復制流程圖如下:

  ① slave會發出一個同步命令,剛開始是Psync命令,表示要求master主機同步數據

  ② master收到psync命令后,會通過執行bgsave生成最新的RDB快照文件,持久化期間,master會繼續接收客戶端的請求,它會把寫請求緩存在內存中

  ③ 發送RDB文件給slave

  ④ master再將之前緩存在內存中的命令發送給slave

  ⑤ 刷新舊的數據。slave在載入主節點的數據之前要先將老數據清除

  ⑥ 加載RDB文件將數據庫狀態更新至主節點執行bgsave時的數據庫狀態和緩沖區數據的加載

  ⑦ master同步長連接持續把寫命令發送給slave,以保證數據的一致

  (2)部分復制

  部分復制是Redis 2.8以后出現的,用於處理在主從復制中因網絡閃斷等原因造成的數據丟失場景,當slave再次連上master后,如果條件允許,master會補發丟失數據給slave。因為補發的數據遠遠小於全量數據,可以有效避免全量復制的過高開銷。部分復制流程圖如下:

  ① 如果網絡抖動(連接斷開 connection lost)

  ② master還是會寫repl_back_buffer(復制緩沖區)

  ③ slave會繼續嘗試連接主機

  ④ slave會把自己當前run_id和偏移量傳輸給master,並且執行pysnc命令同步

  ⑤ slave發送過來的offset在repl_back_buffer中,則master會將緩存中從offset以后的數據一次性同步給slave,否則全量復制

  ⑥ master同步長連接持續把寫命令發送給slave,以保證數據的一致

  3、主從搭建

   其中slave的主要配置如下:

port 6380
pidfile /var/run/redis_6380.pid
dir /usr/local/redis-5.0.2/6380
replicaof 192.168.160.146 6379
replica-serve-stale-data yes
replica-read-only yes

  (1)在6379 set toby xu 

   (2)在6380 keys *

   至此Redis主從搭建完成!!!!!


免責聲明!

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



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