日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

redis学习笔记-持久化

發布時間:2025/5/22 编程问答 19 豆豆
生活随笔 收集整理的這篇文章主要介紹了 redis学习笔记-持久化 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

redis學習筆記-持久化

前言

redis持久化有兩種方式:RDB和AOF。分別對應著全量復制和增量復制。深刻理解各自的實現方式及適用場景對redis的使用和運維十分重要。下面就分別介紹。

RDB持久化

RDB持久化即將當前Redis實例中的數據快照全部保存的磁盤的過程??墒謩佑|發,也可根據配置自動觸發。

手動觸發

手動觸發有兩個命令可以選擇: save和bgsave。兩者區別在于save是阻塞的,復制完成前會阻塞客戶端命令執行,目前已經廢棄。bgsave是非阻塞的。執行過程中redis進程會fork出一個子進程負責復制任務,而主進程依然響應客戶端請求命令。對應bgsave命令,阻塞只存在于fork過程中。大大減小了阻塞的時間。

如圖,上次rdb同步時間在17:20

執行命令bgsave后, 返回 Background saving started ,

查看rdb文件更新時間,已變為當前時間。

自動觸發

若使用自動觸發,需配置save參數。格式 save m n。查看redis配置文件可看到相關配置。

save 900 1save 300 10save 60 10000復制代碼

配置 save m n 含義為當數據在m秒內發生n次修改,自動執行bgsave命令進行RDB持久化。如save 900 1 表示在900秒(15分鐘內)數據有至少1次修改,則觸發RDB。多個配置情況下,只要符合任一條件即可。

具體在實現上,redis服務器會記錄自上次RDB備份后,有多少次修改。每100ms檢查一次,看是否有符合條件的save配置,有則再次執行DRB.

另外,當在客戶端執行關閉服務器命令shutdown,若redis沒有開啟AOF,則自動執行bgsave進行備份。

RDB流程

由于save的持久化命令會發送阻塞,所以目前基本是用bgsave命令觸發的RDB,關于bgsave的流程如下圖所示。

