1. 程式人生 > 其它 >13.redis持久化-RDB

13.redis持久化-RDB

reids的持久化是重點

reids是記憶體資料庫,如果不講記憶體中的資料儲存到磁碟上,那麼服務一旦出了問題,伺服器中的資料庫狀態也會消失,所以redis提供了持久化!

RDB

在指定的時間間隔內將記憶體中的資料集快照寫入磁碟,也就是行話講的Snapshot快照,它恢復時是將快照中檔案直接讀到記憶體中

Redis會到哪都建立(fork),一個子程序來進行持久化,會將資料寫入一個臨時的檔案中,等到持久化過程都結束了,再用這個臨時
檔案替換上次持久化好的檔案。整個過程中,主程序不進行任何的io操作,這就確保了極高的效能。如果需要進行大規模的資料恢復
且對於資料的恢復完整性不是非常的敏感,那麼RDB方式比AOF方式更加的高效,RDB的缺點時最後一次持久化後的資料可能會丟失
我們預設使用的是RDB,一般情況下不需要修改整個配置!

RDB儲存的檔案是:dump.rdb
因為在redis.conf配置檔案中配置了rdb的預設檔名稱
    dbfilename dump.rdb
在redis.conf配置檔案中配置了rdb檔案的持久化規則
save 900 1:表示900 秒內如果至少有 1 個 key 的值變化,則儲存
save 300 10:表示300 秒內如果至少有 10 個 key 的值變化,則儲存
save 60 10000:表示60 秒內如果至少有 10000 個 key 的值變化,則儲存

1.在互動模組獲取rdb檔案的儲存路徑
    127.0.0.1:6379> config get dir
        1) "dir"
        2) "/data"
    127.0.0.1:6379> config get save
        1) "save"
        2) "60 5"------>意思是60秒內有5個key的值發生了變化,就會觸發持久化規則,生成dump.rdb檔案
    127.0.0.1:6379> set k1 v1
        OK
    127.0.0.1:6379> set k2 v2
        OK
    127.0.0.1:6379> set k3 v3
        OK
    127.0.0.1:6379> set k4 v4
        OK
    127.0.0.1:6379> set k5 v5
        OK
    會在docker容器的/data目錄下生成:dump.rdb檔案

RDB 有兩種觸發方式,分別是自動觸發和手動觸發

1.自動觸發
    在配置檔案中配置save策略
    
2.手動觸發
    手動觸發Redis進行RDB持久化的命令有兩種:
        2.1 1、save
          該命令會阻塞當前Redis伺服器,執行save命令期間,Redis不能處理其他命令,直到RDB過程完成為止。
          顯然該命令對於記憶體比較大的例項會造成長時間阻塞,這是致命的缺陷,為了解決此問題,Redis提供了第二種方式
            當執行save時,會直接生成dump.rdb檔案
       2.2 bgsave
          執行該命令時,Redis會在後臺非同步進行快照操作,快照同時還可以響應客戶端請求。
            具體操作是Redis程序執行fork操作建立子程序,RDB持久化過程由子程序負責,完成後自動結束。阻塞只發生在fork階段,一般時間很短。
          基本上 Redis 內部所有的RDB操作都是採用 bgsave 命令。
          ps:執行執行 flushall 命令,也會產生dump.rdb檔案,但裡面是空的.

恢復資料

 將備份檔案 (dump.rdb) 移動到 redis 安裝目錄並啟動服務即可,redis就會自動載入檔案資料至記憶體了。Redis 伺服器在載入 RDB 檔案期間,會一直處於阻塞狀態,直到載入工作完成為止。

停止 RDB 持久化

在redis的客戶端上:使用命令將save策略置為空
    config set save " "

RDB 的優勢和劣勢

①、優勢
  1.RDB是一個非常緊湊(compact)的檔案,它儲存了redis 在某個時間點上的資料集。這種檔案非常適合用於進行備份和災難恢復。
  2.生成RDB檔案的時候,redis主程序會fork()一個子程序來處理所有儲存工作,主程序不需要進行任何磁碟IO操作。
  3.RDB 在恢復大資料集時的速度比 AOF 的恢復速度要快。
②、劣勢
  1、RDB方式資料沒辦法做到實時持久化/秒級持久化。因為bgsave每次執行都要執行fork操作建立子程序,屬於重量級操作,如果不採用壓縮演算法(記憶體中的資料被克隆了一份,大致2倍的膨脹性需要考慮),頻繁執行成本過高(影響效能)
  2、RDB檔案使用特定二進位制格式儲存,Redis版本演進過程中有多個格式的RDB版本,存在老版本Redis服務無法相容新版RDB格式的問題(版本不相容)
  3、在一定間隔時間做一次備份,所以如果redis意外down掉的話,就會丟失最後一次快照後的所有修改(資料有丟失)

RDB 自動儲存的原理

Redis有個伺服器狀態結構:
  struct redisService{
         //1、記錄儲存save條件的陣列
         struct saveparam *saveparams;
         //2、修改計數器
         long long dirty;
         //3、上一次執行儲存的時間
         time_t lastsave;
    }

    1、首先看記錄儲存save條件的陣列 saveparam,裡面每個元素都是一個 saveparams 結構:
        struct saveparam{
             //秒數
             time_t seconds;
             //修改數
             int changes;
        };
    前面我們在 redis.conf 配置檔案中進行了關於save 的配置:
    save 900 1:表示900 秒內如果至少有 1 個 key 的值變化,則儲存
    save 300 10:表示300 秒內如果至少有 10 個 key 的值變化,則儲存
    save 60 10000:表示60 秒內如果至少有 10000 個 key 的值變化,則儲存
那麼伺服器狀態中的saveparam 陣列將會是如下的樣子:
2.、dirty 計數器和lastsave 屬性
  dirty 計數器記錄距離上一次成功執行 save 命令或者 bgsave 命令之後,Redis伺服器進行了多少次修改(包括寫入、刪除、更新等操作)。
   lastsave 屬性是一個時間戳,記錄上一次成功執行 save 命令或者 bgsave 命令的時間。
  通過這兩個命令,當伺服器成功執行一次修改操作,那麼dirty 計數器就會加 1,而lastsave 屬性記錄上一次執行save或bgsave的時間,Redis 伺服器還有一個週期性操作函式 severCron ,
   預設每隔 100 毫秒(100毫秒檢查一次)就會執行一次,該函式會遍歷並檢查 saveparams 陣列中的所有儲存條件,只要有一個條件被滿足,那麼就會執行 bgsave 命令。
  執行完成之後,dirty 計數器更新為 0 ,lastsave 也更新為執行命令的完成時間