3.Redis持久化

持久化

1、RDB

  • 概念
    RDB持久化可以在指定的時間間隔內生成數據集的時間點內存快照
  • 配置
    1、save 60 10000
    2、rdbcompression yes
    3、dbfilename "dump_6379.rdb"
    4、dir "/appdata/redis/savefile"(AOF同)



  • 命令
save  
    通過主進程,造成阻塞,期間不能執行任何命令
bgsave  
    fork()子進程後臺進行
  • 優點
    1、恢復速度快,但載入過程中會令redis一直處於阻塞狀態,直到載入完成;
    2、可壓縮保存;
    3、可最大化Redis性能,父進程fork子進程完成保存操作。


  • 缺點
    1、數據非實時保存,易丟失部分數據;
    2、數據集大時,fork()操作耗時且消耗cpu。

2、AOF

  • 概念
    AOF 持久化記錄服務器執行的所有寫操作命令(append-only file)
  • 配置
1、appendfsync    
        1、always    
        2、everysec  
        3、no(由系統決定同步頻率)  
2、appendonly yes  
3、appendfilename "appendonly.aof"  
4、auto-aof-rewrite-percentage 100  
   auto-aof-rewrite-min-size 64mb
  • AOF還原過程
  1. 創建一個不帶網絡連接的僞客戶端,因爲redis的命令只能在客戶端上下文中執行;
  2. 從AOF文件中分析並讀取一條寫命令;
  3. 使用僞客戶端執行被讀出的寫命令;
  4. 一直重複步驟2和步驟3,直到AOF文件的所有寫命令被處理完畢爲止。
  • aof重寫機制

    1. AOF文件重寫並不需要對現有的AOF文件進行任何讀取、分析或者寫入操作,這個功能是通過讀取服務器當前數據庫狀態來實現的。首先從數據庫中讀取鍵現在的值,然後用一條命令去記錄鍵值對,代替之前記錄這個鍵值對的多條命令,這就是AOF重寫功能的實現原理;
    2. 同時,爲了解決重寫期間有數據寫入導致現有AOF和重寫後的AOF數據不一致的問題,Redis設置了一個AOF重寫緩衝區,Redis執行完一個命令後,它會同時將這個寫命令發送給AOF緩衝區和AOF重寫緩衝區。
    3. AOF重寫完成後,會向父進程發送一個信號,父進程將調用信號處理函數執行以下操作:
      1)將AOF重寫緩衝區的所有內容寫入新AOF文件中;
      2)對新的AOF文件改名,原子地覆蓋現有的AOF文件,完成兩個文件的替換;
      3)整個過程,只有信號處理函數執行時纔會對Redis父進程造成阻塞。


  • aof重寫命令
bgrewriteaof  fork()子進程重寫aof文件
  • 優點
    1、較爲實時,默認(everysec)至多丟失一秒數據
    2、redis-check-aof --fix 可修復AOF文件
    3、文件可讀性強
    4、可進行安全的rewrite操作



  • 缺點
    1、體積較大
    2、根據fsync策略,AOF可能會導致redis速度低於RDB

3、優先級

  1. 優先AOF載入內存,只有關閉AOF功能時纔會載入載入RDB文件恢復數據庫;
  2. BGSAVE和BGREWRITE不可同時進,BGSAVE時發起BGREWRITE,後者會阻塞,等待BGSAVE完成後再開始,BGREWRITE時發起BGSAVE,會被拒絕。

4、寫時複製(Copy-On-Write)

(1) fork()
fork會創建一個子進程,子進程的是父進程的副本。

(2) exec()
exec函數的作用就是裝載一個新的程序(可執行映像)覆蓋當前進程內存空間中的映像,從而執行不同的任務。如redis的子進程專門用於進行bgsave或bgrewrite操作。

(3) Copy-On-Write技術實現原理:
fork()之後,kernel把父進程中所有的內存頁的權限都設爲read-only,然後子進程的地址空間指向父進程。當父子進程都只讀內存時,相安無事。當其中某個進程寫內存時,CPU硬件檢測到內存頁是read-only的,於是觸發頁異常中斷(page-fault),陷入kernel的一箇中斷例程。中斷例程中,kernel就會把觸發的異常的頁複製一份,於是父子進程各自持有獨立的一份。

(4) Copy-On-Write優缺點?
優點:

  • COW技術可減少分配和複製大量資源時帶來的瞬間延時;
  • COW技術可減少不必要的資源分配。比如fork進程時,並不是所有的頁面都需要複製,父進程的代碼段和只讀數據段都不被允許修改,所以無需複製。

缺點:

  • 如果在fork()之後,父子進程都還需要繼續進行寫操作,那麼會產生大量的分頁錯誤(頁異常中斷page-fault),這樣就得不償失。

(5) Copy-On-Write在redis上的應用

  • Redis在持久化時,如果是採用BGSAVE命令或者BGREWRITEAOF的方式,那Redis會fork出一個子進程來讀取數據,從而寫到磁盤中。
  • 總體來看,Redis還是讀操作比較多。如果子進程存在期間,發生了大量的寫操作,那可能就會出現很多的分頁錯誤(頁異常中斷page-fault),這樣就得耗費不少性能在複製上。
  • 在rehash階段上,寫操作是無法避免的。根據 BGSAVE 命令或 BGREWRITEAOF 命令是否正在執行, 服務器執行擴展操作所需的負載因子並不相同, 這是因爲在執行 BGSAVE命令或 BGREWRITEAOF 命令的過程中, Redis 需要創建當前服務器進程的子進程, 而大多數操作系統都採用寫時複製(copy-on-write)技術來優化子進程的使用效率, 所以在子進程存在期間, 服務器會提高執行擴展操作所需的負載因子, 從而儘可能地避免在子進程存在期間進行哈希表擴展操作, 這可以避免不必要的內存寫入操作, 最大限度地節約內存。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章