圖解 Redis | 不多說了,這就是 RDB 快照

      網友投稿 685 2025-04-01

      雖說 Redis 是內存數據庫,但是它為數據的持久化提供了兩個技術。分別是「 AOF 日志和 RDB 快照」。

      這兩種技術都會用各用一個日志文件來記錄信息,但是記錄的內容是不同的。

      AOF 文件的內容是操作命令;

      RDB 文件的內容是二進制數據。

      關于 AOF 持久化的原理我在上一篇已經介紹了,今天主要講下 RDB 快照。

      所謂的快照,就是記錄某一個瞬間東西,比如當我們給風景拍照時,那一個瞬間的畫面和信息就記錄到了一張照片。

      所以,RDB 快照就是記錄某一個瞬間的內存數據,記錄的是實際數據,而 AOF 文件記錄的是命令操作的日志,而不是實際的數據。

      因此在 Redis 恢復數據時, RDB 恢復數據的效率會比 AOF 高些,因為直接將 RDB 文件讀入內存就可以,不需要像 AOF 那樣還需要額外執行操作命令的步驟才能恢復數據。

      接下來,就來具體聊聊 RDB 快照 。

      快照怎么用?

      圖解 Redis | 不多說了,這就是 RDB 快照

      要熟悉一個東西,先看看怎么用是比較好的方式。

      Redis 提供了兩個命令來生成 RDB 文件,分別是 save 和 bgsave,他們的區別就在于是否在「主線程」里執行:

      執行了 save 命令,就會在主線程生成 RDB 文件,由于和執行操作命令在同一個線程,所以如果寫入 RDB 文件的時間太長,會阻塞主線程;

      執行了 bgsava 命令,會創建一個子進程來生成 RDB 文件,這樣可以避免主線程的阻塞;

      RDB 文件的加載工作是在服務器啟動時自動執行的,Redis 并沒有提供專門用于加載 RDB 文件的命令。

      Redis 還可以通過配置文件的選項來實現每隔一段時間自動執行一次 bgsava 命令,默認會提供以下配置:

      save 900 1 save 300 10 save 60 10000

      別看選項名叫 sava,實際上執行的是 bgsava 命令,也就是會創建子進程來生成 RDB 快照文件。

      只要滿足上面條件的任意一個,就會執行 bgsava,它們的意思分別是:

      900 秒之內,對數據庫進行了至少 1 次修改;

      300 秒之內,對數據庫進行了至少 10 次修改;

      60 秒之內,對數據庫進行了至少 10000 次修改。

      這里提一點,Redis 的快照是全量快照,也就是說每次執行快照,都是把內存中的「所有數據」都記錄到磁盤中。

      所以可以認為,執行快照是一個比較重的操作,如果頻率太頻繁,可能會對 Redis 性能產生影響。如果頻率太低,服務器故障時,丟失的數據會更多。

      通常可能設置至少 5 分鐘才保存一次快照,這時如果 Redis 出現宕機等情況,則意味著最多可能丟失 5 分鐘數據。

      這就是 RDB 快照的缺點,在服務器發生故障時,丟失的數據會比 AOF 持久化的方式更多,因為 RDB 快照是全量快照的方式,因此執行的頻率不能太頻繁,否則會影響 Redis 性能,而 AOF 日志可以以秒級的方式記錄操作命令,所以丟失的數據就相對更少。

      執行快照時,數據能被修改嗎?

      那問題來了,執行 bgsava 過程中,由于是交給子進程來構建 RDB 文件,主線程還是可以繼續工作的,此時主線程可以修改數據嗎?

      如果不可以修改數據的話,那這樣性能一下就降低了很多。如果可以修改數據,又是如何做到到呢?

      直接說結論吧,執行 bgsava 過程中,Redis 依然可以繼續處理操作命令的,也就是數據是能被修改的。

      那具體如何做到到呢?關鍵的技術就在于寫時復制技術(Copy-On-Write, COW)。

      執行 bgsava 命令的時候,會通過 fork() 創建子進程,此時子進程和父進程是共享同一片內存數據的,因為創建子進程的時候,會復制父進程的頁表,但是頁表指向的物理內存還是一個。

      只有在發生修改內存數據的情況時,物理內存才會被復制一份。

      這樣的目的是為了減少創建子進程時的性能損耗,從而加快創建子進程的速度,畢竟創建子進程的過程中,是會阻塞主線程的。

      所以,創建 bgsave 子進程后,由于共享父進程的所有內存數據,于是就可以直接讀取主線程里的內存數據,并將數據寫入到 RDB 文件。

      當主線程對這些共享的內存數據也都是只讀操作,那么,主線程和 bgsave 子進程相互不影響。

      但是,如果主線程要修改共享數據里的某一塊數據(比如鍵值對 A)時,就會發生寫時復制,于是這塊數據的物理內存就會被復制一份(鍵值對 A'),然后主線程在這個數據副本(鍵值對A')進行修改操作。與此同時,bgsave 子進程可以繼續把原來的數據(鍵值對 A)寫入到 RDB 文件。

      就是這樣,Redis 使用 bgsave 對當前內存中的所有數據做快照,這個操作是由 bgsave 子進程在后臺完成的,執行時不會阻塞主線程,這就使得主線程同時可以修改數據。

      細心的同學,肯定發現了,bgsave 快照過程中,如果主線程修改了共享數據,發生了寫時復制后,RDB 快照保存的是原本的內存數據,而主線程剛修改的數據,是被辦法在這一時間寫入 RDB 文件的,只能交由下一次的 bgsave 快照。

      所以 Redis 在使用 bgsave 快照過程中,如果主線程修改了內存數據,不管是否是共享的內存數據,RDB 快照都無法寫入主線程剛修改的數據,因為此時主線程的內存數據和子線程的內存數據已經分離了,子線程寫入到 RDB 文件的內存數據只能是原本的內存數據。

      如果系統恰好在 RDB 快照文件創建完畢后崩潰了,那么 Redis 將會丟失主線程在快照期間修改的數據。

      另外,寫時復制的時候會出現這么個極端的情況。

      在 Redis 執行 RDB 持久化期間,剛 fork 時,主進程和子進程共享同一物理內存,但是途中主進程處理了寫操作,修改了共享內存,于是當前被修改的數據的物理內存就會被復制一份。

      那么極端情況下,如果所有的共享內存都被修改,則此時的內存占用是原先的 2 倍。

      所以,針對寫操作多的場景,我們要留意下快照過程中內存的變化,防止內存被占滿了。

      RDB 和 AOF 合體

      盡管 RDB 比 AOF 的數據恢復速度快,但是快照的頻率不好把握:

      如果頻率太低,兩次快照間一旦服務器發生宕機,就可能會比較多的數據丟失;

      如果頻率太高,頻繁寫入磁盤和創建子進程會帶來額外的性能開銷。

      那有沒有什么方法不僅有 RDB 恢復速度快的優點和,又有 AOF 丟失數據少的優點呢?

      當然有,那就是將 RDB 和 AOF 合體使用,這個方法是在 Redis 4.0 提出的,該方法叫混合使用 AOF 日志和內存快照,也叫混合持久化。

      如果想要開啟混合持久化功能,可以在 Redis 配置文件將下面這個配置項設置成 yes:

      aof-use-rdb-preamble yes

      混合持久化工作在 AOF 日志重寫過程。

      當開啟了混合持久化時,在 AOF 重寫日志時,fork 出來的重寫子進程會先將與主線程共享的內存數據以 RDB 方式寫入到 AOF 文件,然后主線程處理的操作命令會被記錄在重寫緩沖區里,重寫緩沖區里的增量命令會以 AOF 方式寫入到 AOF 文件,寫入完成后通知主進程將新的含有 RDB 格式和 AOF 格式的 AOF 文件替換舊的的 AOF 文件。

      也就是說,使用了混合持久化,AOF 文件的前半部分是 RDB 格式的全量數據,后半部分是 AOF 格式的增量數據。

      這樣的好處在于,重啟 Redis 加載數據的時候,由于前半部分是 RDB 內容,這樣加載的時候速度會很快。

      加載完 RDB 的內容后,才會加載后半部分的 AOF 內容,這里的內容是 Redis 后臺子進程重寫 AOF 期間,主線程處理的操作命令,可以使得數據更少的丟失。

      推薦閱讀

      圖解 Reids | AOF 持久化

      圖解 Reids | 緩存雪崩、擊穿、傳統

      Redis 任務調度 數據庫

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:音樂重復怎么刪除(如何刪除重復音樂)
      下一篇:如何自如自如添加表格(怎么做自動化表格)
      相關文章
      亚洲av最新在线网址| 中文字幕亚洲图片| 亚洲成AV人片在| 亚洲五月综合缴情在线观看| 亚洲av手机在线观看| 偷自拍亚洲视频在线观看99| 亚洲精品无码永久在线观看男男 | 亚洲欧洲日本在线| 亚洲 小说区 图片区 都市| | 亚洲精品欧美综合四区| 中日韩亚洲人成无码网站| 中文字幕亚洲综合久久综合| 天堂亚洲国产中文在线| 亚洲国产精品嫩草影院| 亚洲高清乱码午夜电影网| 色天使亚洲综合一区二区| 日韩亚洲翔田千里在线| 亚洲?V无码乱码国产精品| 亚洲人成影院在线观看| 国产成人精品曰本亚洲79ren| 亚洲av成人一区二区三区在线观看| 国产成人高清亚洲一区久久| 亚洲国产av无码精品| 国产精品亚洲产品一区二区三区| 国产a v无码专区亚洲av| 在线亚洲97se亚洲综合在线 | 波多野结衣亚洲一级| 亚洲中文字幕无码久久| 亚洲Av永久无码精品一区二区| 日日摸日日碰夜夜爽亚洲| 亚洲精品无码日韩国产不卡?V| 国产亚洲一区区二区在线| 区三区激情福利综合中文字幕在线一区亚洲视频1 | 亚洲av无码乱码国产精品| 亚洲国产精品第一区二区| 亚洲色图黄色小说| 亚洲娇小性色xxxx| 亚洲爆乳少妇无码激情| 亚洲AV无码乱码在线观看牲色 | 亚洲午夜电影在线观看|