Redis奇幻之旅(三)6. 持久化(RDB/AOF)

6. 持久化(RDB/AOF)

? 眾所周知排苍,Redis是個將數(shù)據(jù)存在內(nèi)存的數(shù)據(jù)庫墩崩,當機器宕機的時候數(shù)據(jù)會全部丟失心赶。因此Redis給了兩種持久化方案,即:RDB(Redis DataBase)和 AOF(Append Only File)鲁冯。

? 講點題外話拷沸,相信接觸過Redis的同學或多或少對于Redis的持久化方案有所了解。但是持久化并不是Redis的專屬薯演,也不是內(nèi)存型數(shù)據(jù)的專屬撞芍。當我們的數(shù)據(jù)需要備份的時候其實都需要持久化方案(可能不叫”持久化“而是叫”備份“),例如:雙機熱備涣仿、主從備份勤庐、跨機房備份等等。其實所謂持久化就是一份數(shù)據(jù)在發(fā)生意外情況時能夠有另一份備份數(shù)據(jù)來繼續(xù)支持外部使用好港。當然在整個過程中必然會出現(xiàn)源數(shù)據(jù)和備份數(shù)據(jù)不一致的情況愉镰。無需去糾結(jié)如何才能做到數(shù)據(jù)完全一致,而是要考慮真實的需求和技術(shù)之間的結(jié)合钧汹。

6.1 RDB

? RDB持久化其實就是快照丈探。顧名思義,就像我們拍照時拔莱,照片會記錄我們某一瞬間的圖像碗降;而快照會記錄我們某一瞬間的數(shù)據(jù)。

6.1.1 SAVE & BGSAVE

? Redis可以使用SAVE命令和BGSAVE命令來將內(nèi)存中的數(shù)據(jù)刷到磁盤中塘秦。

? 當執(zhí)行SAVE命令時讼渊,Redis服務(wù)器會被阻塞,由于Redis是單工作線程模型的尊剔,這時客戶端發(fā)送的所有命令都會被阻塞爪幻。所以一般情況我們不會執(zhí)行SAVE命令。

? BGSAVE就很好的規(guī)避了SAVE阻塞線程的情況须误,因為當調(diào)用BGSAVE的時候Redis會調(diào)用glibc的函數(shù)fork產(chǎn)生一個子進程挨稿,然后由這個子進程來實現(xiàn)快照持久化。這里會使用Linux操作系統(tǒng)的cow機制(在<1.4.4 Rehash>中提到過cow機制)來節(jié)省內(nèi)存資源京痢。

6.1.2 RDB對過期健的處理

? 由于Redis采用了惰性刪除奶甘,所以內(nèi)存中可能存在一些過期了但未被刪除的數(shù)據(jù),當執(zhí)行SAVE或BGSAVE的時候程序會對數(shù)據(jù)庫里的key進行檢查祭椰,如果key已過期則不會保存到新創(chuàng)建的RDB文件中臭家。

6.1.3 RDB文件載入數(shù)據(jù)庫

? 在啟動Redis服務(wù)器時,如果服務(wù)器開啟了RDB功能方淤,那么服務(wù)器將對RDB文件進行載入侣监,載入期間服務(wù)器會一直處于阻塞狀態(tài),當載入完成后服務(wù)器才能對外提供服務(wù)臣淤。

注意:

  • 如果同時開啟了RDB和AOF橄霉,那么只會載入AOF,并不會載入RDB。

  • 如果服務(wù)器以主服務(wù)器模式運行姓蜂,RDB文件中的過期鍵會被丟棄按厘。

  • 如果服務(wù)器以從服務(wù)器模式運行,RDB文件中的過期健仍然會被加載到

6.1.4 RDB配置

redis.conf文件中saveparams的默認配置:

save 900    1
save 300   10
save  60  10000

具體的含義是钱慢,有以下三個條件之一逮京,BGSAVE就會被執(zhí)行:

  • 在900秒之內(nèi),對數(shù)據(jù)庫進行了至少1次修改

  • 在300秒之內(nèi)束莫,對數(shù)據(jù)庫進行了至少10次修改

  • 在60秒之內(nèi)懒棉,對數(shù)據(jù)庫進行了至少10000次修改

redisServer結(jié)構(gòu)體中會保存dirty(修改計數(shù)器)和lastsave(上一次執(zhí)行保存的時間)來實現(xiàn)具體的判斷。

