Redis 的持久化與過期鍵

簡介

Redis 是使用非常廣泛的 Key-Value 內(nèi)存數(shù)據(jù)庫。因?yàn)閿?shù)據(jù)都存放在內(nèi)存中秽晚,所以存取速度非程翱牵快。不過椒楣,很多情況下我們需要將 Redis 中的數(shù)據(jù)保存到硬盤中以便做備份给郊。Redis 提供了兩種數(shù)據(jù)持久化方式,分別是 RDB 和 AOP撒顿,本文分析這兩種方式的使用以及過期鍵對(duì)持久化的影響丑罪。

RDB

RDB 指的是將 Redis 數(shù)據(jù)庫在某個(gè)時(shí)間點(diǎn)的快照保存到磁盤,所生成的 RDB 文件是一個(gè)經(jīng)過壓縮的二進(jìn)制文件凤壁,通過這個(gè)文件可以還原出 Redis 的數(shù)據(jù)狀態(tài)吩屹。

創(chuàng)建快照的方式有以下幾種:

  • 客戶端向 Redis 發(fā)送 BGSAVE 命令,Redis 會(huì)調(diào)用 fork 創(chuàng)建一個(gè)子進(jìn)程拧抖,然后子進(jìn)程負(fù)責(zé)將快照寫入硬盤煤搜,而父進(jìn)程繼續(xù)處理命令請求。
  • 客戶端向 Redis 發(fā)送 SAVE 命令唧席,此時(shí) Redis 將開始創(chuàng)建快照擦盾,并且在完成之前不再響應(yīng)其它命令嘲驾。
  • 用戶設(shè)置 save 配置選項(xiàng),比如 save 60 10000迹卢,那么從 Redis 最近一次創(chuàng)建快照算起辽故,當(dāng) “60 秒內(nèi)有 10000 次寫入” 這個(gè)條件被滿足時(shí), Redis 就會(huì)自動(dòng)觸發(fā) BGSAVE 命令腐碱。如果用戶設(shè)置了多個(gè) save 配置選項(xiàng)誊垢,那么當(dāng)任意一個(gè) save 配置滿足時(shí),Redis 就會(huì)觸發(fā)一次 BGSAVE 命令症见。save 配置的格式如下所示:
save 60 10000
stop-writes-on-bgsave-error no
rdbcompression yes    // 使用壓縮
dbfilename dump.rdb  // RBD 文件的名字

dir ./
  • 當(dāng) Redis 通過 SHUTDOWN 命令接收到關(guān)閉服務(wù)器的請求時(shí)喂走,或者接收到 TERM命令時(shí),會(huì)執(zhí)行一個(gè) SAVE 命令谋作,并且阻塞所有的客戶端芋肠,不再執(zhí)行任何請求。在 SAVE 命令執(zhí)行結(jié)束后關(guān)閉服務(wù)器遵蚜。

  • 當(dāng)一個(gè) Redis 服務(wù)器連接另一個(gè) Redis 服務(wù)器帖池,并向?qū)Ψ桨l(fā)送 SYNC 命令來開始一次復(fù)制操作的時(shí)候,如果主服務(wù)器沒有在執(zhí)行 BGSAVE 操作谬晕,或者主服務(wù)器并非剛執(zhí)行完 BGSAVE碘裕,那么主服務(wù)器會(huì)執(zhí)行 BGSAVE 命令。

RDB 的主要問題是攒钳,如果系統(tǒng)發(fā)生崩潰帮孔,那么最近一次執(zhí)行完快照后修改的數(shù)據(jù)將被丟失。因此不撑,RDB 適合用于即使丟失一部分?jǐn)?shù)據(jù)也不會(huì)造成影響的應(yīng)用程序文兢。

AOF

AOF 指的是將所有執(zhí)行的寫命令寫到 AOF 文件的末尾,以此來記錄數(shù)據(jù)發(fā)生的變化焕檬。如果 Redis 想要恢復(fù) AOF 中的數(shù)據(jù)姆坚,只要重新執(zhí)行一次 AOF 文件中所包含的寫命令就可以。

AOF 的配置如下所示:

appendonly yes  // 打開 aof
appendfsync everysec // aof 同步的頻率
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100 // 文件大小增長比超過這個(gè)值開始自動(dòng)重寫 aof
auto-aof-rewrite-min-size 64mb  // 文件大小超過這個(gè)值才可以有可能自動(dòng)重寫 aof

