<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 的 RDB 持久化

          共 2594字,需瀏覽 6分鐘

           ·

          2021-04-22 05:18

          良心公眾號

          關(guān)注不迷路



          01

          RDB 持久化背景


          在之前的 Redis 的五種基本類型(實(shí)戰(zhàn)篇)和 Redis 的五種基本類型(原理篇)兩篇文章中,我們討論了 Redis 支持的數(shù)據(jù)類型和底層原理,這是對于 Redis 這樣一個鍵值對數(shù)據(jù)庫最為基礎(chǔ)的。由于 Redis 的自身特性,在日常開發(fā)過程中,最常用的場景就是將其作為內(nèi)存數(shù)據(jù)庫來用。


          眾所周知,內(nèi)存 (不包括非易失性內(nèi)存) 是不可靠的,如果不將數(shù)據(jù)持久化到磁盤,在服務(wù)器進(jìn)程退出之后,內(nèi)存中的數(shù)據(jù)將會丟失。


          為了解決上述問題,Redis 提供了 RDB 持久化的能力,該能力可以將 Redis 在內(nèi)存中的數(shù)據(jù)持久化到磁盤,從而防止數(shù)據(jù)丟失。



          02

          RDB 持久化簡介


          Redis 的 RDB 持久化是通過將某一時間點(diǎn)的數(shù)據(jù)庫狀態(tài)保存到 RDB 文件 (經(jīng)過壓縮的二進(jìn)制文件),并將 RDB 文件保存到磁盤中。通過 RDB 文件可以將數(shù)據(jù)還原至生成 RDB 文件的狀態(tài)。



          03

          RDB 持久化命令


          Redis 提供了兩個命令用于生成 RDB 文件,這兩個命令分別是 SAVEBGSAVE。


          SAVE 命令

          SAVE 命令是阻塞式的命令,即在 SAVE 命令執(zhí)行期間,Redis 服務(wù)器進(jìn)程會被阻塞,直到 SAVE 命令執(zhí)行完成,也即 RDB 文件創(chuàng)建完畢為止,在此期間,客戶端發(fā)送至 Redis 服務(wù)器的請求會被拒絕。


          BGSAVE 命令

          BGSAVE 命令是非阻塞式的命令,即執(zhí)行 BGSAVE 命令時,會 fork 子進(jìn)程來異步執(zhí)行 RDB 文件的創(chuàng)建工作,而父進(jìn)程(即 Redis 服務(wù)器進(jìn)程)可以繼續(xù)接收客戶端的請求并進(jìn)行相應(yīng)的處理。但值得一提的是,在 BGSAVE 命令執(zhí)行期間,并不是所有的客戶端請求服務(wù)器都會接收處理。為了避免產(chǎn)生競爭條件, SAVE 命以及新的 BGSAVE 命令,在 BGSAVE 命令執(zhí)行期間都會被拒絕。而出于對性能的考量, BGREWRITEAOF 命令 (用于異步執(zhí)行 AOF 文件重寫) 的執(zhí)行則會被延遲到 BGSAVE 命令執(zhí)行完畢之后。


          自動持久化

          既然 Redis 可以通過 RDB 文件實(shí)現(xiàn)持久化,那么一個比較自然的想法就是,讓 Redis 自動進(jìn)行持久化,而不用經(jīng)常顯式地執(zhí)行 SAVE 或者 BGSAVE 命令。Redis 提供了 save 選項(xiàng)用于配置服務(wù)器的自動持久化。配置方式如下:

          // 100 秒內(nèi)至少進(jìn)行 5 次修改時觸發(fā)自動 RDBsave 100 5


          而由于上文中已經(jīng)提到的,Redis 的 SAVE 命令是阻塞式的,在執(zhí)行期間服務(wù)器會拒絕客戶端的請求,因此,自動持久化背后的機(jī)制實(shí)際上使用的是對客戶端更加友好的 BGSAVE 命令。save 配置可以生效多條。



          04

          RDB 文件結(jié)構(gòu)剖析


          在了解了 Redis 如何 RDB 持久化之后,是時候來看一下 RDB 文件的具體結(jié)構(gòu)了。只有了解了 RDB 文件的結(jié)構(gòu),才能更清楚 RDB 的持久化過程以及數(shù)據(jù)恢復(fù)過程。


          RDB 文件結(jié)構(gòu)如下圖所示:

          從上圖可以看出,Redis 的 RDB 文件結(jié)構(gòu)可以分為如下五個部分:

          • REDIS 是RDB 文件的標(biāo)識,在載入 RDB 文件時,可以通過該標(biāo)識快速判斷該文件是否是 RDB 文件。

          • db_version 是一個長度為 4 個字節(jié)的字符串,它對應(yīng)的整數(shù)值是 RDB 文件的版本號。

          • databases 保存了零個或任意多個數(shù)據(jù)庫,以及數(shù)據(jù)庫中的鍵值對。這一部分內(nèi)容是 RDB 文件的主體。由于該部分可以保存多個數(shù)據(jù)庫以及其中的鍵值對,因此,需要對這一部分內(nèi)容進(jìn)行進(jìn)一步的劃分。對于每一個數(shù)據(jù)庫,它內(nèi)部的結(jié)構(gòu)如下圖所示:

            上圖可以看出,databases 中的每一個數(shù)據(jù)庫內(nèi)部結(jié)構(gòu)可以分為如下三個部分:

            • SELECTDB 是一個長度為 1 個字節(jié)的標(biāo)識,每一個數(shù)據(jù)庫都以 SELECTDB 為起始,不同的數(shù)據(jù)庫之間依靠該標(biāo)識作為分割。

            • db_number 是數(shù)據(jù)庫的號碼,代表接下來要讀的是幾號數(shù)據(jù)庫。

            • key_value_pairs 是 db_number 數(shù)據(jù)庫中所有的鍵值對。


          • EOF 是一個長度為 1 個字節(jié)的標(biāo)識,用于表示 databases 內(nèi)容的結(jié)束。

          • check_sum 是一個長度為 8 個字節(jié)的無符號整數(shù),用于保存該 RDB 文件的校驗(yàn)和,依據(jù)該校驗(yàn)和來檢查和判斷 RDB 文件是否正常。


          至此,我們已經(jīng)了解了 RDB 文件的基本結(jié)構(gòu),Redis 在執(zhí)行 SAVE 命令或者 BGSAVE 命令的時候,就會按照上述的文件結(jié)構(gòu),向磁盤中寫入相應(yīng)的 RDB 文件。



          05

          RDB 持久化的不可靠性


          在了解了 Redis 的 RDB 持久化機(jī)制后,我們會發(fā)現(xiàn)一個問題——RDB 持久化的不可靠問題。這個問題也是面試官經(jīng)??疾斓囊稽c(diǎn)。


          因?yàn)?RDB 文件的寫入并不是實(shí)時的,即便是在配置文件中配置了 save 屬性,在觸發(fā) BGSAVE 命令之前,并不會執(zhí)行 RDB 文件的寫入操作,如果 Redis 服務(wù)進(jìn)程意外退出,此時通過 RDB 文件僅僅能將數(shù)據(jù)庫狀態(tài)恢復(fù)到上一次 RDB 持久化的狀態(tài),在此之后所做的改動將會被丟失,這也就是 RDB 持久化不可靠的根源所在。


          因此,對于數(shù)據(jù)丟失并不敏感的情況下,可以采用 RDB 持久化的方式。而對于數(shù)據(jù)丟失相對比較敏感的情況下,可以采用 Redis 的另外一種持久化的方式——AOF 持久化,在接下來的文章中,將會系統(tǒng)地介紹 AOF 持久化的內(nèi)容,敬請期待!


          綜上所述,本文關(guān)于 Redis 的 RDB 持久化機(jī)制就總結(jié)到這里了。


          歡迎關(guān)注【有理想的菜雞】公眾號,大家一起討論技術(shù),共同成長!



          06

          參考資料


          《Redis 設(shè)計(jì)與實(shí)現(xiàn)》黃健宏 著

          https://github.com/redis/redis

          學(xué)習(xí) | 工作 | 分享

          ??關(guān)注“有理想的菜雞

          只有你想不到,沒有你學(xué)不到
          瀏覽 34
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

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

          手機(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>
                  www视频网站在线操 | 亚洲高清无码一区 | 求一个做爱视频网站免费在线观看 | 成人免费欧美 | 国产精品无码播放1一 |