同樣是持久化,竟然有這么大的差別!
本文轉(zhuǎn)載自微信公眾號「IT界農(nóng)民工」,可以通過以下二維碼關(guān)注。轉(zhuǎn)載本文請聯(lián)系IT界農(nóng)民工公眾號。
作為內(nèi)存數(shù)據(jù)庫,Redis 在數(shù)據(jù)存儲與讀取上的速度是毫不遜色的,這點毋庸置疑。但是對于內(nèi)存來說,斷電或遇到故障后數(shù)據(jù)就會丟失,這卻是一個無法回避的問題。令人欣慰的是,基于這樣的缺點,Redis 也提供了不同的持久化方案。
各位看官請隨小萊接著往下看:
- 思維導圖 -
RDB持久化
對于 Redis 持久化來說,其實就是將存儲在內(nèi)存中的數(shù)據(jù)寫入到磁盤里,只不過寫入的方式是有一定策略的。
那么我們先來看下第一種持久化,首先出場的是 RDB。
1、什么是RDB持久化
英文名稱是 Redis DataBase,它還有一個常用的名字:快照持久化。所謂快照,在這里指的是某一時刻的內(nèi)存數(shù)據(jù),而持久化則是將這一時刻的數(shù)據(jù)以二進制形式寫入到磁盤里。
2、手動觸發(fā)機制
(1)save 命令
你可能會問了,那我通過什么樣的方式來實現(xiàn)持久化呢?不知道你有沒有用過 save 這個命令,在 Redis 里擔任的角色是用來手動觸發(fā)持久化的。也就是說在 Redis 客戶端操作 save 命令就可以將內(nèi)存數(shù)據(jù)寫入到磁盤里。
不過你可千萬不要好奇,生產(chǎn)環(huán)境要是這么玩兒的話,數(shù)據(jù)量少還行,數(shù)量大的話那估計八成得涼涼。為什么這么說呢?你稍微了解下它的運行原理就知道了。
前面的文章中,我們提到了 Redis 處理命令的方式是以單線程形式來進行的??蛻舳说恼埱蠖紩湃胍粋€隊列里。當執(zhí)行 save 命令時,如果執(zhí)行時間很長的話,后面的請求就會被阻塞,客戶端發(fā)送的所有命令都會被拒絕。
這種方式生產(chǎn)場景要慎用!
(2)bgsave 命令
還有一個 bgsave 命令。與 save 不同的是,執(zhí)行過程中它并不會阻塞客戶端的請求。而是將持久化工作交給子進程來執(zhí)行,主進程仍負責客戶端請求的處理工作。
3、自動觸發(fā)機制
RDB 持久化既可以通過手動觸發(fā),也可以通過服務(wù)器配置項來定期執(zhí)行。
自動觸發(fā)通常是 Redis 中配置文件來執(zhí)行的。有這么個配置你需要了解下:
save m n
其中 m 代表秒數(shù),n 代表次數(shù),放在一起表示的是 m 秒內(nèi)發(fā)生 n 次變化時,會觸發(fā) bgsave。
了解了自動化配置,我們再來看下 Redis 配置文件 redis.conf 中的三個默認配置項:
save 900 1 表示的是時間900秒內(nèi),如果 Redis 中數(shù)據(jù)至少發(fā)生一次變化,就會執(zhí)行 bgsave。后邊兩個就不用介紹了,一樣的原理。
看到這三個配置項,不知道你會不會有疑問,這三個到底該執(zhí)行哪一個?答案是設(shè)置多個 save m n 命令時,滿足任何一個條件都會觸發(fā)持久化。
4、RDB 文件恢復
前面我們提到過了,持久化的目的就是為了解決內(nèi)存異常導致的數(shù)據(jù)丟失問題。那么倘若如果真遇到了這樣的情況,RDB 文件如何來實現(xiàn)數(shù)據(jù)恢復呢?
開啟自動持久化后,數(shù)據(jù)會存儲到名為 dump.rdb 的文件中。當 Redis 服務(wù)器重啟時,檢測到 dump.rdb 文件后,會自動加載進行數(shù)據(jù)恢復。
AOF持久化
介紹完了 RDB 后,我們再來看一種叫作 AOF 的持久化方式。
1、什么是AOF持久化
英文名稱是 Append Only File。同樣地,它也有一個常用的名字:文件追加持久化。與RDB 不同的是,它是通過保存所執(zhí)行的寫命令來實現(xiàn)的,并且保存的數(shù)據(jù)格式是客戶端發(fā)送的命令。
2、AOF 實現(xiàn)方式
想要使用 AOF 持久化方式,需要啟用配置文件中的 appendonly 參數(shù)。默認情況下,Redis 是不開啟的。
開啟 AOF 持久化后每執(zhí)行一條修改數(shù)據(jù)的命令,Redis 就會將該命令寫入 aof_buf 緩沖區(qū)。后續(xù)寫入 AOF 文件中的操作是由下面的配置來控制的:
這三個配置項分別表示
appendfsync always:每次寫入都進行刷盤操作,對性能影響最大,占用磁盤 IO 較高,數(shù)據(jù)安全性最高。
appendfsync everysec:1秒刷一次盤,對性能影響相對較小。
appendfsync no:按照操作系統(tǒng)的機制進行刷盤,對性能影響最小,數(shù)據(jù)安全性低。
3、AOF 重寫機制
隨著命令的不斷寫入,AOF 文件會變得越來越大,這時候該如何是好呢?別急,Redis 中提供了瘦身功能,也就是重寫機制。
Redis 配置文件中有兩個對應(yīng)的參數(shù)是來決定重寫機制的觸發(fā)時機的。
auto-aof-rewrite-percentage:AOF 文件距離上次文件增長超過多少百分比
auto-aof-rewrite-min-size:AOF 文件體積最小多大以上觸發(fā)
滿足所設(shè)置的條件時,會自動觸發(fā) AOF 重寫,此時 Redis 會掃描整個實例的數(shù)據(jù),重新生成一個 AOF 文件來達到瘦身的效果。
4、AOF 文件恢復
同樣地,我們也需要對 AOF 文件進行恢復。和 RBD 不同的是,Redis 中是通過創(chuàng)建一個不帶網(wǎng)絡(luò)連接的偽客戶端來進行實現(xiàn)的。為什么要創(chuàng)建偽客戶端呢?你想想 AOF 文件中的數(shù)據(jù)格式,都是由命令組成的。通過客戶端直接執(zhí)行每條命令就可以將數(shù)據(jù)進行恢復。
在這里需要注意的是,如果服務(wù)器開啟了 AOF 持久化功能,會優(yōu)先使用 AOF 文件來進行恢復。只有在 AOF 關(guān)閉狀態(tài)下,服務(wù)器才會使用 RDB 文件來進行還原。
兩種持久化的優(yōu)/缺點
到這里,對兩種持久化也有了一定的認識,那么我們來看看它們分別有什么優(yōu)點和缺點:
1、RDB 優(yōu)點與缺點
(1)優(yōu)點
文件體積?。篟DB 的文件內(nèi)容是二進制格式,因此體積比實例內(nèi)存小。
恢復速度快:當 Redis 實例恢復時,加載 RDB 文件速度很快,能在很短時間內(nèi)迅速恢復數(shù)據(jù)。
(2)缺點
數(shù)據(jù)缺失:RDB 保存的是某一時刻的數(shù)據(jù),當 Redis 實例某一時刻異常時,會導致數(shù)據(jù)丟失。
消耗資源:RDB 文件的生成會消耗大量的 CPU 和內(nèi)存資源,有一定代價。
2、AOF 優(yōu)點與缺點
(1)優(yōu)點
數(shù)據(jù)更完整:AOF 中是及時寫入的方式,數(shù)據(jù)保存更完整?;謴蜁r降低數(shù)據(jù)的損失率
易讀性強:AOF 中保存的數(shù)據(jù)格式是客戶端的寫入命令,可讀性性強。
(2)缺點
文件體積大:AOF 中存儲客戶端所有的寫命令,未經(jīng)壓縮,隨著命令的寫入,文件會越來越大。
增加磁盤IO:AOF 文件刷盤如果采用每秒刷一次的方式會導致磁盤IO升高,影響性能。
混合持久化
既然 RDB 與 AOF 持久化都存在各自的缺點,那么有沒有一種更好的持久化方式?
接下來要介紹的是混合持久化。其實就是 RDB 與 AOF 的混合模式,這是 Redis4 之后新增的。
1、持久化方式
混合持久化是通過 aof-use-rdb-preamble 參數(shù)來開啟的。它的操作方式是這樣的,在寫入的時候先把數(shù)據(jù)以 RDB 的形式寫入文件的開頭,再將后續(xù)的寫命令以 AOF 的格式追加到文件中。這樣既能保證數(shù)據(jù)恢復時的速度,同時又能減少數(shù)據(jù)丟失的風險。
2、文件恢復
那么混合持久化中是如何來進行數(shù)據(jù)恢復的呢?在 Redis 重啟時,先加載 RDB 的內(nèi)容,然后再重放增量 AOF 格式命令。這樣就避免了 AOF 持久化時的全量加載,從而使加載速率得到大幅提升。
總結(jié)
RDB持久化
- 將某一時刻的數(shù)據(jù)以二進制形式寫入到磁盤里,服務(wù)重啟時檢測到對應(yīng)文件自動加載進行數(shù)據(jù)恢復。
- 有手動觸發(fā)和自動觸發(fā)兩種機制。
AOF持久化
- 以文件追加的方式寫入客戶端執(zhí)行的寫命令。
- 數(shù)據(jù)恢復時,通過創(chuàng)建偽客戶端的方式執(zhí)行命令,直到恢復完成。
混合持久化
- 在寫入的時候先把數(shù)據(jù)以 RDB 的形式寫入文件的開頭,再將后續(xù)的寫命令以 AOF 的格式追加到文件中。