Redis持久化


  前言:持久化是什么?簡單的說就是將數據放在斷電后不會丟失的設備中,比如磁盤,數據庫在進行寫操作時做了哪些事呢?

  主要有五個過程
  1、客戶端向服務端發送寫操作(數據在客戶端的內存中)。
  2、數據庫服務端接收到寫請求的數據(數據在服務端的內存中)。
  3、服務端調用write這個系統調用,將數據往磁盤上寫(數據在系統內存的緩沖區中)。
  4、操作系統將緩沖區中的數據轉移到磁盤控制器上(數據在磁盤緩存中)。
  5、磁盤控制器將數據寫到磁盤的物理介質中(數據真正落到磁盤上)。

  從上面可以看出,當數據庫發生故障時,如果系統內核是完好的。那么執行完了第三步,那么數據就是安全的,如果斷電,上面五項中所有的緩存都會失效,數據庫和操作系統都會停止工作。所以只有全部走完才能保證數據不丟失。
  通過上面的分析,我們可能有一些疑惑。
  1、數據庫多長時間調用一次write,將數據寫到內核緩沖區?
  2、內核多長時間會將系統緩沖區中的數據寫到磁盤控制器?
  3、磁盤控制器又在什么時候把緩存中的數據寫到物理介質上?
  其中第一個問題通常都是由數據庫層面控制。第二個問題呢操作系統都有默認的策略,但是可以通過通過POSIX API提供的fsync系列命令強制操作系統將數據從內核區寫到磁盤控制器上
  對於第三個問題數據庫已經無法觸及,但實際上,大多數情況下磁盤緩存是被設置關閉的,或者是只開啟為讀緩存,也就是說寫操作不會進行緩存,直接寫到磁盤。建議的做法是僅僅當你的磁盤設備有備用電池時才開啟寫緩存。
  數據備份一般有三種方式:
  A:數據同步備份的方式
  B:記錄每一步的操作行為
  C:以追加的方式記錄數據,數據本身不修改,數據本身就是一份日志。

  Redis有兩種持久化策略:RDB和AOF

  一、RDB快照

  RDB 持久化可以在指定的時間間隔內生成數據集的時間點快照。如何生成快照呢?Redis借助了fork命令的copy on write機制。在生成快照時,將當前進程fork出一個子進程,然后在子進程中循環所有的數據,將數據寫成為RDB文件。
  子進程基本上是復制父進程,這等於兩個相同的redis進程在系統上運行,會造成內存使用率的大幅增加。redis.conf中配置參數如下:含義為X秒改變了N次

      

Background saving started by pid 19064
19064:C 19 Sep 23:55:45.087 # Failed opening the RDB file dump.rdb (in server root dir /home/matao/redis-3.2.9/src) for saving: Permission denied
#   Will save the DB if both the given number of seconds and the given
--More--(15%)2470:M 19 Sep 23:55:45.186 # Background saving error
#   number of write operations against the DB occurred.
#
#   In the example below the behaviour will be to save:
#   after 900 sec (15 min) if at least 1 key changed
#   after 300 sec (5 min) if at least 10 keys changed
#   after 60 sec if at least 10000 keys changed
#
#   Note: you can disable saving completely by commenting out all "save" lines.
#
#   It is also possible to remove all the previously configured save
#   points by adding a save directive with a single empty string argument
#   like in the following example:
#
#   save ""

//保存的策略
save
900 1 save 300 10 save 60 10000
# The filename where to dump the DB
dbfilename dump.rdb  //保存的文件名       
# The working directory.
#
# The DB will be written inside this directory, with the filename specified
# above using the 'dbfilename' configuration directive.
#
# The Append Only File will also be created inside this directory.
#
# Note that you must specify a directory here, not a file name.
dir ./   //保存的文件路徑

  手動保存有兩種方式:

  1、save 同步進行 阻塞客戶端請求
  2、bgsave異步進行 不妨礙目前的寫入。

  二、AOF

  AOF是通過保存對redis服務端的寫命令來記錄數據庫狀態的,即保存你對redis數據庫的寫操作。AOF的運作方式是不斷的將寫命令追加到文件的末尾,所以隨着寫入命令的不斷增減,AOF的文件體積也會變大越來越大。
  例如:一個計數器調用了100次INCR,那么AOF文件就記錄了100條記錄。實際上只使用一條set命令足以保存計數器當前的值了,為了控制AOF文件的大小,redis支持執行 BGREWRITEAOF 命令, Redis 將生成一個新的 AOF 文件, 這個文件包含重建當前數據集   所需的最少命令。
  Redis調用write寫入后,何時調用fsync將其寫到磁盤上,通過appendfsync來控制
  1、appendfsync no
  當設置appendfsync為no的時候,Redis不會主動調用fsync去將AOF日志內容同步到磁盤,所以這一切就完全依賴於操作系統的調試了。對大多數Linux操作系統,是每30秒進行一次fsync,將緩沖區中的數據寫到磁盤上。
  2、appendfsync everysec
  當設置appendfsync為everysec的時候,Redis會默認每隔一秒進行一次fsync調用,將緩沖區中的數據寫到磁盤。但是當這一 次的fsync調用時長超過1秒時。Redis會采取延遲fsync的策略,再等一秒鍾。也就是在兩秒后再進行fsync,這一次的fsync就不管會執行多長時間都會進行。這時候由於在fsync時文件描述符會被阻塞,所以當前的寫操作就會阻塞。 所以,結論就是:在絕大多數情況下,Redis會每隔一秒進行一次fsync。在最壞的情況下,兩秒鍾會進行一次fsync操作。 這一操作在大多數數據庫系統中被稱為group commit,就是組合多次寫操作的數據,一次性將日志寫到磁盤。
  3、appednfsync always
  當設置appendfsync為always時,每一次寫操作都會調用一次fsync,這時數據是最安全的,當然,由於每次都會執行fsync,所以其性能也會受到影響。
  優點:RDB非常適合用於備份,恢復速度很快。AOF會使redis變得非常耐久,使數據安全性進一步提高。
  缺點:RDB在服務器故障時會丟失一段時間的數據。AOF文件的體積大於RDB,AOF的速度可能會慢於RDB。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM