redis數據複製,可用性怎麼做的?

redis數據複製,可用性怎麼做的?

複製的基本原理(全量同步)

1.slave啟動時會向master發送sync命令。

2.主數據庫接收到sync請求後在後臺保存快照,也就是實現RDB持久化,並將保存快照期間接收到的命令緩存起來

3.快照完成後主數據庫會將快照文件和所有緩存的命令發送給從數據庫

4.從數據庫接收後會載入快照文件並執行緩存的命令, 從而完成複製

5.在數據庫使用階段主數據庫會自動把每次收到的寫命令同步到從服務器

增量同步

redis增量複製是指slave初始化後開始工作時主服務器發生的寫操作同步到從服務器的過程。增量複製的過程主要是主服務器每執行一個寫命令就會向從服務器發送相同的寫命令,從服務器接收並執行收到的寫命令。

主從剛剛連接時,進行全量同步;全量同步結束後,進行增量同步,如果有需要,slave在任何時候都可以發起全量同步。redis策略是無論如何首先會嘗試進行增量同步,如不成功,要求從機進行全量同步。

redis服務器崩潰時數據恢復

1)RDB方式

RDB方式的持久化時通過快照(snapshot)完成的,當符合一定條件時redis會自動將內存中的所有數據進行快照並存儲到硬盤上。快照條件在配置文件裡配置,由時間和改動的鍵的個數構成。

save 900 1

redis使用fork函數複製一份當前進程的副本;父進程繼續接受並處理客戶端命令,子進程開始將內存中的數據寫入硬盤中的臨時文件;子進程寫完所有數據後該臨時文件替換舊的RDB文件,快照完成;當執行fork時,操作系統會使用寫時複製策略,即fork函數發生一刻父子進程共享同一內存數據,當父進程更改其中某個數據時,操作系統會將該數據複製一份以保障子進程數據不受影響,所以新的RDB文件存儲的是執行fork一刻的內存數據。

除了自動快照,可以手動發送save或bgsave命令讓redis執行快照。前者是由主進程進行快照,會阻塞其他請求,後者通過fork子進程進行快照操作。

一旦redis異常退出,就會丟失最後一次快照以後更改的所有數據。設置合理的快照發生時間,將數據損失控制在能夠接受的範圍。如果數據很重要無法承擔任何損失,可以使用AOF持久化。

2)AOF方式

默認情況下redis沒開啟AOF方式持久化,可通過redis.cnf開啟appendonly yes開啟。在啟動redis的時候,會逐個執行AOF中的命令將數據載入到內存。載入速度比RDB慢一些。

開啟AOF後每執行一條會更改redis數據的命令,都會將該命令寫入硬盤的AOF文件,AOF文件保存位置和RDB文件位置相同,都是通過dir參數設置。默認appendonly.aof

aof方式追加log文件可能導致體積過大,系統重啟時aof的方式則加載數據會非常慢。另外每條命令都要寫log,reids的讀寫性能也會有所下降。

redis允許同時開啟AOF和RDB,即保證數據安全又使得備份操作容易。重啟redis後redis會使用AOF文件來恢復數據,AOF方式持久化可能丟失的數據更少。

斷點續傳

從redis 2.8開始,就支持主從複製的斷點續傳,如果主從複製過程中,網絡連接斷掉了,那麼可以接著上次複製的地方,繼續複製下去,而不是從頭開始複製一份

master node會在內存中創建一個backlog,master和slave都會保存一個replica offset還有一個master id,offset就是保存在backlog中的。如果master和slave網絡連接斷掉了,slave會讓master從上次的replica offset開始繼續複製

但是如果沒有找到對應的offset,那麼就會執行一次resynchronization

無磁盤化複製

master在內存中直接創建rdb,然後發送給slave,不會在自己本地落地磁盤了

repl-diskless-sync

repl-diskless-sync-delay,等待一定時長再開始複製,因為要等更多slave重新連接過來

過期key處理

slave不會過期key,只會等待master過期key。如果master過期了一個key,或者通過LRU淘汰了一個key,那麼會模擬一條del命令發送給slave。

異步複製

master每次接收到寫命令之後,先在內部寫入數據,然後異步發送給slave node


分享到:


相關文章: