Redis 持久化

目錄:

  1. RDB
  2. AOF
  3. 持久化恢復(fù)
  4. 問題排查和性能優(yōu)化
    fork 操作
    子進(jìn)程開銷
    AOF 追加阻塞
    單機(jī)多實(shí)例部署
  5. 總結(jié)

1 前言

Redis 相比較于 memcache狼电,多了持久化的功能迎献。而持久化分為 2 種镐躲,一種是 RDB(全量)滥沫,一種是 AOF(增量)对人。

RDB 是舊的模式涛舍,現(xiàn)在基本上都使用 AOF暂筝。當(dāng)然箩言,今天兩個(gè)都會(huì)一起聊聊。

2 RDB

RDB 流程圖:


RDB 特點(diǎn):

  1. RDB 是一種快照模式焕襟,即——保存的是 key value 數(shù)據(jù)內(nèi)容陨收。
  2. RDB 有 2 種持久方式,同步 save 模式和異步 bgsave 模式鸵赖。由于 save 是同步的务漩,所以可以保證數(shù)據(jù)一致性,而 bgsave 則不能它褪。
  3. save 可以在客戶端顯式觸發(fā)饵骨,也可以在 shutdown 時(shí)自動(dòng)觸發(fā);bgsave 可以在客戶端顯式觸發(fā)茫打,也可以通過配置由定時(shí)任務(wù)觸發(fā)居触,也可以在 slave 節(jié)點(diǎn)觸發(fā)。
  4. save 導(dǎo)致 redis 同步阻塞老赤,基本已經(jīng)廢棄轮洋。bgsave 則不會(huì)導(dǎo)致阻塞,但也有缺點(diǎn):在 fork 時(shí)抬旺,需要增加內(nèi)存服務(wù)器開銷弊予,因?yàn)楫?dāng)內(nèi)存不夠時(shí),將使用虛擬內(nèi)存开财,導(dǎo)致阻塞 Redis 運(yùn)行汉柒。所以,需要保證空閑內(nèi)存足夠责鳍。
  5. 默認(rèn)執(zhí)行 shutdown 時(shí)竭翠,如果沒有開啟 AOF,則自動(dòng)執(zhí)行 bgsave薇搁。
  6. 每次的 RDB 文件都是替換的。

關(guān)于優(yōu)化:Redis 會(huì)壓縮 RDB 文件渡八,使用 LZF 算法啃洋,讓最終的 RDB 文件遠(yuǎn)小于內(nèi)存大小传货,默認(rèn)開啟。但會(huì)消耗 CPU宏娄。


RDB 缺點(diǎn):

  1. 無法秒級(jí)持久化问裕。
  2. 老版本 Redis 無法兼容新版本 RDB。

RDB 優(yōu)點(diǎn):

  1. 文件緊湊孵坚,適合備份粮宛,全量復(fù)制場(chǎng)景。例如每 6 小時(shí)執(zhí)行 bgsave卖宠,保存到文件系統(tǒng)之類的巍杈。
  2. Redis 加載 RDB 恢復(fù)數(shù)據(jù)遠(yuǎn)遠(yuǎn)快于 AOF。

3 AOF

由于 RDB 的數(shù)據(jù)實(shí)時(shí)性問題扛伍,AOF(append only file) 是目前 Redis 持久化的主流方式筷畦。

AOF 特點(diǎn):

  1. 默認(rèn)文件名是 appendonly.aof。和 RDB 一樣刺洒,保存在配置中 dir 目錄下鳖宾。
  2. AOF 相比較于 RDB,每次都會(huì)保存命令逆航,數(shù)據(jù)實(shí)時(shí)性更高鼎文。
  3. AOF 由于每次都會(huì)記錄寫命令,文件會(huì)很大因俐,因此需要進(jìn)行優(yōu)化拇惋,稱之為“重寫機(jī)制”(下面詳細(xì)說)。
  4. AOF 每次保存的寫命令都放在一個(gè)緩沖區(qū)女揭,根據(jù)不同的策略(下面詳細(xì)說)同步到磁盤蚤假。

“重寫機(jī)制” 細(xì)節(jié):

  1. fork 子進(jìn)程(類似 bgsave)
  2. 主進(jìn)程會(huì)寫到2個(gè)緩沖區(qū),一個(gè)是原有的 “AOF 緩存區(qū)”吧兔,一個(gè)是專門為子進(jìn)程準(zhǔn)備的 “AOF 重寫緩沖區(qū)”磷仰;
  3. 子進(jìn)程寫到到新的 AOF 文件中,批量的境蔼,默認(rèn) 32m灶平;寫完后通知主進(jìn)程。
  4. 主進(jìn)程把“AOF 重寫緩沖區(qū)”的數(shù)據(jù)寫到新 AOF 文件中箍土。
  5. 將新的 AOF 文件替換老文件逢享。

重寫流程圖:


緩沖區(qū)同步策略,由參數(shù) appendfsync 控制吴藻,一共3種:

  1. always:調(diào)用系統(tǒng) fsync 函數(shù)瞒爬,直到同步到硬盤返回;嚴(yán)重影響 redis 性能
  2. everysec:先調(diào)用 OS write 函數(shù)侧但, 寫到緩沖區(qū)矢空,然后 redis 每秒執(zhí)行一次 OS fsync 函數(shù)。推薦使用這種方式禀横。
  3. no: 只執(zhí)行 write OS 函數(shù)屁药,具體同步硬盤策略由 OS 決定;不推薦柏锄,數(shù)據(jù)不安全酿箭,容易丟失數(shù)據(jù)

4 持久化恢復(fù)

AOF 和 RDB 文件都可以用于服務(wù)器重啟時(shí)的數(shù)據(jù)恢復(fù)趾娃,具體流程如下圖:

從圖中可以看出優(yōu)先加載 AOF缭嫡,當(dāng)沒有 AOF 時(shí)才加載 RDB。當(dāng) AOF 或者 RDB 存在錯(cuò)誤茫舶,則加載失敗械巡。


5 問題排查和性能優(yōu)化

Redis 持久化是影響 Redis 性能的高發(fā)地,也是面試中常問的問題饶氏。

1. fork 操作

當(dāng) Redis 做 RDB 或者 AOF 重寫時(shí)讥耗,必然要進(jìn)行 fork 操作,對(duì)于 OS 來說疹启,fork 都是一個(gè)重量級(jí)操作古程。而且,fork 還會(huì)拷貝一些數(shù)據(jù)喊崖,雖然不會(huì)拷貝主進(jìn)程所有的物理空間挣磨,但會(huì)復(fù)制主進(jìn)程的空間內(nèi)存頁表。對(duì)于 10GB 的 Redis 進(jìn)程荤懂,需要復(fù)制大約 20MB 的內(nèi)存頁表茁裙,因此 fork 操作耗時(shí)跟進(jìn)程總內(nèi)存量息息相關(guān),再加上节仿,如果使用虛擬化技術(shù)晤锥,例如 Xen 虛擬機(jī),fork 會(huì)更加耗時(shí)廊宪。

一個(gè)正常的 fork 耗時(shí)大概在 20毫秒左右矾瘾。為什么呢,假設(shè)一個(gè) Redis 實(shí)例的 OPS 在 5 萬以上箭启,如果 fork 操作耗時(shí)在秒級(jí)壕翩,那么僵拖慢幾萬條命令的執(zhí)行,對(duì)生產(chǎn)環(huán)境影響明顯傅寡。

我們可以在 Info stats 統(tǒng)計(jì)中查詢 latest_fork_usec 指標(biāo)獲取最近一次 fork 操作耗時(shí)放妈,單位微秒北救。

如何優(yōu)化:

  • 優(yōu)先使用物理機(jī)或者高效支持 fork 的虛擬化技術(shù),避免使用 Xen大猛。
  • 控制 redis 實(shí)例最大內(nèi)存扭倾,盡量控制在 10GB 以內(nèi)。
  • 合理配置 Linux 內(nèi)存分配策略挽绩,避免內(nèi)存不足導(dǎo)致 fork 失敗。
  • 降低 fork 的頻率驾中,如適度放寬 AOF 自動(dòng)觸發(fā)時(shí)機(jī)唉堪,避免不必要的全量復(fù)制。

2. 子進(jìn)程開銷

fork 完畢之后肩民,會(huì)創(chuàng)建子進(jìn)程唠亚,子進(jìn)程負(fù)責(zé) RDB 或者 AOF 重寫,這部分過程主要涉及到 CPU持痰,內(nèi)存灶搜,硬盤三個(gè)地方的優(yōu)化。

  • CPU
    寫入文件的過程是 CPU 密集的過程工窍,通常子進(jìn)程對(duì)單核 CPU 利用率接近 90%割卖。
    如何優(yōu)化呢?既然是 CPU 密集型操作患雏,就不要綁定單核 CPU鹏溯,因?yàn)檫@樣會(huì)和父 CPU 進(jìn)行競(jìng)爭(zhēng)。同時(shí)淹仑,不要和其他 CPU 密集型服務(wù)不是在一個(gè)機(jī)器上丙挽。如果部署了多個(gè) Redis 實(shí)例,盡力保證統(tǒng)一時(shí)刻只有一個(gè)子進(jìn)程執(zhí)行重寫工作匀借。

  • 內(nèi)存
    子進(jìn)程通過 fork 操作產(chǎn)生颜阐,占用內(nèi)存大小等同于父進(jìn)程,理論上需要兩倍的內(nèi)存完成持久化操作吓肋,但 Linux 有 copy on write 機(jī)制凳怨,父子進(jìn)程會(huì)共享相同的物理內(nèi)存頁,當(dāng)父進(jìn)程處理寫操作時(shí)蓬坡,會(huì)把要修改的頁創(chuàng)建對(duì)應(yīng)的副本猿棉,而子進(jìn)程在 fork 操作過程中,共享整個(gè)父進(jìn)程內(nèi)存快照屑咳。
    即——如果重寫過程中存在內(nèi)存修改操作萨赁,父進(jìn)程負(fù)責(zé)創(chuàng)建所修改內(nèi)存頁的副本。這里就是內(nèi)存消耗的地方兆龙。
    如何優(yōu)化呢杖爽?盡量保證同一時(shí)刻只有一個(gè)子進(jìn)程在工作敲董;避免大量寫入時(shí)做重寫操作。

  • 硬盤
    硬盤開銷分析:子進(jìn)程主要職責(zé)是將 RDB 或者 AOF 文件寫入硬盤進(jìn)行持久化慰安,勢(shì)必對(duì)硬盤造成壓力腋寨,可通過工具例如 iostat,iotop 等化焕,分析硬盤負(fù)載情況萄窜。

如何優(yōu)化:

  • 不要和其他高硬盤負(fù)載的服務(wù)放在一臺(tái)機(jī)器上,例如 MQ撒桨,存儲(chǔ)查刻。
  • AOF 重寫時(shí)會(huì)消耗大量硬盤 IO,可以開啟配置 no-appendfsync-on-rewrite凤类,默認(rèn)關(guān)閉穗泵。表示在 AOF 重寫期間不做 fsync 操作。
  • 當(dāng)開啟 AOF 的 Redis 在高并發(fā)場(chǎng)景下谜疤,如果使用普通機(jī)械硬盤佃延,每秒的寫速率是 100MB左右,這時(shí)夷磕,Redis 的性能瓶頸在硬盤上履肃,建議使用 SSD。
  • 對(duì)于單機(jī)配置多個(gè) Redis 實(shí)例的情況企锌,可以配置不同實(shí)例分盤存儲(chǔ) AOF 文件榆浓,分?jǐn)傆脖P壓力。

