持久化
將數(shù)據(jù)從內(nèi)存中以某種形式同步到硬盤中,使得重啟后可以根據(jù)硬盤中的記錄恢復(fù)數(shù)據(jù),這一過程就是持久化。
Redis支持兩種方式的持久化:
-
RDB方式:根據(jù)指定規(guī)則“定時(shí)”將內(nèi)存中的數(shù)據(jù)存儲(chǔ)在硬盤上; -
AOF方式:每次執(zhí)行命令后將命令本身記錄下來。
一、RDB方式
? RDB方式的持久化是通過快照(snapshotting)完成的,當(dāng)完成一定條件時(shí)Redis會(huì)自動(dòng)將內(nèi)存中的所有數(shù)據(jù)生成一份副本并存儲(chǔ)在硬盤上,這個(gè)過程稱為“快照”。
1.根據(jù)配置規(guī)則進(jìn)行自動(dòng)快照
通過redis.conf配置文件(/usr/local/etc/redis.conf),我們可以看到Redis為我們預(yù)置了3個(gè)條件:
save 900 1 # 在15分鐘(900秒)內(nèi)有一個(gè)或一個(gè)以上的鍵被更改則進(jìn)行快照。
save 300 10 # 在5分鐘(300秒)內(nèi)至少有10個(gè)鍵被更改則進(jìn)行快照。
save 60 10000 # 在1分鐘(60秒)內(nèi)至少有1000個(gè)鍵被更改則進(jìn)行快照。
每條快照條件占一行,以SAVE參數(shù)開頭。我們可以自定義這些參數(shù),如果符合自動(dòng)快照條件,Redis會(huì)自動(dòng)執(zhí)行快照條件。
2.用戶執(zhí)行SAVE或BGSAVE命令
除了自動(dòng)快照,當(dāng)服務(wù)重啟、手動(dòng)遷移以及備份時(shí),我們需要進(jìn)行手動(dòng)快照操作。
1.SAVE命令
當(dāng)執(zhí)行SAVE命令時(shí),Redis同步地進(jìn)行快照操作,在執(zhí)行快照操作中會(huì)阻塞所有來自客戶端的請(qǐng)求。如果數(shù)據(jù)庫中的數(shù)據(jù)比較多時(shí),會(huì)導(dǎo)致Redis較長時(shí)間內(nèi)無響應(yīng)。因避免在生產(chǎn)環(huán)境中使用這一命令。
2.BGSAVE命令(手動(dòng)時(shí)推薦)
BGSAVE命令可以在后臺(tái)異步執(zhí)行快照操作,快照的同時(shí)仍可接受來自客戶端的請(qǐng)求。執(zhí)行BGSAVE命令后Redis立即返回OK表示開始執(zhí)行快照操作,可通過LASTSAVE命令獲取最近一次成功執(zhí)行快照的時(shí)間。
3.執(zhí)行FLUSHALL命令
執(zhí)行FLUSHALL命令時(shí),Redis會(huì)清除數(shù)據(jù)庫中的所有數(shù)據(jù)。但不論清楚數(shù)據(jù)庫的過程是否觸發(fā)了自動(dòng)快照條件,只要自動(dòng)快照條件不為空,Redis就會(huì)執(zhí)行一次快照操作。
當(dāng)沒有定義自動(dòng)快照條件時(shí),執(zhí)行FLUSHALL則不會(huì)進(jìn)行快照。
4.執(zhí)行復(fù)制時(shí)
當(dāng)設(shè)置主從模式時(shí),Redis會(huì)在復(fù)制初始化時(shí)進(jìn)行自動(dòng)快照。即使沒有定義自動(dòng)快照條件和手動(dòng)執(zhí)行快照操作,也會(huì)生成RDB快照文件。
5.快照原理
快照的過程:
? 1)Redis使用fork函數(shù)復(fù)制一份當(dāng)前進(jìn)程(父進(jìn)程)的副本(子進(jìn)程);
? 2)父進(jìn)程繼續(xù)接收并處理客戶端發(fā)來的命令,而子進(jìn)程開始將內(nèi)存中的數(shù)據(jù)寫入到硬盤中的臨時(shí)文件;
? 3)當(dāng)子進(jìn)程寫入完所有數(shù)據(jù)后會(huì)用該臨時(shí)文件替換舊的RDB文件,至此一次快照操作完成。
RDB文件的路徑和文件名,可以通過配置文件redis.conf中的dir和dbfilename參數(shù)來設(shè)置。
RDB文件是經(jīng)過壓縮(可通過配置rdbcompression參數(shù)禁用壓縮,默認(rèn)是開啟的)的二進(jìn)制格式,所以占用的空間會(huì)小于內(nèi)存中的數(shù)據(jù)大小,更加利于傳輸。
Redis啟動(dòng)后會(huì)讀取RDB快照文件,將數(shù)據(jù)從硬盤載入到內(nèi)存中。通過RDB方式實(shí)現(xiàn)的持久化,若Redis出現(xiàn)異常,就會(huì)丟失最后一次快照以后更改的所有數(shù)據(jù)。
二、AOF方式
AOF = Append Only File,AOF持久化可以降低進(jìn)程中止導(dǎo)致的數(shù)據(jù)丟失;他可以將Redis執(zhí)行的每一條寫命令追加到硬盤文件中。
1.開啟AOF
默認(rèn)情況下,Redis是沒有開啟AOF的,可以通過配置文件進(jìn)行開啟:
appendonly yes
AOF文件的保存位置和RDB文件的位置相同,都是同過dir參數(shù)設(shè)置的,默認(rèn)的文件名是appendonly.aof,可以通過appendfilename參數(shù)修改:
appendfilename appendonly.aof
2.AOF實(shí)現(xiàn)
當(dāng)AOF文件的大小達(dá)到一定條件時(shí),Redis就會(huì)自動(dòng)重寫AOF文件,這個(gè)條件可以在配置文件中設(shè)置:
auto-aof-rewrite-percentage 100 # 當(dāng)目前的AOF文件大小超過上一次重寫時(shí)的AOF文件大小的百分之多少時(shí),會(huì)再次進(jìn)行重寫,如果之前沒有重寫,則以啟動(dòng)時(shí)的AOF文件大小為依據(jù)。
auto-aof-rewrite-min-size 64mb # 限制了允許重寫的最小AOF文件大小
除了自動(dòng)執(zhí)行重寫外,還可以手動(dòng)執(zhí)行AOF重寫:
127.0.0.1:6379> bgrewriteaof
AOF文件和RDB文件的文件格式完全不同。
在啟動(dòng)Redis時(shí)會(huì)逐個(gè)執(zhí)行AOF文件中的命令來將硬盤中的數(shù)據(jù)載入到內(nèi)存中,載入速度相較于RDB會(huì)慢一些。
3.同步硬盤數(shù)據(jù)
在執(zhí)行AOF操作時(shí),由于操作系統(tǒng)的緩存機(jī)制,數(shù)據(jù)并未真正地寫入硬盤,而是進(jìn)入了系統(tǒng)的硬盤緩存中。默認(rèn)情況下系統(tǒng)每30秒會(huì)執(zhí)行一次同步操作,以便將硬盤緩存中的數(shù)據(jù)真正寫入到硬盤中,如果在這期間出現(xiàn)異常會(huì)導(dǎo)致硬盤緩存中的數(shù)據(jù)丟失。這就需要通過設(shè)置參數(shù)要求系統(tǒng)主動(dòng)將緩存內(nèi)容同步要硬盤中。
# appendfsync always # 每次執(zhí)行寫入都會(huì)執(zhí)行同步,最安全但也最慢
appendfsync everysec # 默認(rèn)采用everysec規(guī)則,每秒執(zhí)行一次同步操作。
# appendfsync no # 不主動(dòng)進(jìn)行同步操作,而是交給操作系統(tǒng)來做(即每30秒一次),雖快但不安全
一般情況下使用默認(rèn)值everysec就夠了,性能和安全都有保障。
Redis允許同時(shí)開啟AOF和RDB。