十年網(wǎng)站開發(fā)經(jīng)驗 + 多家企業(yè)客戶 + 靠譜的建站團隊
量身定制 + 運營維護+專業(yè)推廣+無憂售后,網(wǎng)站問題一站解決
一、概述

Redis的強大性能很大程度上都是因為所有數(shù)據(jù)都是存儲在內(nèi)存中的,然而當(dāng)Redis重啟后,所有存儲在內(nèi)存中的數(shù)據(jù)將會丟失,在很多情況下是無法容忍這樣的事情的。所以,我們需要將內(nèi)存中的數(shù)據(jù)持久化!典型的需要持久化數(shù)據(jù)的場景如下:
本文介紹Redis所支持的兩種數(shù)據(jù)持久化方式。
二、Redis數(shù)據(jù)持久化
Redis支持兩種數(shù)據(jù)持久化方式:RDB方式和AOF方式。前者會根據(jù)配置的規(guī)則定時將內(nèi)存中的數(shù)據(jù)持久化到硬盤上,后者則是在每次執(zhí)行寫命令之后將命令記錄下來。兩種持久化方式可以單獨使用,但是通常會將兩者結(jié)合使用。
1、RDB方式
RDB方式的持久化是通過快照的方式完成的。當(dāng)符合某種規(guī)則時,會將內(nèi)存中的數(shù)據(jù)全量生成一份副本存儲到硬盤上,這個過程稱作”快照”,Redis會在以下幾種情況下對數(shù)據(jù)進行快照:
執(zhí)行快照的場景
(1)根據(jù)配置自動快照
Redis允許用戶自定義快照條件,當(dāng)滿足條件時自動執(zhí)行快照。缺省情況下,Redis把數(shù)據(jù)快照存放在磁盤上的二進制文件中,文件名為dump.rdb,此外,我們也可以通過配置文件來修改Redis服務(wù)器dump快照的頻率,在打開redis.windows.conf文件之后,我們搜索save,可以看到下面的配置信息:

注意最后三行,分別表示:
在900秒(15分鐘)之后,如果至少有1個key發(fā)生變化,則dump內(nèi)存快照;
在300秒(5分鐘)之后,如果至少有10個key發(fā)生變化,則dump內(nèi)存快照;
在60秒(1分鐘)之后,如果至少有10000個key發(fā)生變化,則dump內(nèi)存快照。
每個快照條件獨占一行,他們之間是或(||)關(guān)系,只要滿足任何一個就進行快照。上面配置save后的第一個參數(shù)T是時間,單位是秒,第二個參數(shù)M是更改的鍵的個數(shù),含義是:當(dāng)時間T內(nèi)被更改的鍵的個數(shù)大于M時,自動進行快照。比如save 900 1的含義是15分鐘內(nèi)(900s)被更改的鍵的個數(shù)大于1時,自動進行快照操作。
(2)執(zhí)行SAVE或BGSAVE命令
除了讓Redis自動進行快照外,當(dāng)我們需要重啟,遷移,備份Redis時,我們也可以手動執(zhí)行SAVE或BGSAVE命令主動進行快照操作。
SAVE命令:當(dāng)執(zhí)行SAVE命令時,Redis同步進行快照操作,期間會阻塞所有來自客戶端的請求,所以放數(shù)據(jù)庫數(shù)據(jù)較多時,應(yīng)該避免使用該命令;
BGSAVE命令:從命令名字就能看出來,這個命令與SAVE命令的區(qū)別就在于該命令的快照操作是在后臺異步進行的,進行快照操作的同時還能處理來自客戶端的請求。執(zhí)行BGSAVE命令后Redis會馬上返回OK表示開始進行快照操作,如果想知道快照操作是否已經(jīng)完成,可以使用LASTSAVE命令返回最近一次成功執(zhí)行快照的時間,返回結(jié)果是一個Unix時間戳。
(3)執(zhí)行FLUSHALL命令
當(dāng)執(zhí)行FLUSHALL命令時,Redis會清除數(shù)據(jù)庫中的所有數(shù)據(jù)。需要注意的是:不論清空數(shù)據(jù)庫的過程是否觸發(fā)了自動快照的條件,只要自動快照條件不為空,Redis就會執(zhí)行一次快照操作,當(dāng)沒有定義自動快照條件時,執(zhí)行FLUSHALL命令不會進行快照操作。
(4)執(zhí)行復(fù)制
當(dāng)設(shè)置了主從模式時,Redis會在復(fù)制初始化時進行自動快照。
快照原理
Redis默認(rèn)會將快照文件存儲在Redis當(dāng)前進程的工作目錄的dump.rdb文件中,可以通過配置文件中的dir和dbfilename兩個參數(shù)分別指定快照文件的存儲路徑和文件名,默認(rèn)的存儲路徑和文件名如下圖所示:

快照執(zhí)行的過程如下:
(1)Redis使用fork函數(shù)復(fù)制一份當(dāng)前進程(父進程)的副本(子進程);
(2)父進程繼續(xù)處理來自客戶端的請求,子進程開始將內(nèi)存中的數(shù)據(jù)寫入硬盤中的臨時文件;
(3)當(dāng)子進程寫完所有的數(shù)據(jù)后,用該臨時文件替換舊的RDB文件,至此,一次快照操作完成。
需要注意的是:
在執(zhí)行fork的時候操作系統(tǒng)(類Unix操作系統(tǒng))會使用寫時復(fù)制(copy-on-write)策略,即fork函數(shù)發(fā)生的一刻,父進程和子進程共享同一塊內(nèi)存數(shù)據(jù),當(dāng)父進程需要修改其中的某片數(shù)據(jù)(如執(zhí)行寫命令)時,操作系統(tǒng)會將該片數(shù)據(jù)復(fù)制一份以保證子進程不受影響,所以RDB文件存儲的是執(zhí)行fork操作那一刻的內(nèi)存數(shù)據(jù)。所以RDB方式理論上是會存在丟數(shù)據(jù)的情況的(fork之后修改的的那些沒有寫進RDB文件)。
通過上述的介紹可以知道,快照進行時是不會修改RDB文件的,只有完成的時候才會用臨時文件替換老的RDB文件,所以就保證任何時候RDB文件的都是完整的。這使得我們可以通過定時備份RDB文件來實現(xiàn)Redis數(shù)據(jù)的備份。RDB文件是經(jīng)過壓縮處理的二進制文件,所以占用的空間會小于內(nèi)存中數(shù)據(jù)的大小,更有利于傳輸。
Redis啟動時會自動讀取RDB快照文件,將數(shù)據(jù)從硬盤載入到內(nèi)存,根據(jù)數(shù)量的不同,這個過程持續(xù)的時間也不盡相同,通常來講,一個記錄1000萬個字符串類型鍵,大小為1GB的快照文件載入到內(nèi)存需要20-30秒的時間。
示例
下面演示RDB方式持久化,首先使用配置有如下快照規(guī)則:
save 900 1 save 300 10 save 60 10000 dbfilename dump.rdb dir ./
另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國服務(wù)器、虛擬主機、免備案服務(wù)器”等云主機租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務(wù)可用性高、性價比高”等特點與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場景需求。