3. AOF 追加阻塞

當(dāng)開啟 AOF 持久化時(shí)撕攒,常用的同步硬盤的策略是“每秒同步” everysec陡鹃,用于平衡性能和數(shù)據(jù)安全性,對(duì)于這種方式抖坪,redis 使用另一條線程每秒執(zhí)行 fsync 同步硬盤萍鲸,當(dāng)系統(tǒng)資源繁忙時(shí),將造成 Redis 主線程阻塞擦俐。

流程圖如下:

通過上圖可以發(fā)現(xiàn):everysec 配置最多可能丟失 2 秒數(shù)據(jù)脊阴,不是 1 秒;如果系統(tǒng) fsync 緩慢蚯瞧,將會(huì)導(dǎo)致 Redis 主線程阻塞影響效率嘿期。

問題定位:

  1. 發(fā)生 AOF 阻塞時(shí),會(huì)輸入日志埋合。用于記錄 AOF fsync 阻塞導(dǎo)致拖慢 Redis 服務(wù)的行為备徐。
  2. 每當(dāng) AOF 追加阻塞事件發(fā)生時(shí),在 info Persistence 統(tǒng)計(jì)中甚颂,aof_delayed_fsync 指標(biāo)會(huì)累加蜜猾,查看這個(gè)指標(biāo)方便定位 AOF 阻塞問題秀菱。
  3. AOF 同步最多運(yùn)行 2 秒的延遲,當(dāng)延遲發(fā)生時(shí)說明硬盤存在性能問題蹭睡,可通過監(jiān)控工具 iotop 查看衍菱,定位消耗 IO 的進(jìn)程。

4. 單機(jī)多實(shí)例部署

Redis 單線程架構(gòu)無法充分利用多核CPU肩豁,通常的做法是一臺(tái)機(jī)器上部署多個(gè)實(shí)例脊串,當(dāng)多個(gè)實(shí)例開啟 AOF 后,彼此之間就會(huì)產(chǎn)生CPU 和 IO 的競(jìng)爭(zhēng)清钥。

如何解決這個(gè)問題呢洪规?

讓所有實(shí)例的 AOF 串行執(zhí)行。

我們通過 info Persistence 中關(guān)于 AOF 的信息寫出 Shell 腳本循捺,然后串行執(zhí)行實(shí)例的 AOF 持久化。

整個(gè)過程如圖:

通過不斷判斷 AOF 的狀態(tài)雄人,手動(dòng)執(zhí)行 AOF 重寫从橘,保證 AOF 不會(huì)存在競(jìng)爭(zhēng)。具體的 Shell 編寫以及 info 信息判斷础钠,可以查看下圖:

6 總結(jié)

本文主要講了 Redis 的持久化相關(guān)功能恰力,持久化一直是影響 Redis 性能的高發(fā)地,也是面試中經(jīng)常被問到的旗吁。包括 RDB 相關(guān)的特定和優(yōu)缺點(diǎn)踩萎,AOF 的優(yōu)缺點(diǎn),事實(shí)上很钓,由于 RDB 的數(shù)據(jù)實(shí)時(shí)性問題香府,目前用 AOF 比較多了。而持久化恢復(fù)也是優(yōu)先 AOF码倦。

關(guān)于持久化的問題排查企孩,就很麻煩了,但無非幾個(gè)方面袁稽,fork 耗時(shí)勿璃,子進(jìn)程的 CPU,內(nèi)存推汽,硬盤開銷补疑,AOF 的同步阻塞,單機(jī)多實(shí)例部署歹撒。

這些優(yōu)化莲组,可以通過前面寫的分析進(jìn)行排查。

引用