簡要流程如下

  • redis進程(即圖中主進程)收到bgsave命令后,調用fork命令創建子進程。期間主進程是阻塞的(圖中1,2)。
  • 主進程創建子進程完成后,返回Background saving started,不再阻塞,照常響應客戶端命令。(圖中3)
  • 子進程開啟RDB復制任務,根據主進程內存快照進行備份。(圖4)
  • 子進程完成后通知主進程,RDB任務完成。(圖5)
  • 簡要來說是父進程fork出了一個子進程用于持久化任務,父進程仍響應客戶端請求,耗時的RDB讓子進程來做。這樣的確可以大大減少阻塞時間,可有一個問題是,主進程還在接受請求,子進程怎樣進行復制?難道子進程再復制一份主進程的內存用于復制,這樣內存豈不是要翻倍?肯定不能這樣。要是子進程共享父進程的內存,那怎樣保證邊接受請求邊復制呢?

    事實上,fork操作使用寫時復制(copy-on-write)技術實現。創建的子進程共享父進程地址空間,當只有需要寫入時才會復制地址空間。也就是說,redis的子進程使用共享的內存快照完成RDB備份,而主進程當收到寫請求后,會將涉及到的內存頁復制出一份副本,在此副本進行修改。當子進程RDB完成后,通知主進程更換副本,RDB就此完成。

    RDB參數設置及注意點

  • RDB文件路徑由dir設置,文件名由dbfilename指定。RDB文件為二進制文件,可開啟壓縮處理,壓縮后文件體積可大大縮小。使用rdbcompression參數指定,默認為yes。
  • RDB文件表示某時刻的redis內存快照,文件也相對較小,適用于備份,全量復制等場景。不適合實時持久化。
  • 以下是redis配置文件有關rdb的默認配置

    ## 是否開啟rdb文件壓縮 rdbcompression yes## rdb文件效驗 rdbchecksum yes## rdb文件名 dbfilename redis-dump-127.0.0.1-6379.rdb## 備份文件儲存目錄 dir /usr/local/var/db/redis/復制代碼

    AOF持久化

    AOF主要用于解決redis實時持久化的問題。方式為實時將redis所有寫命令記錄下來,用于以后恢復及備份。

    開啟AOF

    aof默認是關閉的,使用appendonly yes開啟。用appendfilename設置aof文件名。同rdb一樣,dir表示aof儲存目錄。

    在配置文件設好后重啟redis,即開啟了aof功能。可使用info persistence可查看redis持久化的參數,如下

    aof_enabled:1

    表示已開啟aof功能。

    AOF流程

    AOF寫入日志的直接就是文本格式。如set hello world這個命令,在appendonly.aof文件中儲存的就是

    *3 $3 SET $5 hello $5 world 復制代碼

    這就是Redis客戶端與服務器通信的的序列化協議(RESP),每行用\r\n分割,*n表示參數個數,$n表示字節數,十分簡單明了。AOF直接使用協議格式可讓redis直接識別。無需特殊處理,避免二次處理的開銷,也方便修改。

    AOF的流程如下

  • 每當遇到寫命令時,執行完命令后,會將此命令再寫入一個由AOF維護的緩存區(aof_buf)。
  • AOF緩沖區根據指定策略將數據刷到硬盤保存落地。
  • 用流程圖表示就是

    為什么不直接將命令寫入磁盤很容易理解,這里需關注的是以什么策略從緩沖區寫到磁盤。redis提供了3種策略。

    策略說明
    always每次命令寫入緩沖區后都同步刷新到硬盤(使用fsync命令刷新磁盤),此方式最安全,但也是最慢的,因為每次寫數據都要同步硬盤
    everysec每次寫命令調用系統命令write操作,write只會將數據寫入系統緩沖區,然后由專門的線程每秒同步刷盤
    no每次寫命令調用系統命令write操作寫入系統緩沖區,具體刷盤時間由操作系統決定,性能是最高的,但數據安全性不能保證

    通常,我們選擇everysec作為刷盤策略,也是redis默認配置,可以兼顧性能和數據安全。

    AOF追加阻塞

    一般我們使用everysec的同步刷盤策略。此時會有一個專門的線程每秒執行一次刷盤操作。為保證數據安全性,redis主進程會比對上次刷盤時間與當前時間的差值,如果大于2秒,則阻塞以等待刷盤完成。

    也就是說,如果硬盤性能很差,fsync執行太慢,會造成redis阻塞。以保證硬盤的數據不被真實內存數據落的太遠(最大2秒的數據差)。

    AOF重寫機制

    剛才提到,AOF直接使用redis的序列化協議進行備份,一段時間后,aof文件會很大。為解決此問題,可配置aof重寫機制對原aof文件進行瘦身。

    AOF重寫的實質即把redis進程的內存數據轉為寫命令重新生成一份aof文件,以替代原aof文件。

    重寫后比原aof體積小的原因有以下幾點

  • 過期數據不再寫入
  • 命令可合并(hset k1 f1 v1,hset k1 f2 v2可合并hmset k1 f1 v1 f2 v2)
  • 重寫直接使用內存數據生成,一些無效命令就不會再寫入了。(如set hello a, set hello b等)
  • 觸發方式

    AOF可有手動觸發和自動觸發。

    手動觸發使用bgrewriteaof命令觸發。

    自動觸發有關參數及含義如下

    ## aof重寫時此時aof文件與上次aof文件大小百分比 auto-aof-rewrite-percentage 100## aof重寫時文件最小大小,默認64M auto-aof-rewrite-min-size 64mb復制代碼

    如按默認配置,則發生重寫的條件為aof文件大于64M且此時aof文件比上次重寫時大100%,即是上次的2倍。

    重寫流程

  • redis主進程收到aof重寫命令(bgwriteaof),fork出子進程用于執行aof重寫流程(圖中1,2)。
  • 主進程繼續接收客戶端請求,將請求寫入aof_buf緩沖區。保證原有aof流程正常工作(圖中3.1.1和3.1.2)。
  • 同時,主進程還會將寫命令寫入aof_rewrite_aof(aof重寫緩沖區),用于補償aof重寫期間丟失的命令(圖中3.2)。
  • 子進程與此同時進行aof重寫過程(圖中3.3)
  • 子進程完成aof重寫后信號通知主進程(圖中4)
  • 主進程收到子進程完成信號后,將aof_rewrite_aof的命令寫入新aof文件(圖中5)
  • 新aof文件原子替換舊aof文件,aof重寫流程結束(圖中6)。
  • aof重寫雖然比較復雜,但對比圖,也能很容易明白其中流程。這這里有個疑問是為什么主進程在子進程重寫時為什么要維護兩個緩沖區?只維護一個不行嗎?畢竟原有aof文件等到新aof文件生成后也是要替換的。

    仔細想想就可知,有必要維護兩個緩沖區。主要是需要維護原有aof邏輯不變,以防aof重寫失敗導致數據丟失。另一點兩個緩沖區目的也不同,不宜混淆。

    注意:

    為防止資源過于競爭,同一時刻只能進行一個AOF重寫任務,當進行重寫時發現有RDB任務時,也會等RDB完成后進行。

    RDB與AOF

    加載順序

    在重啟時,redis會首先判斷是否開啟aof,若開啟aof且aof文件存在,則加載aof文件進行數據恢復以啟動。否則判斷rdb文件存在并加載rdb以啟動。

    性能開銷

    在進行RDB備份或是AOF重寫時,都需要fork出子進程運行任務。此期間會大量消耗CPU,通常子進程對單核CPU的利用率達到90%,因此在有RDB或需AOF重寫任務的redis,不要做綁定單核CPU操作,這會導致父子進程對CPU產生競爭。

    RDB與AOF比較

  • RDB是全量復制的持久化方式,一次性生成內存快照,產生二進制文件。文件讀取速度快,生成較慢。適用于數據冷備。
  • AOF通過追加生成持久化文件,體積較大,用于數據實時備份。
  • redis阻塞的場景在fork子進程和AOF的追加阻塞階段。
  • 參考文章

  • Redis開發與運維
  • Redis設計與實現
  • Linux進程管理——fork()和寫時復制
  • 總結

    以上是生活随笔為你收集整理的redis学习笔记-持久化的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。