上面的配置中实愚,appendfsync everysec 設(shè)置的是同步的頻率兼呵。應(yīng)用程序在向硬盤寫入數(shù)據(jù)的時(shí)候有 3 個(gè)步驟:

  1. 調(diào)用 file.write() 向文件寫入,此時(shí)需要寫入的內(nèi)容被存儲(chǔ)到了緩沖區(qū)腊敲,并不是真正寫到硬盤上了击喂。
  2. 操作系統(tǒng)在某個(gè)時(shí)候?qū)⒕彌_區(qū)的內(nèi)容寫入硬盤,這時(shí)數(shù)據(jù)才真正被持久化了碰辅。

操作系統(tǒng)使用以上的文件寫入方式是為了提高性能懂昂,畢竟硬盤 I/O 操作是比較耗時(shí)的。但是没宾,這種方式的缺點(diǎn)在于如果機(jī)器崩潰了那么緩沖區(qū)的內(nèi)容將丟失凌彬。程序可以使用 file.flush() 來請求操作系統(tǒng)盡快地將緩沖區(qū)的內(nèi)容刷新到硬盤上沸柔,不過何時(shí)開始執(zhí)行仍然由操作系統(tǒng)決定。程序也可以命令操作系統(tǒng)將文件同步 ( sync ) 到硬盤铲敛,同步操作會(huì)阻塞應(yīng)用程序直到數(shù)據(jù)被寫入硬盤褐澎。當(dāng)同步操作完成后,即使系統(tǒng)出現(xiàn)故障原探,也不會(huì)對(duì)被同步的文件造成影響乱凿。

對(duì)于 Redis 來講,可以指定 appendfsync 以何種方式讓數(shù)據(jù)完全同步到硬盤咽弦,這個(gè)配置有 3 個(gè)選項(xiàng):

  1. always: 每個(gè) Redis 寫命令都立即同步到硬盤,這是比較消耗性能的
  2. everysec: 每秒執(zhí)行一次同步胁出,兼顧性能與數(shù)據(jù)安全型型,是比較常用的選項(xiàng)
  3. no: 讓操作系統(tǒng)決定何時(shí)進(jìn)行同步

always 可以使得在 Redis 發(fā)生崩潰時(shí)丟失的數(shù)據(jù)最少,但是也是最消耗性能的全蝶,導(dǎo)致 Redis 的處理速度變慢闹蒜。ererysec 是一種兼顧性能與數(shù)據(jù)安全的方式,在這種情況下抑淫,如果系統(tǒng)崩潰绷落,用戶最多會(huì)丟失一秒內(nèi)的數(shù)據(jù)。no 選項(xiàng)完全將同步交給操作系統(tǒng)被決定始苇,性能也不比 everysec 高多少砌烁,是不推薦的方式。

AOF 的缺點(diǎn)是隨著 Redis 的不斷運(yùn)行催式,AOF 文件可能會(huì)非常大函喉,甚至用完硬盤的空間。解決這個(gè)問題的辦法是 AOF 重寫荣月。

重寫

客戶端可以發(fā)送 BGREWRITEAOF 命令讓 Redis 重寫 AOF 文件管呵,Redis 會(huì)移除冗余的 AOF 命令進(jìn)行重寫,使得 AOF 文件的體積盡可能地小哺窄。

除了客戶端主動(dòng)發(fā)送 BGREWRITEAOF 命令捐下,也可以使用配置讓 Redis 在滿足一定條件地情況下自動(dòng)開始重寫 AOF 文件。例如上一小節(jié)設(shè)置了 auto-aof-rewrite-percentage 100auto-aof-rewrite-min-size 64mb萌业。這兩個(gè)配置的含義是坷襟,如果 AOF 文件大于 64MB 并且比上一次重寫之后的大小增加了一倍的時(shí)候,Redis 將執(zhí)行 BGREWERITEAOF 命令咽白。

過期鍵刪除

