Redis的數據是如何持久化的?

Redis的數據是如何持久化的?redis

  • 一種是RDB方式、
    • 則「定時」將內存中的數據存儲在硬盤上
  • 另外一種是AOF(append-only-file)方式。
    • 在每次執行命令後將命令自己記錄下來
  • 兩種持久化方式能夠單獨使用其中一種,
    • 也能夠將這兩種方式結合使用

RDB方式vim

  • 當符合必定條件時,
    • Redis會單首創建(fork)一個子進程來進行持久化,
    • 會先將數據寫入到一個臨時文件中,等到持久化過程都結束了,
    • 再用這個臨時文件替換上次持久化好的文件。
  • 整個過程當中,主進程是不進行任何IO操做的,
    • 這就確保了極高的性能。
  • RDB的缺點是最後一次持久化後的數據可能丟失
  • --fork的做用是複製一個與當前進程同樣的進程。

Redis會在如下幾種狀況下對數據進行快照緩存

  • 根據配置規則進行自動快照
    • Redis容許用戶自定義快照條件,
      • 當符合快照條件時,Redis會自動執行快照操做
    • 配置格式以下:
      • save 900 1
        • 第一個參數是時間窗口,第二個是鍵的個數
        • 在900秒(15分)內有一個以上的鍵被更改則進行快照。
        • 每條快照規則佔一行,每條規則之間是「或」的關係
  • 用戶執行SAVE或者GBSAVE命令
    • 當咱們對服務進行重啓或者服務器遷移咱們須要人工去幹預備份
    • redis提供了兩條命令來完成這個任務
      • save命令
        • 當執行save命令時,Redis同步作快照操做,
          • 在快照執行過程當中會阻塞全部來自客戶端的請求。
        • 當redis內存中的數據較多時,
          • 經過該命令將致使Redis較長時間的不響應。
          • 因此不建議在生產環境上使用這個命令,
          • 而是推薦使用bgsave命令
      • bgsave命令
        • bgsave命令能夠在後臺異步地進行快照操做,
          • 快照的同時服務器還能夠繼續響應來自客戶端的請求
          • 執行BGSAVE後,Redis會當即返回ok表示開始執行快照操做
    • 經過LASTSAVE命令能夠獲取最近一次成功執行快照的時間;
      • 自動快照採用的是異步快照操做
  • 執行FLUSHALL命令
    • 會清除redis在內存中的全部數據
    • 執行該命令後,只要redis中配置的快照規則不爲空,也就是save 的規則存在。
      • redis就會執行一次快照操做。
      • 無論規則是什麼樣的都會執行。
      • 若是沒有定義快照規則,就不會執行快照操做
  • 執行復制(replication)時
    • 在主從模式下,redis會在複製初始化時進行自動快照。
    • 這裏只須要了解當執行復制操做時
      • 即便沒有定義自動快照規則,而且沒有手動執行過快照操做,
      • 它仍然會生成RDB快照文件

AOF方式服務器

  • 當使用Redis存儲非臨時數據時,
    • 通常須要打開AOF持久化來下降進程終止致使的數據丟失。
  • AOF能夠將Redis執行的每一條寫命令追加到硬盤文件中,
    • 這一過程會下降Redis的性能,
    • 但大部分狀況下這個影響是可以接受的,
    • 另外使用較快的硬盤能夠提升AOF的性能
  • 開啓AOF
    • 默認狀況下Redis沒有開啓AOF
    • 能夠經過appendonly參數啓用,
      • 在redis.conf 中找到 appendonly yes
    • 開啓AOF持久化後
      • 每執行一條會更改Redis中的數據的命令後
        • Redis就會將該命令寫入硬盤中的AOF文件。
  • AOF文件的保存位置和RDB文件的位置相同,
    • 都是經過dir參數設置的,
      • 默認的文件名是apendonly.aof.
    • 能夠在redis.conf中的屬性 appendfilename  appendonlyh.aof修改
  • AOF的實現
    • AOF文件以純文本的形式記錄Redis執行的寫命令
    • 經過vim的方式能夠看到aof文件中的內容
      • set foo 1
        set foo 2
        set foo 3
        get
      • 從內容中咱們發現Redis只記錄了3 條命令
        • get 未記錄
      • 這時有一個問題是前面2條命令實際上是冗餘的
      • 隨着執行的命令愈來愈多,AOF文件的大小也會愈來愈大,
        • 其實內存中實際的數據可能沒有多少
      • 所以咱們但願Redis能夠自動優化AOF文件
      • 實際上Redis也考慮到了,能夠配置一個條件,
        • 每當達到必定條件時Redis就會自動重寫AOF文件,
        • 這個條件的配置問 auto-aof-rewrite-percentage 100 auto-aof-rewrite-min-size 64mb
        • auto-aof-rewrite-percentage
          • 表示的是當目前的AOF文件大小
          • 超過上一次重寫時的AOF文件大小的百分之多少時
          • 會再次進行重寫,若是以前沒有重寫過,
          • 則以啓動時AOF文件大小爲依據
        • auto-aof-rewrite-min-size
          • 表示限制了容許重寫的最小AOF文件大小,
          • 一般在AOF文件很小的狀況下
            • 即便其中有不少冗餘的命令咱們也並不太關心。
      • BGREWRITEAOF 命令手動執行AOF,
        • 執行完之後冗餘的命令已經被刪除了
        • 在啓動時,Redis會逐個執行AOF文件中的命令來將硬盤中的數據載入到內存中,
          • 載入的速度相對於RDB會慢一些

AOF的重寫原理app

  • 重寫後的新 AOF 文件包含了恢復當前數據集所需的最小命令集合。
  • 重寫的流程是這樣,
    • 主進程會fork一個子進程出來進行AOF重寫,
    • 這個重寫過程並不是基於原有的aof文件來作的,
      • 而是有點相似於快照的方式,全量遍歷內存中的數據,
      • 而後逐個序列到aof文件中。
    • 在fork子進程這個過程當中,服務端仍然能夠對外提供服務
      • 這個過程當中,主進程的數據更新操做,會緩存到aof_rewrite_buf中,
        • 也就是單獨開闢一塊緩存來存儲重寫期間收到的命令,
        • 當子進程重寫完之後再把緩存中的數據追加到新的aof文件。
      • 當全部的數據所有追加到新的aof文件中後,把新的aof文件重命名,
        • 此後全部的操做都會被寫入新的aof文件。
      • 若是在rewrite過程當中出現故障,不會影響原來aof文件的正常工做,
        • 只有當rewrite完成後纔會切換文件。
        • 所以這個rewrite過程是比較可靠的
相關文章
相關標籤/搜索