十一、Redis的持久化(RDB、AOF)

寫在前面的話:讀書破萬卷,編碼若有神
----------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------
一、Redis持久化概述
Redis持久化分紅兩種方式:RDB(redis database)、 AOF(append only file)
  • RDB是在不一樣的時間點,將Redis某一時刻的數據生成快照並存儲到磁盤上。
  • AOF是隻容許追加不容許改寫的文件,是將Redis執行過的全部寫指令記錄下來,在下次redis重啓的時候,只要把這些寫指令從前到後重復執行一遍,就能夠實現數據恢復。
  • RDB和AOF兩種方式能夠同時使用,在這種狀況下,若是Redis重啓的話,則會優先採用AOF方式進行數據恢復,這是由於AOF方式的數據恢復完整度更高
  • 能夠關閉RDB和AOF,這樣的話,Redis就變成了一個純內存數據庫,就像Memcached同樣
  • 經過配置redis.config中的appendonly爲yes就能夠打開AOF功能
----------------------------------------------------------------------------------------
二、RDB 
  RDB方式,Redis會單首創建(fork)一個子進程進行持久化,會先將數據寫入到一個臨時文件中,待持久化過程都結束了,再用這個臨時文件替換上次持久化好的文件。整個過程當中,主進程是不進行任何IO操做的,這就確保了極高的性能。
  若是須要進行大規模數據的恢復,且對數據恢復的完整性不是很是敏感,那RDB方式要比AOF方式更加高效。RDB的缺點是最後一次持久化後的數據可能丟失。
2.一、RDB的問題
  • fork一個進程時,內存的數據也被複制了,即內存會是原來的兩倍
  • 每次快照持久化都是將內存數據完整寫入到磁盤一次,並非增量的只同步髒數據。若是數據量大的話,並且寫操做比較多,必然會引發大量的磁盤io操做,可能會嚴重影響性能
  • 因爲快照方式是在必定間隔時間作一次,因此若是redis意外down掉的話,就會丟失最後一次快照後的全部修改
2.二、觸發快照的狀況
  • 根據配置規則進行自動快照
  • 用戶執行save或bgsave命令
  • 執行flushall命令
  • 執行復制replication時
2.三、RDB相關命令:
  • save命令:(生產環境不要用)執行save命令時,redis會阻塞全部客戶端的請求,而後同步進行快照操做。
  • bgsave命令執行bgsave命令時,redis會在後臺異步進行快照操做,快照同時還能夠響應客戶端請求。能夠經過lastsave命令獲取最後一次成功執行快照的時間。
  • flushall命令這個命令會致使redis清除內存中的全部數據,若是定義了自動快照的條件,那麼不管是否知足條件,都會進行一次快照操做;若是沒有定義自動快照的條件,那麼不會進行快照。
2.四、快照部分的配置信息
配置信息以下:
 1 ################################ SNAPSHOTTING  ################################
 2 #
 3 # Save the DB on disk:
 4 #
 5 #   save <seconds> <changes>
 6 #
 7 #   Will save the DB if both the given number of seconds and the given
 8 #   number of write operations against the DB occurred.
 9 #
10 #   In the example below the behaviour will be to save:
11 #   after 900 sec (15 min) if at least 1 key changed
12 #   after 300 sec (5 min) if at least 10 keys changed
13 #   after 60 sec if at least 10000 keys changed
14 #
15 #   Note: you can disable saving completely by commenting out all "save" lines.
16 #
17 #   It is also possible to remove all the previously configured save
18 #   points by adding a save directive with a single empty string argument
19 #   like in the following example:
20 #
21 #   save ""
22 
23 save 900 1
24 save 300 10
25 save 60 10000
26 
27 # By default Redis will stop accepting writes if RDB snapshots are enabled
28 # (at least one save point) and the latest background save failed.
29 # This will make the user aware (in a hard way) that data is not persisting
30 # on disk properly, otherwise chances are that no one will notice and some
31 # disaster will happen.
32 #
33 # If the background saving process will start working again Redis will
34 # automatically allow writes again.
35 #
36 # However if you have setup your proper monitoring of the Redis server
37 # and persistence, you may want to disable this feature so that Redis will
38 # continue to work as usual even if there are problems with disk,
39 # permissions, and so forth.
40 stop-writes-on-bgsave-error yes
41 
42 # Compress string objects using LZF when dump .rdb databases?
43 # For default that's set to 'yes' as it's almost always a win.
44 # If you want to save some CPU in the saving child set it to 'no' but
45 # the dataset will likely be bigger if you have compressible values or keys.
46 rdbcompression yes
47 
48 # Since version 5 of RDB a CRC64 checksum is placed at the end of the file.
49 # This makes the format more resistant to corruption but there is a performance
50 # hit to pay (around 10%) when saving and loading RDB files, so you can disable it
51 # for maximum performances.
52 #
53 # RDB files created with checksum disabled have a checksum of zero that will
54 # tell the loading code to skip the check.
55 rdbchecksum yes
56 
57 # The filename where to dump the DB
58 dbfilename dump_6379.rdb
59 
60 # The working directory.
61 #
62 # The DB will be written inside this directory, with the filename specified
63 # above using the 'dbfilename' configuration directive.
64 #
65 # The Append Only File will also be created inside this directory.
66 #
67 # Note that you must specify a directory here, not a file name.
68 dir ./
View Code
(1)save * * : 保存快照的頻率,第一個*表示多長時間,單位是秒;第二個*表示至少執行寫操做的次數;在必定時間內至少執行必定數量的寫操做時,就自動保存快照,可設置多個條件。
  • 若是想要禁用RDB持久化的策略,只要不設置任何save指令,或者給save傳入一個空字符串參數就能夠。
  • 若是用戶開啓了RDB快照功能,那麼在redis持久化數據到磁盤時若是出現失敗,默認狀況下,redis會中止接受全部的寫請求,這樣作的好處在於可讓用戶很明顯的知道內存的數據和磁盤上的數據已經不存在一致性了。若是一下次RDB持久化成功,redis會自動恢復寫請求。
