Redis入門(六):Redis 持久化

https://github.com/Haiyoung/learning-and-preparing-for-interview/blob/master/redis.md

Redis 持久化

  • 什麼是持久化 Redis的數據操作都是在內存中進行的,如果服務掛掉的話,數據會丟失。所謂持久化,就是將redis保存在內存中的數據,異步保存到磁盤上,以便在需要的時候,對數據進行恢復。
  • redis數據持久化方式 快照(RDB); 寫日誌(AOF)
  • Redis 還可以同時使用 AOF 持久化和 RDB 持久化。 在這種情況下, 當 Redis 重啓時, 它會優先使用 AOF 文件來還原數據集, 因爲 AOF 文件保存的數據集通常比 RDB 文件所保存的數據集更完整
  • 持久化功能是可以關閉的,讓數據只在服務器運行時存在

RDB

  • 什麼是RDB

    RDB Redis Database File, 將Redis內存中的數據,完整的生成一個快照,以二進制格式文件(.rdb文件)保存在硬盤當中。當需要進行恢復時,再從硬盤加載到內存中。

    Redis rdbs

  • RDB的觸發方式

    • save(同步)

      Redis rdbs

      • save命令觸發RDB快照持久化,命令會阻塞Redis服務,直至rdb文件生成結束
      • 如果已經存在rdb文件,則新生成的rdb文件會替換舊的rdb文件
    • bgsave(異步)

      Redis rdbs

      • bgsave命令在觸發RDB持久化時,在fork()函數產生子進程的過程中,依然有可能短暫阻塞Redis服務
      • fork()出子進程,會消耗額外的內存,但是基本不會阻塞redis命令
    • config(滿足條件,自動觸發)
      • 在redis配置文件中,添加如下配置,在滿足條件時,會自動觸發RDB快照
      • 一般不推薦配置自動觸發RDB快照的持久化方式
        shell
        # 配置自動生成規則。一般不建議配置自動生成RDB文件
        save 900 1 #900秒內改變1條數據,自動生成RDB文件
        save 300 10 #300秒內改變10條數據,自動生成RDB文件
        save 60 10000 #60秒內改變1萬條數據,自動生成RDB文件
        # 指定rdb文件名
        dbfilename dump.rdb
        # 指定rdb文件目錄
        dir /opt/redis/data
        # bgsave發生錯誤,停止寫入
        stop-writes-on-bgsave-error yes
        # rdb文件採用壓縮格式
        rdbcompression yes
        # 對rdb文件進行校驗
        rdbchecksum yes

AOF

  • 什麼是AOF

    AOF Append Only File, 持久化記錄服務器執行的所有寫操作命令,並在服務器啓動時,通過重新執行這些命令來還原數據集。 AOF 文件中的命令全部以 Redis 協議的格式來保存,新命令會被追加到文件的末尾。 Redis 還可以在後臺對 AOF 文件進行重寫(rewrite),使得 AOF 文件的體積不會超出保存數據集狀態所需的實際大小。
    Redis rdbs

    • 所有的寫入命令會追加到aof_buf(緩衝區)中
    • AOF緩衝區根據配置的策略向硬盤做同步操作
    • 隨着AOF文件越來越大,需要定期對AOF文件進行重寫,重寫可以壓縮AOF文件,也能使文件被更快的加載
    • 當Redis服務重啓時,可以加載AOF文件進行數據恢復
  • 命令寫入
    • Redis執行寫命令,將命令刷新到硬盤緩衝區當中
    • 所有寫入命令都包含追加操作,直接採用協議格式,避免二次處理開銷
  • 緩衝同步
    • always 命令寫入緩衝區後,立即調用同步操作,將寫命令追加到AOF文件,追加完成後,線程返回
    • everysec 讓緩衝區中的數據每秒刷新一次到AOF文件,相比always,在高寫入量的情況下,可以保護硬盤。出現故障可能會丟失一秒數據(這也是AOF的默認策略)
    • no 刷新策略讓操作系統來決定
  • AOF重寫

    • 隨着時間的推移,命令的逐步寫入。AOF文件也會逐漸變大。當我們用AOF來恢復時會很慢,而且當文件無限增大時,對硬盤的管理,對寫入的速度也會有產生影響。Redis當然考慮到這個問題,所以就有了AOF重寫
    • 原生AOF
      shell
      set hello world
      set hello java
      set hello python
      incr counter
      incr counter
      rpush mylist a
      rpush mylist b
      rpush mylist c
      過期數據
    • 重寫後的AOF
      shell
      set hello python
      set counter 2
      rpush mylist a b c
    • AOF重寫的方式

      • bgrewriteaof 類似於RDB快照中,bgsave的執行過程;redis客戶端向Redis發bgrewriteaof命令,redis服務端fork一個子進程去完成AOF重寫。這裏的AOF重寫,是將Redis內存中的數據進行一次回溯,回溯成AOF文件。而不是重寫AOF文件生成新的AOF文件去替換

        Redis rdbs

      • aof重寫配置
        auto-aof-rewrite-min-size:AOF文件重寫需要的尺寸
        auto-aof-rewrite-percentage:AOF文件增長率
        redis提供了aof_current_size和aof_base_size,分別用來統計AOF當前尺寸(單位:字節)和AOF上次啓動和重寫的尺寸(單位:字節)
        AOF自動重寫的觸發時機,同時滿足以下兩點:
      • aof_current_size > auto-aof-rewrite-min-size
      • aof_current_size - aof_base_size/aof_base_size > auto-aof-rewrite-percentage
        
        # 開啓正常AOF的append刷盤操作
        
        appendonly yes
        
        # AOF文件名
        
        appendfilename "appendonly.aof"
        
        # 每秒刷盤
        
        appendfsync everysec
        
        # 文件目錄
        
        dir /opt/redis/data
        
        # AOF重寫增長率
        
        auto-aof-rewrite-percentage 100
        
        # AOF重寫最小尺寸
        
        auto-aof-rewrite-min-size 64mb
        
        # AOF重寫期間是否暫停append操作。AOF重寫非常消耗磁盤性能,而正常的AOF過程中也會往磁盤刷數據。
        
        
        # 通常偏向考慮性能,設爲yes。萬一重寫失敗了,這期間正常AOF的數據會丟失,因爲我們選擇了重寫期間放棄了正常AOF刷盤。
        
        no-appendfsync-on-rewrite yes

持久化最佳策略

  • RDB最佳策略
    • 建議關閉RDB,無論是Redis主節點,還是從節點,都建議關掉RDB。但是關掉不是絕對的,主從複製時還是會藉助RDB
    • 用作數據備份,RDB雖然是很重的操作,但是對數據備份很有作用。文件大小比較小,可以按天或按小時進行數據備份
    • 在極個別的場景下,需要在從節點開RDB,可以再本地保存這樣子的一個歷史的RDB文件。雖然從節點不進行讀寫,但是Redis往往單機多部署,由於RDB是個很重的操作,所以還是會對CPU、硬盤和內存造成一定影響。根據實際需求進行設定
  • AOF最佳策略
    • 建議開啓AOF,如果Redis數據只是用作數據源的緩存,並且緩存丟失後從數據源重新加載不會對數據源造成太大壓力,這種情況下,AOF可以關
    • AOF重寫集中管理,單機多部署情況下,發生大量fork可能會內存爆滿
    • everysec 建議採用每秒刷盤策略

reference

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章