一、前述
持久化概念:將數據從掉電易失的內存存放到能夠永久存儲的設備上。
Redis持久化方式
RDB(Redis DB) hdfs: fsimage
AOF(AppendOnlyFile) hdfs : edit logs 默認關閉的
二、RDB方式
在默認情況下,Redis 將數據庫快照保存在名字為 dump.rdb的二進制文件中
在RDB方式下,有兩種方式,
1、一種是手動執行持久化數據命令來讓redis進行一次數據快照,而手動執行持久化命令,你依然有兩種選擇,那就是save命令和bgsave命令。
save:
客戶端手動執行SAVE命令
redis > save
阻塞Redis服務,無法響應客戶端請求
創建新的dump.rdb替代舊文件
bgsave:是一個異步命令
redis > bgsave
非阻塞,Redis服務正常接收處理客戶端請求
Redis會fork()一個新的子進程來創建RDB文件,子進程處理完后會向父進程發送一個信號,通知它處理完畢
父進程用新的dump.rdb替代舊文件
注意:
Fork發生時,父子進程內存共享,所以為了不影響子進程做數據快照,在這期間修改的數據,將會被復制一份,而不進共享內存。所以說,RDB所持久化的數據,是Fork發生時的數據。在這樣的條件下進行持久化數據,如果因為某些情況宕機,則會丟失一段時間的數據。如果你的實際情況對數據丟失沒那么敏感,丟失的也可以從傳統數據庫中獲取或者說丟失部分也無所謂,那么你可以選擇RDB持久化方式。
比較:
SAVE 和 BGSAVE 命令
SAVE不用創建新的進程,速度略快
BGSAVE需要創建子進程,消耗額外的內存
SAVE適合停機維護,服務低谷時段
BGSAVE適合線上執行
2、另一種則是根據你所配置的配置文件 的 策略,達到策略的某些條件時來自動持久化數據。和bgsave執行原理相同
這是配置文件默認的策略,他們之間的關系是或,每隔900秒,在這期間變化了至少一個鍵值,做快照。或者每三百秒,變化了十個鍵值做快照。或者每六十秒,變化了至少一萬個鍵值,做快照。
三、AOF方式
ppend only file,采用追加的方式保存
默認文件appendonly.aof
記錄所有的寫操作命令,在服務啟動的時候使用這些命令就可以還原數據庫
調整AOF持久化策略,可以在服務出現故障時,不丟失任何數據,也可以丟失一秒的數據。相對於RDB損失小得多
1、AOF寫入機制(但事實上,並不會立即將命令寫入到硬盤文件中,而是寫入到硬盤緩存,在接下來的策略中,配置多久來從硬盤緩存寫入到硬盤文件。所以在一定程度一定條件下,還是會有數據丟失,不過你可以大大減少數據損失。)
AOF方式不能保證絕對不丟失數據
目前常見的操作系統中,執行系統調用write函數,將一些內容寫入到某個文件里面時,為了提高效率,系統通常不會直接將內容寫入硬盤里面,而是先將內容放入一個內存緩沖區(buffer)里面,等到緩沖區被填滿,或者用戶執行fsync調用和fdatasync調用時才將儲存在緩沖區里的內容真正的寫入到硬盤里,未寫入磁盤之前,數據可能會丟失
2、寫入磁盤的策略(這里是配置AOF持久化的策略。redis默認使用everysec,就是說每秒持久化一次,而always則是每次操作都會立即寫入aof文件中。而no則是不主動進行同步操作,是默認30s一次。當然always一定是效率最低的,everysec就夠用了,數據安全性能又高。)
appendfsync選項,這個選項的值可以是always、everysec或者no
Always:服務器每寫入一個命令,就調用一次fdatasync,將緩沖區里面的命令寫入到硬盤。這種模式下,服務器出現故障,也不會丟失任何已經成功執行的命令數據
Everysec(默認):服務器每一秒重調用一次fdatasync,將緩沖區里面的命令寫入到硬盤。這種模式下,服務器出現故障,最多只丟失一秒鍾內的執行的命令數據
No:服務器不主動調用fdatasync,由操作系統決定何時將緩沖區里面的命令寫入到硬盤。這種模式下,服務器遭遇意外停機時,丟失命令的數量是不確定的
運行速度:always的速度慢,everysec和no都很快
3、AOF重寫機制
AOF有序的記錄了redis的命令操作。意外情況下數據丟失甚少。他不斷地對aof文件添加操作日志記錄,你可能會說,這樣的文件得多么龐大呀。是的,的確會變得龐大,但redis會有優化的策略,比如你對一個key1鍵的操作,set key1 001 , set key1 002, set key1 003。那優化的結果就是將前兩條去掉咯,那具體優化的配置在配置文件中對應的是
前者是指超過上一次aof重寫aof文件大小的百分之多少,會再次優化,如果沒有重寫過,則以啟動時為主。后者是限制了允許重寫的最小aof文件大小。bgrewriteaof命令是手動重寫命令,會fork子進程,在臨時文件中重建數據庫狀態,對原aof無任何影響,當重建舊的狀態后,也會把fork發生后的一段時間內的數據一並追加到臨時文件,最后替換原有aof文件,新的命令繼續向新的aof文件中追加。
AOF文件過大
合並重復的操作,AOF會使用盡可能少的命令來記錄
重寫過程
fork一個子進程負責重寫AOF文件
子進程會創建一個臨時文件寫入AOF信息
父進程會開辟一個內存緩沖區接收新的寫命令
子進程重寫完成后,父進程會獲得一個信號,將父進程接收到的新的寫操作由子進程寫入到臨時文件中
新文件替代舊文件
注:如果寫入操作的時候出現故障導致命令寫半截,可以使用redis-check-aof工具修復
AOF重寫觸發
手動:客戶端向服務器發送BGREWRITEAOF命令
自動:配置文件中的選項,自動執行BGREWRITEAOF命令
auto-aof-rewrite-min-size <size>,觸發AOF重寫所需的最小體積:只要在AOF文件的體積大於等於size時,才會考慮是否需要進行AOF重寫,這個選項用於避免對體積過小的AOF文件進行重寫
auto-aof-rewrite-percentage <percent>,指定觸發重寫所需的AOF文件體積百分比:當AOF文件的體積大於auto-aof-rewrite-min-size指定的體積,並且超過上一次重寫之后的AOF文件體積的percent %時,就會觸發AOF重寫。(如果服務器剛剛啟動不久,還沒有進行過AOF重寫,那么使用服務器啟動時載入的AOF文件的體積來作為基准值)。將這個值設置為0表示關閉自動AOF重寫
AOF重寫配置項舉例
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
appendonly no / yes
當AOF文件大於64MB時候,可以考慮重寫AOF文件
只有當AOF文件的增量大於起始size的100%時(就是文件大小翻了一倍),啟動重寫
默認關閉,請開啟
四、Rdb和AOF比較
1、RDB:
優點:
完全備份,不同時間的數據集備份可以做到多版本恢復
緊湊的單一文件,方便網絡傳輸,適合災難恢復
恢復大數據集速度較AOF快
缺點:
會丟失最近寫入、修改的而未能持久化的數據
fork過程非常耗時,會造成毫秒級不能響應客戶端請求
2、AOF
優點
寫入機制,默認fysnc每秒執行,性能很好不阻塞服務,最多丟失一秒的數據
重寫機制,優化AOF文件
如果誤操作了(FLUSHALL等),只要AOF未被重寫,停止服務移除AOF文件尾部FLUSHALL命令,重啟Redis,可以將數據集恢復到 FLUSHALL 執行之前的狀態
缺點
相同數據集,AOF文件體積較RDB大了很多
恢復數據庫速度較RDB慢(文本,命令重演)