redis?的讀寫都是在內(nèi)存中,所以它的性能較高,但在內(nèi)存中的數(shù)據(jù)會(huì)隨著服務(wù)器的重啟而丟失,為了保證數(shù)據(jù)不丟失,我們需要將內(nèi)存中的數(shù)據(jù)存儲(chǔ)到磁盤,以便 Redis 重啟時(shí)能夠從磁盤中恢復(fù)原有的數(shù)據(jù),而整個(gè)過程就叫做 Redis 持久化。
Redis 持久化也是 Redis 和 memcached 的主要區(qū)別之一,因?yàn)?Memcached 是不具備持久化功能的。
1.持久化的幾種方式
Redis 持久化擁有以下三種方式:
快照方式(RDB, Redis database)將某一個(gè)時(shí)刻的內(nèi)存數(shù)據(jù),以二進(jìn)制的方式寫入磁盤;
文件追加方式(AOF, append Only File),記錄所有的操作命令,并以文本的形式追加到文件中;
混合持久化方式,Redis 4.0 之后新增的方式,混合持久化是結(jié)合了 RDB 和 AOF 的優(yōu)點(diǎn),在寫入的時(shí)候,先把當(dāng)前的數(shù)據(jù)以 RDB 的形式寫入文件的開頭,再將后續(xù)的操作命令以 AOF 的格式存入文件,這樣既能保證 Redis 重啟時(shí)的速度,又能簡(jiǎn)單數(shù)據(jù)丟失的風(fēng)險(xiǎn)。
因?yàn)槊糠N持久化方案,都有特定的使用場(chǎng)景,讓我們先從 RDB 持久化說起吧。
2.RDB簡(jiǎn)介
RDB(Redis DataBase)是將某一個(gè)時(shí)刻的內(nèi)存快照(Snapshot),以二進(jìn)制的方式寫入磁盤的過程。
3.持久化觸發(fā)
RDB 的持久化觸發(fā)方式有兩類:一類是手動(dòng)觸發(fā),另一類是自動(dòng)觸發(fā)。
1)手動(dòng)觸發(fā)
手動(dòng)觸發(fā)持久化的操作有兩個(gè): save 和 bgsave ,它們主要區(qū)別體現(xiàn)在:是否阻塞 Redis 主線程的執(zhí)行。
① save 命令
在客戶端中執(zhí)行 save 命令,就會(huì)觸發(fā) Redis 的持久化,但同時(shí)也是使 Redis 處于阻塞狀態(tài),直到 RDB 持久化完成,才會(huì)響應(yīng)其他客戶端發(fā)來的命令,所以在生產(chǎn)環(huán)境一定要慎用。
save?命令使用如下:
從圖片可以看出,當(dāng)執(zhí)行完?save?命令之后,持久化文件 dump.rdb?的修改時(shí)間就變了,這就表示 save?成功的觸發(fā)了?RDB 持久化。
save?命令執(zhí)行流程,如下圖所示:
② bgsave 命令
bgsave(background save)既后臺(tái)保存的意思, 它和 save 命令最大的區(qū)別就是 bgsave 會(huì) fork() 一個(gè)子進(jìn)程來執(zhí)行持久化,整個(gè)過程中只有在 fork() 子進(jìn)程時(shí)有短暫的阻塞,當(dāng)子進(jìn)程被創(chuàng)建之后,Redis 的主進(jìn)程就可以響應(yīng)其他客戶端的請(qǐng)求了,相對(duì)于整個(gè)流程都阻塞的 save 命令來說,顯然 bgsave 命令更適合我們使用。
bgsave 命令使用,如下圖所示:
bgsave?執(zhí)行流程,如下圖所示:
2)自動(dòng)觸發(fā)
說完了?RDB?的手動(dòng)觸發(fā)方式,下面來看如何自動(dòng)觸發(fā)?RDB?持久化?
RDB?自動(dòng)持久化主要來源于以下幾種情況。
① save m n
save m n?是指在 m 秒內(nèi),如果有 n 個(gè)鍵發(fā)生改變,則自動(dòng)觸發(fā)持久化。
參數(shù) m?和?n?可以在?Redis?的配置文件中找到,例如,save 60 1?則表明在 60 秒內(nèi),至少有一個(gè)鍵發(fā)生改變,就會(huì)觸發(fā)?RDB?持久化。
自動(dòng)觸發(fā)持久化,本質(zhì)是?Redis?通過判斷,如果滿足設(shè)置的觸發(fā)條件,自動(dòng)執(zhí)行一次?bgsave?命令。
注意:當(dāng)設(shè)置多個(gè) save m n 命令時(shí),滿足任意一個(gè)條件都會(huì)觸發(fā)持久化。
例如,我們?cè)O(shè)置了以下兩個(gè) save m n 命令:
save?60?10save?600?1
當(dāng) 60s 內(nèi)如果有 10 次 Redis 鍵值發(fā)生改變,就會(huì)觸發(fā)持久化;如果 60s 內(nèi) Redis 的鍵值改變次數(shù)少于 10 次,那么 Redis 就會(huì)判斷 600s 內(nèi),Redis 的鍵值是否至少被修改了一次,如果滿足則會(huì)觸發(fā)持久化。
② flushall
flushall?命令用于清空 Redis 數(shù)據(jù)庫(kù),在生產(chǎn)環(huán)境下一定慎用,當(dāng) Redis 執(zhí)行了?flushall?命令之后,則會(huì)觸發(fā)自動(dòng)持久化,把?RDB 文件清空。
執(zhí)行結(jié)果如下圖所示:
③ 主從同步觸發(fā)
在 Redis 主從復(fù)制中,當(dāng)從節(jié)點(diǎn)執(zhí)行全量復(fù)制操作時(shí),主節(jié)點(diǎn)會(huì)執(zhí)行 bgsave?命令,并將 RDB 文件發(fā)送給從節(jié)點(diǎn),該過程會(huì)自動(dòng)觸發(fā) Redis 持久化。
4.配置說明
合理的設(shè)置 RDB 的配置,可以保障 Redis 高效且穩(wěn)定的運(yùn)行,下面一起來看 RDB 的配置項(xiàng)都有哪些?
RDB 配置參數(shù)可以在? Redis 的配置文件中找見,具體內(nèi)容如下:
# RDB 保存的條件 save 900 1 save 300 10 save 60 10000 # bgsave 失敗之后,是否停止持久化數(shù)據(jù)到磁盤,yes 表示停止持久化,no 表示忽略錯(cuò)誤繼續(xù)寫文件。 stop-writes-on-bgsave-error yes # RDB 文件壓縮 rdbcompression yes # 寫入文件和讀取文件時(shí)是否開啟 RDB 文件檢查,檢查是否有無損壞,如果在啟動(dòng)是檢查發(fā)現(xiàn)損壞,則停止啟動(dòng)。 rdbchecksum yes # RDB 文件名 dbfilename dump.rdb # RDB 文件目錄 dir ./
其中比較重要的參數(shù)如下列表:
① save 參數(shù)
它是用來配置觸發(fā) RDB 持久化條件的參數(shù),滿足保存條件時(shí)將會(huì)把數(shù)據(jù)持久化到硬盤。
默認(rèn)配置說明如下:
save 900 1:表示 900 秒內(nèi)如果至少有 1 個(gè) key 值變化,則把數(shù)據(jù)持久化到硬盤;save 300 10:表示 300 秒內(nèi)如果至少有 10 個(gè) key 值變化,則把數(shù)據(jù)持久化到硬盤;save 60 10000:表示 60 秒內(nèi)如果至少有 10000 個(gè) key 值變化,則把數(shù)據(jù)持久化到硬盤。
② rdbcompression 參數(shù)
它的默認(rèn)值是?yes?表示開啟 RDB 文件壓縮,Redis 會(huì)采用 LZF 算法進(jìn)行壓縮。如果不想消耗 CPU 性能來進(jìn)行文件壓縮的話,可以設(shè)置為關(guān)閉此功能,這樣的缺點(diǎn)是需要更多的磁盤空間來保存文件。
③ rdbchecksum 參數(shù)
它的默認(rèn)值為?yes?表示寫入文件和讀取文件時(shí)是否開啟 RDB 文件檢查,檢查是否有無損壞,如果在啟動(dòng)是檢查發(fā)現(xiàn)損壞,則停止啟動(dòng)。
5.配置查詢
Redis 中可以使用命令查詢當(dāng)前配置參數(shù)。查詢命令的格式為:config get xxx?,例如,想要獲取 RDB 文件的存儲(chǔ)名稱設(shè)置,可以使用 config get dbfilename?,執(zhí)行效果如下圖所示:
查詢 RDB 的文件目錄,可使用命令 config get dir?,執(zhí)行效果如下圖所示:
6.配置設(shè)置
設(shè)置 RDB 的配置,可以通過以下兩種方式:
●?手動(dòng)修改 Redis 配置文件;
●?使用命令行設(shè)置,例如,使用?config set dir “/usr/data”?就是用于修改 RDB 的存儲(chǔ)目錄。
注意:手動(dòng)修改 Redis 配置文件的方式是全局生效的,即重啟?Redis?服務(wù)器設(shè)置參數(shù)也不會(huì)丟失,而使用命令修改的方式,在 Redis 重啟之后就會(huì)丟失。但手動(dòng)修改?Redis?配置文件,想要立即生效需要重啟?Redis?服務(wù)器,而命令的方式則不需要重啟?Redis?服務(wù)器。
小貼士:Redis?的配置文件位于?Redis?安裝目錄的根路徑下,默認(rèn)名稱為 redis.conf。
7.RDB 文件恢復(fù)
當(dāng)?Redis?服務(wù)器啟動(dòng)時(shí),如果 Redis 根目錄存在?RDB?文件 dump.rdb,Redis 就會(huì)自動(dòng)加載 RDB 文件恢復(fù)持久化數(shù)據(jù)。
如果根目錄沒有?dump.rdb 文件,請(qǐng)先將 dump.rdb?文件移動(dòng)到 Redis 的根目錄。
驗(yàn)證?RDB?文件是否被加載
Redis?在啟動(dòng)時(shí)有日志信息,會(huì)顯示是否加載了?RDB?文件,我們執(zhí)行 Redis 啟動(dòng)命令:src/redis-server redis.conf?,如下圖所示:
從日志上可以看出, Redis 服務(wù)在啟動(dòng)時(shí)已經(jīng)正常加載了 RDB 文件。
小貼士:Redis 服務(wù)器在載入 RDB 文件期間,會(huì)一直處于阻塞狀態(tài),直到載入工作完成為止。
8.RDB 優(yōu)缺點(diǎn)
1)RDB 優(yōu)點(diǎn)
●?RDB 的內(nèi)容為二進(jìn)制的數(shù)據(jù),占用內(nèi)存更小,更緊湊,更適合做為備份文件;
●?RDB 對(duì)災(zāi)難恢復(fù)非常有用,它是一個(gè)緊湊的文件,可以更快的傳輸?shù)竭h(yuǎn)程服務(wù)器進(jìn)行 Redis 服務(wù)恢復(fù);
●?RDB 可以更大程度的提高 Redis 的運(yùn)行速度,因?yàn)槊看纬志没瘯r(shí) Redis 主進(jìn)程都會(huì) fork() 一個(gè)子進(jìn)程,進(jìn)行數(shù)據(jù)持久化到磁盤,Redis 主進(jìn)程并不會(huì)執(zhí)行磁盤 I/O 等操作;
●?與 AOF 格式的文件相比,RDB 文件可以更快的重啟。
2)RDB 缺點(diǎn)
●?因?yàn)?RDB 只能保存某個(gè)時(shí)間間隔的數(shù)據(jù),如果中途 Redis 服務(wù)被意外終止了,則會(huì)丟失一段時(shí)間內(nèi)的 Redis 數(shù)據(jù);
●?RDB 需要經(jīng)常 fork() 才能使用子進(jìn)程將其持久化在磁盤上。如果數(shù)據(jù)集很大,fork() 可能很耗時(shí),并且如果數(shù)據(jù)集很大且 CPU 性能不佳,則可能導(dǎo)致 Redis 停止為客戶端服務(wù)幾毫秒甚至一秒鐘。
9.禁用持久化
禁用持久化可以提高 Redis 的執(zhí)行效率,如果對(duì)數(shù)據(jù)丟失不敏感的情況下,可以在連接客戶端的情況下,執(zhí)行 config set save “”?命令即可禁用 Redis 的持久化,如下圖所示:
10.小結(jié)
通過本文我們可以得知,RDB?持久化分為手動(dòng)觸發(fā)和自動(dòng)觸發(fā)兩種方式,它的優(yōu)點(diǎn)是存儲(chǔ)文件小,Redis?啟動(dòng)時(shí)恢復(fù)數(shù)據(jù)比較快,缺點(diǎn)是有丟失數(shù)據(jù)的風(fēng)險(xiǎn)。RDB?文件的恢復(fù)也很簡(jiǎn)單,只需要把?RDB?文件放到?Redis?的根目錄,在?Redis?啟動(dòng)時(shí)就會(huì)自動(dòng)加載并恢復(fù)數(shù)據(jù)。
更多Redis相關(guān)知識(shí),請(qǐng)?jiān)L問Redis使用教程欄目!??