Redis数据持久化之AOF持久化
一、RDB持久化的缺點
創(chuàng)建RDB文件需要將服務(wù)器所有的數(shù)據(jù)庫的數(shù)據(jù)都保存起來,這是一個非常耗費(fèi)資源和時間的操作,所以服務(wù)器需要隔一段時間才能創(chuàng)建一個新的RDB文件,就也是說創(chuàng)建RDB文件的操作不能執(zhí)行的過于頻繁,否則就會嚴(yán)重地影響服務(wù)器的性能。
在 save 配置選項的默認(rèn)設(shè)置下,即使有超過 10000 次修改操作發(fā)生,服務(wù)器也至少會間隔一分鐘才創(chuàng)建下一個 RDB 文件:
save 900 1 save 300 10 save 60 10000如果在等待創(chuàng)建下一個 RDB 文件的過程中,服務(wù)器遭遇了意外停機(jī),那么用戶將丟失最后一次創(chuàng)建RDB 文件之后,數(shù)據(jù)庫發(fā)生的所有修改。
解決方法:
為了解決 RDB 持久化在遭遇意外停機(jī)時丟失大量數(shù)據(jù)的問題,Redis 提供了 AOF 持久化功能。比起 RDB 持久化, AOF 持久化有一個巨大的優(yōu)勢,那就是,用戶可以根據(jù)自己的需要對 AOF 持久化進(jìn)行調(diào)整,讓 Redis 在遭遇意外停機(jī)時不丟失任何數(shù)據(jù),或者只丟失一秒鐘數(shù)據(jù),這比 RDB 持久化遭遇意外停機(jī)時,丟失的數(shù)據(jù)要少得多。
?
二、AOF 持久化的運(yùn)作原理
數(shù)據(jù)保存
AOF 持久化保存數(shù)據(jù)庫數(shù)據(jù)的方法是:每當(dāng)有修改數(shù)據(jù)庫的命令被執(zhí)行時,服務(wù)器就會將被執(zhí)行的命令寫入到 AOF 文件的末尾。
數(shù)據(jù)還原
因為 AOF 文件里面儲存了服務(wù)器執(zhí)行過的所有數(shù)據(jù)庫修改命令,所以給定一個 AOF 文件,服務(wù)器只要重新執(zhí)行一遍 AOF 文件里面包含的所有命令,就可以達(dá)到還原數(shù)據(jù)庫數(shù)據(jù)的目的。
舉個例子,對于包含以下內(nèi)容的 AOF 文件來說:
服務(wù)器只要重新執(zhí)行這些命令,就可以還原出右圖所示的數(shù)據(jù)庫
安全性問題
雖然服務(wù)器每執(zhí)行一個修改數(shù)據(jù)庫的命令,就會將被執(zhí)行的命令寫入到 AOF 文件,但這并不意味著AOF 持久化不會丟失任何數(shù)據(jù)。
在目前常見的操作系統(tǒng)中,執(zhí)行系統(tǒng)調(diào)用 write 函數(shù),將一些內(nèi)容寫入到某個文件里面時,為了提高效率,系統(tǒng)通常不會直接將內(nèi)容寫入到硬盤里面,而是先將內(nèi)容放入到一個內(nèi)存緩沖區(qū)(buffer)里面,等到緩沖區(qū)被填滿,或者用戶執(zhí)行 fsync 調(diào)用和 fdatasync 調(diào)用時,才將儲存在緩沖區(qū)里面的內(nèi)容真正地寫入到硬盤里面。
對于 AOF 持久化來說,當(dāng)一條命令真正地被寫入到硬盤里面時,這條命令才不會因為停機(jī)而意外丟失。
因此,AOF 持久化在遭遇停機(jī)時丟失命令的數(shù)量,取決于命令被寫入到硬盤的時間:
1) 越早將命令寫入到硬盤,發(fā)生意外停機(jī)時丟失的數(shù)據(jù)就越少;
2) 越遲將命令寫入到硬盤,發(fā)生意外停機(jī)時丟失的數(shù)據(jù)就越多。
?
安全性控制
為了控制 Redis 服務(wù)器在遇到意外停機(jī)時丟失的數(shù)據(jù)量,Redis 為 AOF 持久化提供了 appendfsync選項,這個選項的值可以是 always 、 everysec 或者 no ,這些值的意思分別為:
always :服務(wù)器每寫入一個命令,就調(diào)用一次 fdatasync ,將緩沖區(qū)里面的命令寫入到硬盤里面。在這種模式下,服務(wù)器即使遭遇意外停機(jī),也不會丟失任何已經(jīng)成功執(zhí)行的命令數(shù)據(jù)。
everysec :服務(wù)器每秒鐘調(diào)用一次 fdatasync ,將緩沖區(qū)里面的命令寫入到硬盤里面。在這種模式下,服務(wù)器遭遇意外停機(jī)時,最多只丟失一秒鐘內(nèi)執(zhí)行的命令數(shù)據(jù)。
no :服務(wù)器不主動調(diào)用 fdatasync ,由操作系統(tǒng)決定何時將緩沖區(qū)里面的命令寫入到硬盤里面。在這種模式下,服務(wù)器遭遇意外停機(jī)時,丟失命令的數(shù)量是不確定的。
運(yùn)行速度: always 的速度慢, everysec 和 no 都很快。默認(rèn)值: everysec 。
?
三、AOF 重寫
隨著服務(wù)器的不斷運(yùn)行,為了記錄數(shù)據(jù)庫發(fā)生的變化,服務(wù)器會將越來越多的命令寫入到 AOF 文件里面,使得 AOF 文件的體積不斷地增大。為了讓 AOF 文件的大小控制在合理的范圍,避免它胡亂地增長,Redis 提供了 AOF 重寫功能,通過這個功能,服務(wù)器可以產(chǎn)生一個新的 AOF 文件:
1) 新 AOF 文件記錄的數(shù)據(jù)庫數(shù)據(jù)和原有 AOF 文件記錄的數(shù)據(jù)庫數(shù)據(jù)完全一樣;
2) 新的 AOF 文件會使用盡可能少的命令來記錄數(shù)據(jù)庫數(shù)據(jù),因此新 AOF 文件的體積通常會比原有 AOF 文件的體積要小得多。
3) AOF 重寫期間,服務(wù)器不會被阻塞,可以正常處理客戶端發(fā)送的命令請求。
AOF 重寫的觸發(fā)
有兩種方法可以觸發(fā) AOF 重寫:
1) 客戶端向服務(wù)器發(fā)送 BGREWRITEAOF 命令;
2) 通過設(shè)置配置選項來讓服務(wù)器自動執(zhí)行 BGREWRITEAOF 命令,它們分別是:
auto-aof-rewrite-min-size <size> ,觸發(fā) AOF 重寫所需的最小體積:只有在 AOF 文件的體積
大于等于 size 時,服務(wù)器才會考慮是否需要進(jìn)行 AOF 重寫。這個選項用于避免對體積過小的AOF 文件進(jìn)行重寫。
auto-aof-rewrite-percentage <percent> ,指定觸發(fā)重寫所需的 AOF 文件體積百分比:當(dāng) AOF
文件的體積大于 auto-aof-rewrite-min-size 指定的體積,并且超過上一次重寫之后的 AOF 文件體積的 percent% 時,就會觸發(fā) AOF 重寫。(如果服務(wù)器剛剛啟動不久,還沒有進(jìn)行過 AOF 重寫,那么使用服務(wù)器啟動時載入的 AOF 文件的體積來作為基準(zhǔn)值。)將這個值設(shè)置為 0 表示關(guān)閉自動 AOF 重寫。
例子:
?
四、AOF持久化小結(jié)
創(chuàng)建 RDB 文件需要將服務(wù)器包含的所有數(shù)據(jù)全部寫入到硬盤里面,這是一個非常耗費(fèi)資源和時間的操作,因此服務(wù)器通常需要每隔一段時間才創(chuàng)建一個新的 RDB 文件,這使得服務(wù)器在遭遇意外停機(jī)時,可能會丟失大量數(shù)據(jù);
AOF 持久化會將每個修改了數(shù)據(jù)庫的命令都寫入到 AOF 文件末尾,在啟動服務(wù)器的時候,只要重新執(zhí)行 AOF 文件包含的命令,就可以還原服務(wù)器原有的數(shù)據(jù)庫數(shù)據(jù);
因為寫入緩沖區(qū)的存在,AOF 持久化的安全性取決于緩沖區(qū)里面的命令何時會被真正地寫入到硬盤里面,通過設(shè)置 appendfsync 配置選項,用戶可以讓 AOF 持久化不丟失任何已經(jīng)成功執(zhí)行的命令數(shù)據(jù),或者只丟失一秒鐘內(nèi)被執(zhí)行的命令數(shù)據(jù),又或者不主動執(zhí)行 fdatasync 調(diào)用,將寫入硬盤的時機(jī)交給操作系統(tǒng)來管理;
隨著服務(wù)器的運(yùn)行,AOF 文件會產(chǎn)生越來越多冗余命令,使得文件的體積不斷增大,而通過執(zhí)行 AOF重寫操作,服務(wù)器可以創(chuàng)建一個保存相同數(shù)據(jù)庫數(shù)據(jù),但不包含任何冗余命令的新 AOF 文件,并使用這個新 AOF 文件來代替原有的 AOF 文件。
?
五、RDB和AOF對比
可以同時使用兩種持久化,根據(jù)你的需求來判斷。還原數(shù)據(jù)優(yōu)先使用 AOF 文件。
總結(jié)
以上是生活随笔為你收集整理的Redis数据持久化之AOF持久化的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: keepalived基础及使用DR模型构
- 下一篇: nginx限速