用戶往往為 Redis 中的鍵設(shè)定過期時(shí)間啤握,因此需要一定的策略來刪除過期鍵,可以有三種策略:

  1. 定時(shí)刪除晶框,即通過定時(shí)器在過期時(shí)間到達(dá)的時(shí)候刪除過期的鍵排抬。這種方式的優(yōu)點(diǎn)是節(jié)省內(nèi)存懂从,不會(huì)因?yàn)榇罅康倪^期鍵占用內(nèi)存資源番甩,而缺點(diǎn)則是消耗 CPU 資源缘薛,尤其是過期鍵數(shù)量較多的時(shí)候,刪除操作消耗太長時(shí)間卡睦,降低了 Redis 的響應(yīng)時(shí)間宴胧。

  2. 惰性刪除,即在每次獲取某個(gè)鍵的時(shí)候判斷是否過期表锻,如果未過期恕齐,則正常返回其值,否則刪除這個(gè)鍵瞬逊,返回空显歧。這種方式的優(yōu)點(diǎn)是節(jié)省 CPU 資源,但是消耗了內(nèi)存确镊。尤其是過期鍵數(shù)量較多的時(shí)候士骤,大量內(nèi)存被無效的鍵占用,相當(dāng)于內(nèi)存泄露蕾域。

  3. 定期刪除拷肌,即每隔一段時(shí)間周期對(duì)數(shù)據(jù)庫中的鍵進(jìn)行掃描,但是只掃描其中一部分束铭,力求在內(nèi)存和 CPU 之間達(dá)到一個(gè)平衡廓块。

從上面 3 種策略可以看出,單用第一個(gè)肯定是不行的契沫,Redis 的響應(yīng)時(shí)間至關(guān)重要带猴。第二個(gè)則是比較好的方式,在獲取鍵的時(shí)候判斷是否過期并決定是否刪除懈万,它的缺點(diǎn)是很多鍵無法及時(shí)刪除拴清。如果一個(gè)過期鍵再也沒有被訪問,那么它將永遠(yuǎn)留在內(nèi)存中会通,而第三種方式正好可以彌補(bǔ)口予。

Redis 中過期鍵的刪除策略正是惰性刪除與定期刪除的結(jié)合。

過期鍵與持久化

了解了過期鍵的刪除策略后涕侈,下面看下鍵的過期時(shí)間對(duì)持久化的影響沪停。

在生成 RDB 文件的過程中,如果一個(gè)鍵已經(jīng)過期,那么其不會(huì)被保存到 RDB 文件中木张。在載入 RDB 的時(shí)候众辨,要分兩種情況:

  1. 如果 Redis 以主服務(wù)器的模式運(yùn)行,那么會(huì)對(duì) RDB 中的鍵進(jìn)行時(shí)間檢查舷礼,過期的鍵不會(huì)被恢復(fù)到 Redis 中鹃彻。
  2. 如果 Redis 以從服務(wù)器的模式運(yùn)行,那么 RDB 中所有的鍵都會(huì)被載入妻献,忽略時(shí)間檢查蛛株。在從服務(wù)器與主服務(wù)器進(jìn)行數(shù)據(jù)同步的時(shí)候,從服務(wù)器的數(shù)據(jù)會(huì)先被清空育拨,所以載入過期鍵不會(huì)有問題谨履。

對(duì)于 AOF 來說,如果一個(gè)鍵過期了至朗,那么不會(huì)立刻對(duì) AOF 文件造成影響屉符。因?yàn)?Redis 使用的是惰性刪除和定期刪除,只有這個(gè)鍵被刪除了锹引,才會(huì)往 AOF 文件中追加一條 DEL 命令。在重寫 AOF 的過程中唆香,程序會(huì)檢查數(shù)據(jù)庫中的鍵嫌变,已經(jīng)過期的鍵不會(huì)被保存到 AOF 文件中。

在運(yùn)行過程中躬它,對(duì)于主從復(fù)制的 Redis腾啥,主服務(wù)器和從服務(wù)器對(duì)于過期鍵的處理也不相同:

  1. 對(duì)于主服務(wù)器,一個(gè)過期的鍵被刪除了后冯吓,會(huì)向從服務(wù)器發(fā)送 DEL 命令倘待,通知從服務(wù)器刪除對(duì)應(yīng)的鍵
  2. 從服務(wù)器接收到讀取一個(gè)鍵的命令時(shí),即使這個(gè)鍵已經(jīng)過期组贺,也不會(huì)刪除凸舵,而是照常處理這個(gè)命令。
  3. 從服務(wù)器接收到主服務(wù)器的 DEL 命令后失尖,才會(huì)刪除對(duì)應(yīng)的過期鍵啊奄。

這么做的主要目的是保證數(shù)據(jù)一致性,所以當(dāng)一個(gè)過期鍵存在于主服務(wù)器時(shí)掀潮,也必然存在于從服務(wù)器菇夸。

