<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          徹底理解 Redis 的持久化和主從復(fù)制

          共 4626字,需瀏覽 10分鐘

           ·

          2020-12-26 13:13



          作者 |?張君鴻

          來(lái)源 |?https://juejin.cn/post/6844903874927525902


          在這篇文章,我們繼續(xù)有關(guān)Redis方面知識(shí)的學(xué)習(xí),一起了解一下其中一個(gè)非常重要的內(nèi)容:Redis的持久化機(jī)制。

          什么是Redis持久化?

          Redis作為一個(gè)鍵值對(duì)內(nèi)存數(shù)據(jù)庫(kù)(NoSQL),數(shù)據(jù)都存儲(chǔ)在內(nèi)存當(dāng)中,在處理客戶端請(qǐng)求時(shí),所有操作都在內(nèi)存當(dāng)中進(jìn)行,如下所示:

          這樣做有什么問(wèn)題呢?

          其實(shí),只要稍微有點(diǎn)計(jì)算機(jī)基礎(chǔ)知識(shí)的人都知道,存儲(chǔ)在內(nèi)存當(dāng)中的數(shù)據(jù),只要服務(wù)器關(guān)機(jī)(各種原因引起的),內(nèi)存中的數(shù)據(jù)就會(huì)消失了,不僅服務(wù)器關(guān)機(jī)會(huì)造成數(shù)據(jù)消失,Redis服務(wù)器守護(hù)進(jìn)程退出,內(nèi)存中的數(shù)據(jù)也一樣會(huì)消失。

          對(duì)于只把Redis當(dāng)緩存來(lái)用的項(xiàng)目來(lái)說(shuō),數(shù)據(jù)消失或許問(wèn)題不大,重新從數(shù)據(jù)源把數(shù)據(jù)加載進(jìn)來(lái)就可以了,但如果直接把用戶提交的業(yè)務(wù)數(shù)據(jù)存儲(chǔ)在Redis當(dāng)中,把Redis作為數(shù)據(jù)庫(kù)來(lái)使用,在其放存儲(chǔ)重要業(yè)務(wù)數(shù)據(jù),那么Redis的內(nèi)存數(shù)據(jù)丟失所造成的影響也許是毀滅性。

          為了避免內(nèi)存中數(shù)據(jù)丟失,Redis提供了對(duì)持久化的支持,我們可以選擇不同的方式將數(shù)據(jù)從內(nèi)存中保存到硬盤當(dāng)中,使數(shù)據(jù)可以持久化保存。

          Redis提供了RDBAOF兩種不同的數(shù)據(jù)持久化方式,下面我們就來(lái)詳細(xì)介紹一下這種不同的持久化方式吧。

          RDB

          RDB是一種快照存儲(chǔ)持久化方式,具體就是將Redis某一時(shí)刻的內(nèi)存數(shù)據(jù)保存到硬盤的文件當(dāng)中,默認(rèn)保存的文件名為dump.rdb,而在Redis服務(wù)器啟動(dòng)時(shí),會(huì)重新加載dump.rdb文件的數(shù)據(jù)到內(nèi)存當(dāng)中恢復(fù)數(shù)據(jù)。

          開(kāi)啟RDB持久化方式

          開(kāi)啟RDB持久化方式很簡(jiǎn)單,客戶端可以通過(guò)向Redis服務(wù)器發(fā)送savebgsave命令讓服務(wù)器生成rdb文件,或者通過(guò)服務(wù)器配置文件指定觸發(fā)RDB條件。

          1. save命令

          save命令是一個(gè)同步操作。

          #?同步數(shù)據(jù)到磁盤上
          >?save?
          復(fù)制代碼

          當(dāng)客戶端向服務(wù)器發(fā)送save命令請(qǐng)求進(jìn)行持久化時(shí),服務(wù)器會(huì)阻塞save命令之后的其他客戶端的請(qǐng)求,直到數(shù)據(jù)同步完成。

          如果數(shù)據(jù)量太大,同步數(shù)據(jù)會(huì)執(zhí)行很久,而這期間Redis服務(wù)器也無(wú)法接收其他請(qǐng)求,所以,最好不要在生產(chǎn)環(huán)境使用save命令。

          2. bgsave

          save命令不同,bgsave命令是一個(gè)異步操作。

          #?異步保存數(shù)據(jù)集到磁盤上
          >?bgsave
          復(fù)制代碼

          當(dāng)客戶端發(fā)服務(wù)發(fā)出bgsave命令時(shí),Redis服務(wù)器主進(jìn)程會(huì)forks一個(gè)子進(jìn)程來(lái)數(shù)據(jù)同步問(wèn)題,在將數(shù)據(jù)保存到rdb文件之后,子進(jìn)程會(huì)退出。

          所以,與save命令相比,Redis服務(wù)器在處理bgsave采用子線程進(jìn)行IO寫入,而主進(jìn)程仍然可以接收其他請(qǐng)求,但forks子進(jìn)程是同步的,所以forks子進(jìn)程時(shí),一樣不能接收其他請(qǐng)求,這意味著,如果forks一個(gè)子進(jìn)程花費(fèi)的時(shí)間太久(一般是很快的),bgsave命令仍然有阻塞其他客戶的請(qǐng)求的情況發(fā)生。

          3. 服務(wù)器配置自動(dòng)觸發(fā)

          除了通過(guò)客戶端發(fā)送命令外,還有一種方式,就是在Redis配置文件中的save指定到達(dá)觸發(fā)RDB持久化的條件,比如【多少秒內(nèi)至少達(dá)到多少寫操作】就開(kāi)啟RDB數(shù)據(jù)同步。

          例如我們可以在配置文件redis.conf指定如下的選項(xiàng):

          #?900s內(nèi)至少達(dá)到一條寫命令
          save?900?1
          #?300s內(nèi)至少達(dá)至10條寫命令
          save?300?10
          #?60s內(nèi)至少達(dá)到10000條寫命令
          save?60?10000
          復(fù)制代碼

          之后在啟動(dòng)服務(wù)器時(shí)加載配置文件。

          #?啟動(dòng)服務(wù)器加載配置文件
          redis-server?redis.conf
          復(fù)制代碼

          這種通過(guò)服務(wù)器配置文件觸發(fā)RDB的方式,與bgsave命令類似,達(dá)到觸發(fā)條件時(shí),會(huì)forks一個(gè)子進(jìn)程進(jìn)行數(shù)據(jù)同步,不過(guò)最好不要通過(guò)這方式來(lái)觸發(fā)RDB持久化,因?yàn)樵O(shè)置觸發(fā)的時(shí)間太短,則容易頻繁寫入rdb文件,影響服務(wù)器性能,時(shí)間設(shè)置太長(zhǎng)則會(huì)造成數(shù)據(jù)丟失。

          rdb文件

          前面介紹了三種讓服務(wù)器生成rdb文件的方式,無(wú)論是由主進(jìn)程生成還是子進(jìn)程來(lái)生成,其過(guò)程如下:

          1. 生成臨時(shí)rdb文件,并寫入數(shù)據(jù)。
          2. 完成數(shù)據(jù)寫入,用臨時(shí)文代替代正式rdb文件。
          3. 刪除原來(lái)的db文件。

          RDB默認(rèn)生成的文件名為dump.rdb,當(dāng)然,我可以通過(guò)配置文件進(jìn)行更加詳細(xì)配置,比如在單機(jī)下啟動(dòng)多個(gè)redis服務(wù)器進(jìn)程時(shí),可以通過(guò)端口號(hào)配置不同的rdb名稱,如下所示:

          #?是否壓縮rdb文件
          rdbcompression?yes

          #?rdb文件的名稱
          dbfilename?redis-6379.rdb

          #?rdb文件保存目錄
          dir?~/redis/
          復(fù)制代碼
          RDB的幾個(gè)優(yōu)點(diǎn)
          1. 與AOF方式相比,通過(guò)rdb文件恢復(fù)數(shù)據(jù)比較快。
          2. rdb文件非常緊湊,適合于數(shù)據(jù)備份。
          3. 通過(guò)RDB進(jìn)行數(shù)據(jù)備,由于使用子進(jìn)程生成,所以對(duì)Redis服務(wù)器性能影響較小。
          RDB的幾個(gè)缺點(diǎn)
          1. 如果服務(wù)器宕機(jī)的話,采用RDB的方式會(huì)造成某個(gè)時(shí)段內(nèi)數(shù)據(jù)的丟失,比如我們?cè)O(shè)置10分鐘同步一次或5分鐘達(dá)到1000次寫入就同步一次,那么如果還沒(méi)達(dá)到觸發(fā)條件服務(wù)器就死機(jī)了,那么這個(gè)時(shí)間段的數(shù)據(jù)會(huì)丟失。
          2. 使用save命令會(huì)造成服務(wù)器阻塞,直接數(shù)據(jù)同步完成才能接收后續(xù)請(qǐng)求。
          3. 使用bgsave命令在forks子進(jìn)程時(shí),如果數(shù)據(jù)量太大,forks的過(guò)程也會(huì)發(fā)生阻塞,另外,forks子進(jìn)程會(huì)耗費(fèi)內(nèi)存。

          AOF

          聊完了RDB,來(lái)聊聊Redis的另外一個(gè)持久化方式:AOF(Append-only file)

          RDB存儲(chǔ)某個(gè)時(shí)刻的快照不同,AOF持久化方式會(huì)記錄客戶端對(duì)服務(wù)器的每一次寫操作命令,并將這些寫操作以Redis協(xié)議追加保存到以后綴為aof文件末尾,在Redis服務(wù)器重啟時(shí),會(huì)加載并運(yùn)行aof文件的命令,以達(dá)到恢復(fù)數(shù)據(jù)的目的。

          開(kāi)啟AOF持久化方式

          Redis默認(rèn)不開(kāi)啟AOF持久化方式,我們可以在配置文件中開(kāi)啟并進(jìn)行更加詳細(xì)的配置,如下面的redis.conf文件:

          #?開(kāi)啟aof機(jī)制
          appendonly?yes

          #?aof文件名
          appendfilename?"appendonly.aof"

          #?寫入策略,always表示每個(gè)寫操作都保存到aof文件中,也可以是everysec或no
          appendfsync?always

          #?默認(rèn)不重寫aof文件
          no-appendfsync-on-rewrite?no

          #?保存目錄
          dir?~/redis/
          復(fù)制代碼
          三種寫入策略

          在上面的配置文件中,我們可以通過(guò)appendfsync選項(xiàng)指定寫入策略,有三個(gè)選項(xiàng)

          appendfsync?always
          #?appendfsync?everysec
          #?appendfsync?no
          復(fù)制代碼
          1. always

          客戶端的每一個(gè)寫操作都保存到aof文件當(dāng),這種策略很安全,但是每個(gè)寫請(qǐng)注都有IO操作,所以也很慢。

          2. everysec

          appendfsync的默認(rèn)寫入策略,每秒寫入一次aof文件,因此,最多可能會(huì)丟失1s的數(shù)據(jù)。

          3. no

          Redis服務(wù)器不負(fù)責(zé)寫入aof,而是交由操作系統(tǒng)來(lái)處理什么時(shí)候?qū)懭?code style="font-size: 14px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(53, 179, 120);background-color: rgba(27, 31, 35, 0.05);word-break: break-all;">aof文件。更快,但也是最不安全的選擇,不推薦使用。

          AOF文件重寫

          AOF將客戶端的每一個(gè)寫操作都追加到aof文件末尾,比如對(duì)一個(gè)key多次執(zhí)行incr命令,這時(shí)候,aof保存每一次命令到aof文件中,aof文件會(huì)變得非常大。

          incr?num?1
          incr?num?2
          incr?num?3
          incr?num?4
          incr?num?5
          incr?num?6
          ...
          incr?num?100000
          復(fù)制代碼

          aof文件太大,加載aof文件恢復(fù)數(shù)據(jù)時(shí),就會(huì)非常慢,為了解決這個(gè)問(wèn)題,Redis支持aof文件重寫,通過(guò)重寫aof,可以生成一個(gè)恢復(fù)當(dāng)前數(shù)據(jù)的最少命令集,比如上面的例子中那么多條命令,可以重寫為:

          set?num?100000
          復(fù)制代碼

          aof文件是一個(gè)二進(jìn)制文件,并不是像上面的例子一樣,直接保存每個(gè)命令,而使用Redis自己的格式,上面只是方便演示。

          兩種重寫方式

          通過(guò)在redis.conf配置文件中的選項(xiàng)no-appendfsync-on-rewrite可以設(shè)置是否開(kāi)啟重寫,這種方式會(huì)在每次fsync時(shí)都重寫,影響服務(wù)器性以,因此默認(rèn)值為no,不推薦使用。

          #?默認(rèn)不重寫aof文件
          no-appendfsync-on-rewrite?no
          復(fù)制代碼

          客戶端向服務(wù)器發(fā)送bgrewriteaof命令,也可以讓服務(wù)器進(jìn)行AOF重寫。

          #?讓服務(wù)器異步重寫追加aof文件命令
          >?bgrewriteaof
          復(fù)制代碼

          AOF重寫方式也是異步操作,即如果要寫入aof文件,則Redis主進(jìn)程會(huì)forks一個(gè)子進(jìn)程來(lái)處理,如下所示:

          重寫aof文件的好處
          1. 壓縮aof文件,減少磁盤占用量。
          2. 將aof的命令壓縮為最小命令集,加快了數(shù)據(jù)恢復(fù)的速度。
          AOF文件損壞

          在寫入aof日志文件時(shí),如果Redis服務(wù)器宕機(jī),則aof日志文件文件會(huì)出格式錯(cuò)誤,在重啟Redis服務(wù)器時(shí),Redis服務(wù)器會(huì)拒絕載入這個(gè)aof文件,可以通過(guò)以下步驟修復(fù)aof并恢復(fù)數(shù)據(jù)。

          1. 備份現(xiàn)在aof文件,以防萬(wàn)一。
          2. 使用redis-check-aof命令修復(fù)aof文件,該命令格式如下:
          #?修復(fù)aof日志文件
          $?redis-check-aof?-fix?file.aof
          復(fù)制代碼
          1. 重啟Redis服務(wù)器,加載已經(jīng)修復(fù)的aof文件,恢復(fù)數(shù)據(jù)。
          AOF的優(yōu)點(diǎn)

          AOF只是追加日志文件,因此對(duì)服務(wù)器性能影響較小,速度比RDB要快,消耗的內(nèi)存較少。

          AOF的缺點(diǎn)
          1. AOF方式生成的日志文件太大,即使通過(guò)AFO重寫,文件體積仍然很大。
          2. 恢復(fù)數(shù)據(jù)的速度比RDB慢。

          選擇RDB還是AOF呢?

          通過(guò)上面的介紹,我們了解了RDB與AOF各自的優(yōu)點(diǎn)與缺點(diǎn),到底要如何選擇呢?

          通過(guò)下面的表示,我們可以從幾個(gè)方面對(duì)比一下RDB與AOF,在應(yīng)用時(shí),要根本自己的實(shí)際需求,選擇RDB或者AOF,其實(shí),如果想要數(shù)據(jù)足夠安全,可以兩種方式都開(kāi)啟,但兩種持久化方式同時(shí)進(jìn)行IO操作,會(huì)嚴(yán)重影響服務(wù)器性能,因此有時(shí)候不得不做出選擇。

          當(dāng)RDB與AOF兩種方式都開(kāi)啟時(shí),Redis會(huì)優(yōu)先使用AOF日志來(lái)恢復(fù)數(shù)據(jù),因?yàn)锳OF保存的文件比RDB文件更完整。

          小結(jié)

          上面講了一大堆Redis的持久化機(jī)制的知識(shí),其實(shí),如果你只是單純把Redis作為緩存服務(wù)器,那么可以完全不用考慮持久化,但是,在如今的大多數(shù)服務(wù)器架構(gòu)中,Redis的單單只是扮演一個(gè)緩存服務(wù)器的角色,還可以作為數(shù)據(jù)庫(kù),保存我們的業(yè)務(wù)數(shù)據(jù),此時(shí),我們則需要好好了解有關(guān)Redis持久化策略的區(qū)別與選擇。


          巨星隕落!2007年圖靈獎(jiǎng)得主Edmund Clarke因感染新冠離世...

          2020-12-25

          微信突然更新,新增了這些功能...

          2020-12-25

          Eclipse 官宣,干掉 VS Code !

          2020-12-25

          2020年Spring Cloud最后一個(gè)大版本發(fā)布!

          2020-12-24

          支持Dubbo接口文檔生成的工具!

          2020-12-24

          36 張圖梳理 Intellij IDEA 常用設(shè)置

          2020-12-23



          掃一掃,關(guān)注我

          知曉前沿科技,領(lǐng)略技術(shù)魅力

          DD自研的滬牌代拍業(yè)務(wù)

          深度交流



          瀏覽 30
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  国产三级日本三级国产三级 | 人人草人人爱 | 自拍偷拍视频网 | 就爱干一区二区三区 | 久久人妻免费视频 |