6.2 AOF

? AOF持久化其實就是命令執(zhí)行日志览绿。它是連續(xù)增量的策严,內(nèi)部具體內(nèi)容滿足Redis通信協(xié)議。(具體RESP可在<3.3 redis的通信協(xié)議>中查看)

6.2.1 AOF原理

AOF持久化功能的實現(xiàn)大致分為命令追加饿敲、文件寫入妻导、文件同步三個步驟。

  • 命令追加:當Redis服務(wù)器執(zhí)行完一個命令之后怀各,會以RESP格式追加到aof_buf緩沖區(qū)的末尾

  • 文件寫入:服務(wù)器每次結(jié)束一個事件循環(huán)之前倔韭,都會調(diào)用flushAppendOnlyFile來將aof_buf中的內(nèi)容寫到AOF文件。

  • 文件同步:將寫入AOF緩沖區(qū)的數(shù)據(jù)同步到磁盤上瓢对。

寫入(write)和同步(fsync)其實是操作系統(tǒng)為了提高效率設(shè)置的一個機制寿酌,當調(diào)用write的時候,系統(tǒng)會將數(shù)據(jù)暫時保存在內(nèi)存緩沖區(qū)硕蛹,當緩沖區(qū)空間被填滿或者超過了指定的時間醇疼,數(shù)據(jù)才會被真正寫到磁盤上。這樣的機制雖然提高了寫入效率但帶來了宕機數(shù)據(jù)丟失的風險妓美,為此系統(tǒng)提供了fsync和fdatasync兩個同步函數(shù),可以讓緩沖區(qū)的數(shù)據(jù)立即寫到磁盤中鲤孵。

小提示:在Redis4.0之后AOF Sync的操作被移到一個獨立異步的線程去做壶栋,防止阻塞主線程。

配置文件中有對fsync各級別的詳細說明(默認超1秒同步一次):

# The fsync() call tells the Operating System to actually write data on disk
# instead of waiting for more data in the output buffer. Some OS will really flush
# data on disk, some other OS will just try to do it ASAP.
#
# Redis supports three different modes:
#
# no: don't fsync, just let the OS flush the data when it wants. Faster.
# always: fsync after every write to the append only log. Slow, Safest.
# everysec: fsync only one time every second. Compromise.
#
# The default is "everysec", as that's usually the right compromise between
# speed and data safety. It's up to you to understand if you can relax this to
# "no" that will let the operating system flush the output buffer when
# it wants, for better performances (but if you can live with the idea of
# some data loss consider the default persistence mode that's snapshotting),
# or on the contrary, use "always" that's very slow but a bit safer than
# everysec.
#
# More details please check the following article:
# http://antirez.com/post/redis-persistence-demystified.html
#
# If unsure, use "everysec".

# appendfsync always
appendfsync everysec
# appendfsync no

6.2.2 AOF重寫

? 隨著Redis對外提供服務(wù)的時間增長普监,必然會導致AOF文件越來越大贵试,不論是對于宿主機器的磁盤資源還是AOF重放來說,都不是一件好事凯正。所以為了保證資源合理使用毙玻、服務(wù)正常運行,AOF有一個重寫功能廊散,重寫完之后的AOF不會浪費空間桑滩,保證數(shù)據(jù)完整性的前提下使得新AOF文件體積小于原AOF文件。

整個AOF重寫和原AOF文件半毛錢關(guān)系沒有允睹,簡單來說就分了三步:

  • 新建一個AOF文件重寫文件运准。
  • 保存一份當前Redis數(shù)據(jù)庫的快照放在重寫文件頭部幌氮。
  • 將新產(chǎn)生的日志append到重寫文件中,替換原AOF文件胁澳。

6.2.3 AOF重寫觸發(fā)機制

Redis觸發(fā)AOF重寫的機制有三種:

  • Redis服務(wù)器接收到客戶端發(fā)送的BGREWRITEAOF指令請求该互,如果當前AOF/RDB數(shù)據(jù)持久化沒有在執(zhí)行,那么就執(zhí)行BGREWRITEAOF命令韭畸,否則Redis會等當前AOF/RDB數(shù)據(jù)持久化結(jié)束后再執(zhí)行宇智。

  • 用戶設(shè)置”config set appendonly yes“開啟AOF的時,調(diào)用startAppendOnly函數(shù)會觸發(fā)AOF重寫胰丁。

  • 在Redis配置文件redis.conf中随橘,用戶設(shè)置了auto-aof-rewrite-percentage(默認100)和auto-aof-rewrite-min-size(默認64mb)參數(shù),并且當前AOF文件大小server.aof_current_size大于auto-aof-rewrite-min-size(server.aof_rewrite_min_size)隘马,同時AOF文件大小的增長率大于auto-aof-rewrite-percentage(server.aof_rewrite_perc)時太防,會自動觸發(fā)AOF重寫。