總結(jié)

本文對(duì) Redis 的兩種持久化方式進(jìn)行了簡要的梳理,分析了 Redis 刪除過期鍵的策略以及對(duì)持久化的影響仪吧。理解了這部分內(nèi)容不僅可以讓我們對(duì) Redis 的使用更加得心應(yīng)手庄新,對(duì)于學(xué)習(xí) Redis 的其它內(nèi)容如復(fù)制的過程也會(huì)很有幫助。

參考

  • 《Redis 實(shí)戰(zhàn)》
  • 《Redis 設(shè)計(jì)與實(shí)現(xiàn)》
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市择诈,隨后出現(xiàn)的幾起案子械蹋,更是在濱河造成了極大的恐慌,老刑警劉巖吭从,帶你破解...
    沈念sama閱讀 217,406評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件朝蜘,死亡現(xiàn)場離奇詭異,居然都是意外死亡涩金,警方通過查閱死者的電腦和手機(jī)谱醇,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來步做,“玉大人副渴,你說我怎么就攤上這事∪龋” “怎么了煮剧?”我有些...
    開封第一講書人閱讀 163,711評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長将鸵。 經(jīng)常有香客問我勉盅,道長,這世上最難降的妖魔是什么顶掉? 我笑而不...
    開封第一講書人閱讀 58,380評(píng)論 1 293
  • 正文 為了忘掉前任草娜,我火速辦了婚禮,結(jié)果婚禮上痒筒,老公的妹妹穿的比我還像新娘宰闰。我一直安慰自己,他們只是感情好簿透,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,432評(píng)論 6 392
  • 文/花漫 我一把揭開白布移袍。 她就那樣靜靜地躺著,像睡著了一般老充。 火紅的嫁衣襯著肌膚如雪葡盗。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,301評(píng)論 1 301
  • 那天蚂维,我揣著相機(jī)與錄音戳粒,去河邊找鬼。 笑死虫啥,一個(gè)胖子當(dāng)著我的面吹牛蔚约,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播涂籽,決...
    沈念sama閱讀 40,145評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼苹祟,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起树枫,我...
    開封第一講書人閱讀 39,008評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤直焙,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后砂轻,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體奔誓,經(jīng)...
    沈念sama閱讀 45,443評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,649評(píng)論 3 334
  • 正文 我和宋清朗相戀三年搔涝,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了厨喂。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,795評(píng)論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡庄呈,死狀恐怖蜕煌,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情诬留,我是刑警寧澤斜纪,帶...
    沈念sama閱讀 35,501評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站文兑,受9級(jí)特大地震影響盒刚,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜绿贞,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,119評(píng)論 3 328
  • 文/蒙蒙 一伪冰、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧樟蠕,春花似錦、人聲如沸靠柑。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,731評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽歼冰。三九已至靡狞,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間隔嫡,已是汗流浹背甸怕。 一陣腳步聲響...
    開封第一講書人閱讀 32,865評(píng)論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留腮恩,地道東北人梢杭。 一個(gè)月前我還...
    沈念sama閱讀 47,899評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像秸滴,于是被迫代替她去往敵國和親武契。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,724評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • 從這篇文章開始,將依次介紹Redis高可用相關(guān)的知識(shí)——持久化咒唆、復(fù)制(及讀寫分離)届垫、哨兵、以及集群全释。 本文將先說明...
    不變甄心閱讀 693評(píng)論 0 4
  • 前言 在上一篇文章中装处,介紹了Redis內(nèi)存模型,從這篇文章開始浸船,將依次介紹Redis高可用相關(guān)的知識(shí)——持久化妄迁、復(fù)...
    Java架構(gòu)閱讀 2,314評(píng)論 3 21
  • 一近哟、Redis高可用概述 在介紹Redis高可用之前迫肖,先說明一下在Redis的語境中高可用的含義。 我們知道旺垒,在w...
    空語閱讀 1,597評(píng)論 0 2
  • 企業(yè)級(jí)redis集群架構(gòu)的特點(diǎn) 海量數(shù)據(jù) 高并發(fā) 高可用 要達(dá)到高可用项戴,持久化是不可減少的形帮,持久化主要是做災(zāi)難恢復(fù)...
    lucode閱讀 2,206評(píng)論 0 7
  • 在布局文件中給edittext的父控件增加兩個(gè)屬性
    柏林billy閱讀 1,618評(píng)論 0 1