(2)stop-writes-on-bgsave-error : 若是配置成no,表示不在意數據不一致或者其餘的手段發現和控制這種不一致,那麼在快照寫入失敗時,也就能確保redis繼續接受新的寫請求。
(3)rdbcompression :對於存儲到磁盤中的快照,能夠設置是否進行壓縮存儲。若是是的話,redis會採用LZF算法進行壓縮。若是你不想消耗CPU來進行壓縮的話,能夠設置爲關閉此功能。
(3)rdbchecksum : 在存儲快照後,還可讓redis使用CRC64算法來進行數據校驗,可是這樣作會增長大約10%的性能消耗,若是但願獲取到最大性能提高,能夠關閉此功能。
(4)dbfilename : 數據快照文件名(只是文件名,不包括目錄),默認dump.rdb
(5)dir : 數據快照的保存目錄,默認是當前路徑
 ----------------------------------------------------------------------------------------
三、AOF
默認的AOF持久化策略是每秒鐘fsync一次,fsync是指把緩存中的寫指令記錄到磁盤中,在這種狀況下,Redis仍能夠保持很高的性能。
固然因爲OS會在內核中緩存write作的修改,因此可能不是當即寫到磁盤上。這樣AOF方式的持久化也仍是有可能會丟失部分修改。不過能夠經過配置文件告訴redis,想要經過fsync函數強制os寫入到磁盤的時機。
AOF方式在同等數據規模的狀況下,AOF文件要比RDB文件的體積大,所以AOF方式的恢復速度也要慢於RDF方式
3.一、 AOF日誌恢復
若是在追加日誌時,剛好遇到磁盤空間滿或者斷電的狀況,致使日誌寫入不完整,也沒有關係,redis提供了redis-check-aof工具,能夠用來進行日誌修復,基本步驟以下:
    • 備份被寫壞的AOF文件
    • 運行redis-check-aof -fix 進行修復
    • 用diff -u來看下兩個文件的差別,確認問題點
    • 重啓redis,加載修復後的AOF文件
3.二、 AOF重寫
AOF採用文件追加方式,這會致使AOF文件愈來愈大,爲此,Redis提供了AOF文件重寫(rewrite)機制,即當AOF文件的大小超過所設定的閾值時,Redis就會啓動AOF文件的內容壓縮,只保留能夠恢復數據的最小指令集。可使用命令:bgrewriteaof
3.三、 AOF重寫觸發機制
Redis是這樣工做的:Redis會記錄上次重寫時AOF大小,假如自啓動至今尚未進行太重寫,那麼啓動時AOF文件的大小會被做爲基準值,這個基準值會和當前的AOF大小進行比較,若是當前AOF大小超出所設置的增加比例,則會觸發重寫。另外,你還須要設置一個最小大小,是爲了防止在AOF很小時就觸發重寫。
3.四、 AOF重寫的基本原理
  • 在重寫開始前,redis會建立一個"重寫子進程",這個子進程會讀取現有的AOF文件,並將其包含的指令進行分析解壓縮並寫入到一個臨時文件中
  • 與此同時,主進程將新接收到的寫指令一邊累積到內存緩衝區中,一邊繼續寫入到原有的AOF文件中,這樣作是保證原有的AOF文件的可用性,避免在重寫過程當中出現意外
  • 當"重寫子進程"完成重寫工做後,它會給父進程發一個信號,父進程收到信號後就會將內存中緩存的寫指令追加到新AOF文件中
  • 當追加結束後,redis就會用新AOF文件來替代舊AOF文件,以後再有新的寫指令,就都會追加到新的AOF文件中
  • 重寫AOF文件的操做,並無讀取舊的AOF文件,而是將整個內存中的數據庫內容用命令的方式重寫了一個新的AOF文件,這點和快照有點相似。
3.五、AOF 配置信息
(1)appendonly : 是否開啓AOF
(2)appendfilename : 設置AOF的日誌文件名
(3)appendfsync : 設置AOF日誌如何同步到磁盤,fsync()調用,用來告訴操做系統當即將緩存的指令寫入磁盤,有三個選項:
    • always : 每次寫都強制調用fsync,這種模式下,redis會相對較慢,但數據最安全
    • everysec : 每秒啓用一次fsync。(推薦)
    • no : 不調用fsync()。而是讓操做系統自行決定sync的時間。這種模式下,redis的性能會最快
(4)no-appendfsync-on-write : 設置當redis在rewrite的時候,是否容許appendsync。由於redis進程在進行AOF重寫的時候,fsync()在主進程中的調用會被阻止,也就是redis的持久化功能暫時失效,默認爲no,這樣能保證數據安全
(5)auto-aof-rewrite-min-size : 設置一個最小大小,是爲了防止在aof很小時就觸發重寫
(6)auto-aof-rewrite-percentage : 設置自動進行aof重寫的基準值,也就是重寫啓動時的AOF文件大小,假如redis自啓動至今尚未進行太重寫,那麼啓動時aof文件的大小會被做爲基準值,這個基準值會和當前的aof大小進行比較。若是當前aof大小超出設置的增加比例,則會觸發重寫,若是設置auto-aof-rewrite-percentage爲0,則會關閉此重寫功能。
相關文章
相關標籤/搜索