Redis學習之持久化
前言
在前面我們學習了Redis的基本操作,也學習了Redis的Java客戶端Jedis的使用,接下來我們來學習Redis的持久化。
在前面的學習中,我們知道Redis是基于內(nèi)存的鍵值對數(shù)據(jù)庫,眾所周知,基于內(nèi)存的數(shù)據(jù)會在內(nèi)存斷電之后丟失,所以,如果Redis中沒有持久化機制,那么,當Redis服務(wù)器重啟之后,存儲的數(shù)據(jù)就丟失了,這顯示是不能接受的,所幸,Redis有持久化機制,本小節(jié)我們就來學習這部分的內(nèi)容。
持久化
Redis支持兩種不同的持久化方式,RDB以及AOF,RDB會定時將內(nèi)存中的數(shù)據(jù)存儲在硬盤上,而AOF則是每次將命令記錄下來,Redis中這兩種方式可以單獨使用,也可以混合使用。
RDB方式
RDB持久化是通過快照的方式完成的,當符合一定條件時,Redis會自動將內(nèi)存中的所有數(shù)據(jù)生成一份副本并存儲在硬盤上
觸發(fā)條件
- 根據(jù)配置規(guī)則進行自動快照
- 用戶執(zhí)行save或者bgsave命令
- 執(zhí)行flushall命令
- 執(zhí)行復制時
配置規(guī)則
配置規(guī)則配置在Redis的配置文件中,save命令后面跟一個時間窗口大小以及該時間內(nèi)被修改的鍵的個數(shù),舉例如下
save 900 1 # 900秒內(nèi)至少一個鍵被修改
save 300 10 # 300秒內(nèi)至少十個鍵被修改
save 60 10000 # 60秒內(nèi)至少10000個鍵被修改
多個規(guī)則之間是或的關(guān)系,也就是只要其中一個條件滿足,則觸發(fā)RDB持久化
save/bgsave命令
save命令是前臺操作,命令執(zhí)行后Redis會阻塞所有的客戶端請求,在生產(chǎn)環(huán)境中不建議使用
bgsave執(zhí)行之后,Redis會在后臺執(zhí)行快照操作(異步),快照的同時服務(wù)器可以繼續(xù)響應(yīng)客戶端請求
flushall命令
執(zhí)行flushall時,Redis會清除數(shù)據(jù)庫中所有數(shù)據(jù),無論清空數(shù)據(jù)庫的過程是否滿足觸發(fā)條件,只要自動快照條件不為空,則會進行快照操作
快照原理
Redis默認將快照文件存儲在當前進程工作目錄下的dump.rdb文件中,可以通過配置dbfilename FILENAME來指定文件的名稱,通過dir PATH來指定工作的目錄
快照過程
- Reids使用fork系統(tǒng)調(diào)用產(chǎn)生子進程
- 父進程繼續(xù)處理請求,子進程開始將內(nèi)存中的數(shù)據(jù)寫入臨時文件
- 當子進程完成所有數(shù)據(jù)的寫入操作后,將該臨時文件替換舊的RDB文件,完成快照操作
由于fork操作采用的是寫時復制策略,所以,如果父進程沒有進行操作,子進程與父進程共享同份內(nèi)存,如果父進程發(fā)生寫入操作,則子進程會復制一份父進程的內(nèi)存空間,所以,快照的內(nèi)容其實只是fork時刻的內(nèi)存,而不是實時的數(shù)據(jù)。
RDB文件是經(jīng)過壓縮的,可以通過配置rdbcompression yes/no來決定是否啟動壓縮功能,啟動壓縮功能會消耗多一點CPU資源,但減少文件的大小。
Redis啟動后會自動讀取RDB文件,并將數(shù)據(jù)從硬盤載入到內(nèi)存中。
AOF方式
AOF是將每條命令追加到硬盤中,可以通過appendonly yes/no來啟用,通過appendfilename FILENAME來設(shè)置AOF文件的名稱,存儲位置也是dir指定的目錄之下。
默認情況下AOF會記錄所有的操作,當命令重復比較大的情況下,會比較消耗空間,所以,Redis提供了重寫AOF的功能,可以通過auto-aof-rewrite-percentage PERCENT、auto-aof-rewrite-min-size SIZE來配置自動重寫的觸發(fā)條件
auto-aof-rewrite-percentage表示當前的AOF文件的大小超過上一次重寫時AOF文件大小的百分比時會自動重寫,如果之前沒有重寫過,則以啟動時的AOF文件大小為基準。
auto-aof-rewrite-min-size表示允許重寫的最小AOF文件大小
可以通過bgrewriteaof來手動觸發(fā)重寫
由于OS本身會對寫入磁盤的數(shù)據(jù)做緩存,所以雖然AOF是將每條命令寫入到磁盤中,但是實際上并不會實時刷新到硬盤中,所以,如果需要實時寫入,需要配置如下內(nèi)容
#appendfsync always #每次寫入,會對性能有影響
appendfsync everysec # 每秒寫入
# appendfsync no # 由OS來決定寫入時間
如果同時開啟AOF和RDB,Redis會在重啟之后使用AOF來恢復數(shù)據(jù),畢竟AOF丟失的數(shù)據(jù)量比較少
總結(jié)
本小節(jié)我們主要學習了Redis的兩種持久化方式,RDB和AOF,RDB是根據(jù)觸發(fā)條件對內(nèi)存的數(shù)據(jù)執(zhí)行一次快照操作,AOF則是將每次操作的命令記錄下來。兩種方式中,Redis默認啟用的是RDB方式,AOF則需要我們手動開啟,相比于RDB,AOF能保存的數(shù)據(jù)更加完整,所以如果兩者都啟用,Redis重啟的時候,以AOF為基準進行數(shù)據(jù)的恢復。