1. 程式人生 > >Redis系列(四):Redis持久化和主從複製原理

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主從搭建完成!!!!!