【Redis篇】Redis持久化方式AOF和RDB

LHBlog發表於2018-02-23

一、前述

持久化概念:將資料從掉電易失的記憶體放到能夠永久儲存的裝置上。

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慢(文字,命令重演)

相關文章