以下為配置文件中的說明:

# Automatic rewrite of the append only file.
# Redis is able to automatically rewrite the log file implicitly calling
# BGREWRITEAOF when the AOF log size grows by the specified percentage.
#
# This is how it works: Redis remembers the size of the AOF file after the
# latest rewrite (if no rewrite has happened since the restart, the size of
# the AOF at startup is used).
#
# This base size is compared to the current size. If the current size is
# bigger than the specified percentage, the rewrite is triggered. Also
# you need to specify a minimal size for the AOF file to be rewritten, this
# is useful to avoid rewriting the AOF file even if the percentage increase
# is reached but it is still pretty small.
#
# Specify a percentage of zero in order to disable the automatic AOF
# rewrite feature.

auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
禁止轉(zhuǎn)載酸员,如需轉(zhuǎn)載請通過簡信或評論聯(lián)系作者蜒车。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市幔嗦,隨后出現(xiàn)的幾起案子酿愧,更是在濱河造成了極大的恐慌,老刑警劉巖邀泉,帶你破解...
    沈念sama閱讀 211,639評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件嬉挡,死亡現(xiàn)場離奇詭異,居然都是意外死亡汇恤,警方通過查閱死者的電腦和手機庞钢,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,277評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來因谎,“玉大人基括,你說我怎么就攤上這事〔撇恚” “怎么了风皿?”我有些...
    開封第一講書人閱讀 157,221評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長匠璧。 經(jīng)常有香客問我桐款,道長,這世上最難降的妖魔是什么夷恍? 我笑而不...
    開封第一講書人閱讀 56,474評論 1 283
  • 正文 為了忘掉前任魔眨,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘冰沙。我一直安慰自己侨艾,他們只是感情好,可當我...
    茶點故事閱讀 65,570評論 6 386
  • 文/花漫 我一把揭開白布拓挥。 她就那樣靜靜地躺著唠梨,像睡著了一般。 火紅的嫁衣襯著肌膚如雪侥啤。 梳的紋絲不亂的頭發(fā)上当叭,一...
    開封第一講書人閱讀 49,816評論 1 290
  • 那天,我揣著相機與錄音盖灸,去河邊找鬼蚁鳖。 笑死,一個胖子當著我的面吹牛赁炎,可吹牛的內(nèi)容都是我干的醉箕。 我是一名探鬼主播,決...
    沈念sama閱讀 38,957評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼徙垫,長吁一口氣:“原來是場噩夢啊……” “哼讥裤!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起姻报,我...
    開封第一講書人閱讀 37,718評論 0 266
  • 序言:老撾萬榮一對情侶失蹤己英,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后吴旋,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體损肛,經(jīng)...
    沈念sama閱讀 44,176評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,511評論 2 327
  • 正文 我和宋清朗相戀三年荣瑟,在試婚紗的時候發(fā)現(xiàn)自己被綠了治拿。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,646評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡笆焰,死狀恐怖劫谅,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情仙辟,我是刑警寧澤同波,帶...
    沈念sama閱讀 34,322評論 4 330
  • 正文 年R本政府宣布鳄梅,位于F島的核電站叠国,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏戴尸。R本人自食惡果不足惜粟焊,卻給世界環(huán)境...
    茶點故事閱讀 39,934評論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧项棠,春花似錦悲雳、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,755評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至透典,卻和暖如春晴楔,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背峭咒。 一陣腳步聲響...
    開封第一講書人閱讀 31,987評論 1 266
  • 我被黑心中介騙來泰國打工税弃, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人凑队。 一個月前我還...
    沈念sama閱讀 46,358評論 2 360
  • 正文 我出身青樓则果,卻偏偏與公主長得像,于是被迫代替她去往敵國和親漩氨。 傳聞我的和親對象是個殘疾皇子西壮,可洞房花燭夜當晚...
    茶點故事閱讀 43,514評論 2 348

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