《Redis 開發(fā)與運(yùn)維》
《深入分布式緩存》

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末栈妆,一起剝皮案震驚了整個(gè)濱河市胁编,隨后出現(xiàn)的幾起案子厢钧,更是在濱河造成了極大的恐慌,老刑警劉巖嬉橙,帶你破解...
    沈念sama閱讀 218,036評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件早直,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡市框,警方通過查閱死者的電腦和手機(jī)霞扬,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,046評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來枫振,“玉大人喻圃,你說我怎么就攤上這事》嗦耍” “怎么了斧拍?”我有些...
    開封第一講書人閱讀 164,411評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)杖小。 經(jīng)常有香客問我肆汹,道長(zhǎng),這世上最難降的妖魔是什么予权? 我笑而不...
    開封第一講書人閱讀 58,622評(píng)論 1 293
  • 正文 為了忘掉前任昂勉,我火速辦了婚禮,結(jié)果婚禮上扫腺,老公的妹妹穿的比我還像新娘岗照。我一直安慰自己,他們只是感情好笆环,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,661評(píng)論 6 392
  • 文/花漫 我一把揭開白布攒至。 她就那樣靜靜地躺著,像睡著了一般咧织。 火紅的嫁衣襯著肌膚如雪嗓袱。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,521評(píng)論 1 304
  • 那天习绢,我揣著相機(jī)與錄音渠抹,去河邊找鬼。 笑死闪萄,一個(gè)胖子當(dāng)著我的面吹牛梧却,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播败去,決...
    沈念sama閱讀 40,288評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼放航,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了圆裕?” 一聲冷哼從身側(cè)響起广鳍,我...
    開封第一講書人閱讀 39,200評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤荆几,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后赊时,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體吨铸,經(jīng)...
    沈念sama閱讀 45,644評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,837評(píng)論 3 336
  • 正文 我和宋清朗相戀三年祖秒,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了诞吱。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,953評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡竭缝,死狀恐怖房维,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情抬纸,我是刑警寧澤咙俩,帶...
    沈念sama閱讀 35,673評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站湿故,受9級(jí)特大地震影響暴浦,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜晓锻,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,281評(píng)論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望飞几。 院中可真熱鬧砚哆,春花似錦、人聲如沸屑墨。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,889評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽卵史。三九已至战转,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間以躯,已是汗流浹背槐秧。 一陣腳步聲響...
    開封第一講書人閱讀 33,011評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留忧设,地道東北人刁标。 一個(gè)月前我還...
    沈念sama閱讀 48,119評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像址晕,于是被迫代替她去往敵國(guó)和親膀懈。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,901評(píng)論 2 355

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

  • 前言 在上一篇文章中谨垃,介紹了Redis內(nèi)存模型启搂,從這篇文章開始硼控,將依次介紹Redis高可用相關(guān)的知識(shí)——持久化、復(fù)...
    Java架構(gòu)閱讀 2,314評(píng)論 3 21
  • 企業(yè)級(jí)redis集群架構(gòu)的特點(diǎn) 海量數(shù)據(jù) 高并發(fā) 高可用 要達(dá)到高可用胳赌,持久化是不可減少的牢撼,持久化主要是做災(zāi)難恢復(fù)...
    lucode閱讀 2,206評(píng)論 0 7
  • 本文翻譯自官方文檔http://redis.io/topics/persistence 。 Redis 持久化 R...
    六尺帳篷閱讀 1,631評(píng)論 1 15
  • Redis持久化: 提供了多種不同級(jí)別的持久化方式:一種是RDB,另一種是AOF. RDB 持久化可以在指定的時(shí)間...
    不姓馬的小馬哥閱讀 641評(píng)論 0 10
  • Redis 持久化: 常用的兩種持久化 提供了多種不同級(jí)別的持久化方式:一種是RDB,另一種是AOF. RDB 持...
    邊學(xué)邊記閱讀 1,129評(píng)論 0 1