1. 程式人生 > >Redis(一)持久化:快照和AOF

Redis(一)持久化:快照和AOF

一、持久化

Redis持久化提供兩種方式:快照和AOF。

1.快照(snapshotting)

將Redis記憶體中的資料在同一時刻(可以配置,比如300秒內有10個key發生了變化)的副本寫到磁碟
save 900 1 #900秒 1個修改
save 300 10 #300秒 10個更新
save 60 10000 #60秒 10000個更新

Redis觸發快照有5種方式:

A.客戶端執行BGSAVE命令,Redis fork一個子程序來將快照寫到磁碟,如果Redis記憶體儲存幾十G資料時可能需要暫停幾ms到幾百ms不等(視伺服器硬體而定)來fork子程序,在子程序進行BGSAVE操作時,Redis主程序照樣可以處理客戶端的命令,BGSAVE不會停住阻塞Redis程序。

如看下面
Redis主程序
2251 www       20   0  130m 7920 1484 S  0.0  0.8   0:00.63 redis-server
Redis的日誌:
2251:M 23 Dec 18:54:05.021 * 10 changes in 300 seconds. Saving...
2251:M 23 Dec 18:54:05.048 * Background saving started by pid 2286
2286:C 23 Dec 18:54:05.082 * DB saved on disk
2286:C 23 Dec 18:54:05.083 * RDB: 6 MB of memory used by copy-on-write
2251:M 23 Dec 18:54:05.149 * Background saving terminated with success
可以看出,從上次快照完成到現在的300秒內有10個key發生變化,Redis主程序fork子程序2286進行BGSAVE的快照操作。

B.客戶端執行SAVE命令,Redis會停住客戶端的所有請求命令,直到快照完成。

C.當我們配置了save配置行,只要其中一個save配置行條件滿足,則會啟動快照操作,快照操作是BGSAVE模式的,所以Redis不會停下來,而會繼續處理客戶的請求。

D.Redis接收到SHUTDOWN命令時,它啟動SAVE模式的快照操作,所有客戶的命令請求會被停住阻塞,快照完成後關閉Redis。
如:
客戶端
127.0.0.1:6379> shutdown
not connected>
Redis服務端
2901:M 23 Dec 04:06:13.609 # User requested shutdown...
2901:M 23 Dec 04:06:13.609 * Saving the final RDB snapshot before exiting.
2901:M 23 Dec 04:06:13.613 * DB saved on disk

2901:M 23 Dec 04:06:13.613 # Redis is now ready to exit, bye bye...

E.從節點Redis(slave)連線上主節點(master)併發送SYNC命令(請求master同步資料命令)複製資料,master會啟動BGSAVE模式的快照操作。

2.AOF(append-only file,追加檔案)

每次執行寫命令時都將寫命令寫到磁碟
可以通過配置
appendonly yes|no
設定yes從而開戶AOF持久化的特性。
當然了,寫命令不會直接寫到磁碟,寫命令會首先寫到緩衝區,到了觸發點時才能將緩衝區的寫操作命令寫到AOF檔案結尾
觸發AOF持久化的頻率可以通過下面三種之一來配置
appendfsync always #每次執行寫命令,也將寫到AOF檔案,這使得Redis效能低下,轉盤式磁碟200次/秒寫操作,固態磁碟幾萬次/秒操作
appendfsync everysec    #每秒同步一次寫操作到AOF檔案,這樣可以使得即使Redis崩潰了,Redis的丟失資料也是在1秒之內或者無丟失。
appendfsync no     #讓作業系統決定何時將寫操作同步到AOF檔案,這個配置選項,
                                  #由於 我們無法控制何時將緩衝區的寫命令同步到AOF檔案,可能導致緩衝區溢滿導致寫操作無法執行,造成Redis阻塞。
隨著寫命令的不斷累加,會導致AOF不斷地增大,Redis提供後臺重寫AOF(BGREWRITEAOF),BGREWRITEAOF類似快照持久化的BGSAVE,也會fork一個子程序對AOF檔案進行重寫,重寫完AOF檔案後,需要刪除舊的AOFT檔案,這時Redis主程序會被阻塞,直到舊的AOF被刪除才能使用新重寫的AOF檔案,如果舊的AOF過大的話可能會造成Redis數秒的阻塞時長。
BGREWRITEAOF這個特性可能通過下面配置
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
當AOF檔案比上次重寫後的AOF檔案增大了100%並且AOF檔案大於64mb時會觸發AOF的後臺重寫操作BGREWRITEAOF。

介紹下下面配置
no-appendfsync-on-rewrite yes|no #預設情況下設定為no
當AOF進行BGREWRITEAOF操作,Redis的主程序不會進行AOF持久化(是指設定為yes的情況下),這樣在重寫AOF期間Redis崩潰了,會造成這段時間寫操作的資料丟失,所以謹慎使用。