1. 程式人生 > >6-Redis 的持久化之 AOF

6-Redis 的持久化之 AOF

2017-01-01 16:42:13


該系列文章連結
NoSQL 資料庫簡介
Redis的安裝及及一些雜項基礎知識
Redis 的常用五大資料型別(key,string,hash,list,set,zset)
Redis 配置檔案介紹
Redis 持久化之RDB
Redis 持久化之AOF
Redis 主從複製
Redis 事務
Redis 釋出與訂閱
Redis jdedis 介紹


Redis 官網介紹 持久化(RDB 與 AOF)
1.AOF: Append only file
AOF 以日誌的形式記錄每個寫操作,將 Redis 執行過的所有寫指令記錄下來,不記錄讀操作。
只需追加檔案但不可以改寫檔案,redis 啟動之初會讀取該檔案重新構建資料,也就是說,redis 重啟的話就根據日誌檔案的內容將寫指令從前到後執行一次已完成資料的恢復工作

aof 儲存的檔案是 appendonly.aof 檔案

2.AOF 在 redis.conf 的一些配置
    2.1 appendonly
         預設情況下,Redis非同步轉儲資料集到磁碟上。此模式在許多應用程式中都足夠好,但例如如果Redis程序會由於停電的問題而導致幾分鐘的寫入丟失(取決於配置的儲存點)。
        AOF 是一種備用持久化模式,可提供更好的持久化。例如,使用預設資料 fsync 策略(請參閱配置檔案中的後面部分)Redis在伺服器斷電等戲劇性事件中只會丟失一秒寫入,如果Redis程序本身出現問題,則會丟失一次,但是作業系統仍然正常執行。
        可以同時啟用AOF和RDB持久化以保證不會出現問題。
        如果在啟動時啟用AOF,Redis將載入AOF,即檔案
        將具有更好的永續性保證。
        請檢視 http://redis.io/topics/persistence 以獲取更多資訊。

        總的來說,這個配置是 開啟或關閉AOF 的總配置

    2.2 appendfilename
        AOF 檔案的名稱(預設:"appendonly.aof")

    2.3 appendfsync
         呼叫 fsync()將讓作業系統實際寫入資料到磁碟上,而不是等待輸出緩衝區中的更多資料。某些作業系統會真正重新整理資料到磁碟上,其他一些作業系統會盡快嘗試這樣做。
        Redis支援三種不同的模式:
            no:不要 fsync,只需讓作業系統在需要時重新整理資料。速度更快。
            always:每次有寫入操作都會呼叫 fsync,將寫入操作記錄到 appendonly.aof 中。慢,最安全。
            everysec:每秒呼叫一次 fsync ,將寫入操作記錄到 appendonly.aof 中。妥協方案。

        預設值為“everysec”,因為這通常是速度和資料安全之間的正確折衷。這取決於你是否可以理解不總是讓作業系統在需要時重新整理輸出緩衝區,以獲得更好的效能(但如果你能想到一些資料丟失的想法,請考慮預設的持久化模式,也就是 RDB),或相反,使用“always”,將非常慢,但比 everysec 方案更安全。
        更多詳情請檢視以下文章:http://antirez.com/post/redis-persistence-demystified.html

        如果不確定,請使用“everysec”。
        
    2.4 no-appendfsync-on-rewrite
        當AOF fsync策略設定為always或everysec且後臺儲存程序(後臺儲存或AOF日誌後臺重寫)正在對磁碟執行大量I/O操作時,在某些Linux配置中,Redis可能會阻塞太長時間在 fsync()呼叫。請注意,目前沒有對此進行修復,因為即使在不同的執行緒中執行 fsync 也會阻塞我們的同步 write(2) 的呼叫。
        為了緩解這個問題,當BGSAVE或BGREWRITEAOF正在進行中時可以使用這個配置來阻止在主程序中呼叫fsync()。
        這意味著當另一個子程序正在儲存時,Redis的 appendfsync 策略將會與“appendfsync none”相同。實際上,這意味著在最糟糕的情況下(使用預設的Linux設定)可能會丟失最多30秒的日誌。
        如果您有延遲問題,請將其轉為 "yes"。否則,從耐用性的角度來看,它是最“最安全”的選擇使用 "no"。

    2.5 auto-aof-rewrite-percentage/auto-aof-rewrite-min-size
        自動重寫 appendonly.file 。
        當AOF日誌大小增長到指定的百分比(即 auto-aof-rewrite-percentage的值)時,Redis能夠自動重寫日誌檔案,隱式呼叫 BGREWRITEAOF。
        這是它的工作原理:Redis會在最近的重寫後記住AOF檔案的大小(如果重啟後沒有重寫,則使用啟動時的AOF大小)。
        將此基本大小與當前大小進行比較。如果當前大小大於指定的百分比,則觸發重寫。此外,您需要指定要重寫的AOF檔案的最小大小,這有助於避免重寫AOF檔案,即使達到 auto-aof-rewrite-percentage 但仍然非常小。
        指定 auto-aof-rewrite-percentage = 0 以禁用自動AOF重寫功能。

    2.6 aof-load-truncated
        如果系統(尤其是在沒有data = ordered選項的情況下掛載ext4檔案系統)出現崩潰且此時 Redis 啟動程序在使用 AOF 的 appendonly.aof 檔案將資料載入回記憶體時,可能會發生 appendonly.aof 末尾出現錯誤(也就是末尾被截斷,檔案不正常終止)這種情況(但是當Redis本身崩潰或中止但作業系統仍能正常工作時,這種情況不會發生)。
        發生這種情況時,Redis可以退出,或者載入儘可能多的資料(預設值),如果發現AOF檔案在末尾被截斷,則啟動。此選項控制此行為。
        如果將aof-load-truncated設定為yes,則會載入截斷的AOF檔案,並且Redis伺服器會開始發出日誌以通知使用者該事件。
        否則,如果該選項設定為no,則伺服器將中止並顯示錯誤並拒絕啟動。當該選項設定為no時,使用者需要使用“redis-check-aof”實用程式修復AOF檔案,然後才能重新啟動伺服器。
        請注意,如果發現AOF檔案在中間被破壞,伺服器仍將退出並顯示錯誤。此選項僅在Redis嘗試從AOF檔案中讀取更多資料但不會找到足夠的位元組時適用。

    2.7 aof-use-rdb-preamble
         重寫AOF檔案時,Redis能夠使用AOF檔案中的RDB前導碼來加快重寫和恢復速度。啟用此選項後,重寫的AOF檔案由兩個不同的節組成:
               [RDB檔案] [AOF尾]
         載入時Redis識別出AOF檔案以“REDIS”字串開頭並載入字首RDB檔案,並繼續載入AOF尾部。
3.AOF rewrite
    3.1 重寫
        AOF 採用檔案追加的方式,檔案會越來越大為避免出現此種情況,新增重寫機制。
        當 AOF 檔案大小超過所設定的閾值時,Redis 就會啟動 AOF 檔案的內容壓縮,只保留可以恢復資料的最小指令集。可以使用命令 bgrewriteaof

    3.2 重寫原理
        AOF 檔案持續增長而過大時,會 fork 出一條新程序來講檔案重寫(先寫臨時檔案最後在改名,預設名字為 appendonly.aof),遍歷新程序的記憶體中資料,每條記錄有一條 set 語句,重寫 aof 檔案,並沒有讀取舊的 aof 檔案
        而是將整個記憶體中的資料用命令的方式重寫了一個新的 aof 檔案,這點和快照有點類似

    3.3 重寫觸發機制
        Redis 會記錄賞賜重寫時的 AOF 大小,預設配置是當 AOF 檔案大小是上次 rewrite 後大小的已被且檔案大小大於 64M 時觸發

4. AOF 同步策略
    4.1 always:每次發生寫入操作時都會被立即記錄到磁碟,效能較差但資料完整性比較好

    4.2 everysec:非同步操作,每秒記錄,如果在一秒內宕機,那麼將丟失 一秒的資料

    4.3 no:不同步

5.AOF 劣勢
    5.1 相同資料集的資料而言 aof 檔案要遠大於 rdb 檔案,恢復速度慢於 rdb
    5.2 aof 執行效率要慢於 rdb, everysec 同步策略效率較好,no 同步策略效率和 rdb 相同

6.關於 RDB 和 AOF 這兩種持久化方式的總結
    6.1 RDB
        RDB 持久化方式能夠在指定的時間間隔內對你的資料進行快照儲存

    6.2 AOF
        AOF 持久化方式記錄每次對伺服器寫的操作,當伺服器衝i的時候會重新執行這些命令來恢復原始的資料。AOF 命令以 redis 協議追加儲存每次寫的操作到檔案末尾
        redis 還能對 AOF 檔案進行後臺重寫,使得 AOF 檔案體積不至於過大

    6.3 不開啟持久化
        當然如果 redis 只做快取的話,那麼可以不用任何持久化的方式

    6.4 開啟持久化
        但是如果不只做快取,那麼最好同時開啟兩種持久化方式
        在這種情況下,redis 重啟時會優先載入 AOF 檔案來恢復原始的資料,因為在通常情況下 AOF 檔案儲存的資料要比 RDB 檔案儲存的資料要完整

        那麼 RDB 資料不實時,而且同時使用兩者時伺服器重啟也只會找 AOF 檔案,要不要只使用 AOF 呢?(我有一個大膽的想法,你要不要聽聽)
        redis 開發人員建議不要,因為 RDB 更適合用於備份資料庫,AOF 在不斷變化不好備份
        而且快速重啟後,RDB 不會有 AOF 可能潛在的bug,留著 RDB 可以作為一個以防萬一的手段

    6.4 開啟了主從複製且開啟了持久化
        因為RDB檔案只用作後備用途,建議只在Slave上持久化RDB檔案,而且只要15分鐘備份一次就夠了,即只保留save 900 1這條規則。
        如果開啟 AOF,好處是在最惡劣情況下也只會丟失不超過30秒資料,啟動指令碼較簡單隻載入自己的AOF檔案就可以了。代價一是帶來了持續的IO,二是AOF 重寫的最後將重寫過程中產生的新資料寫到新檔案造成的阻塞幾乎是不可避免的。只要硬碟許可,應該儘量減少AOF 重寫的頻率,AOF重寫的基礎大小預設值64M太小了,可以設到5G以上。預設超過原大小100%大小時重寫可以改到適當的數值,例如80%。
        如果不開啟 AOF ,僅靠主從複製實現高可用性也可以。能省掉一大筆IO也減少了重寫時帶來的系統波動。代價是如果Master/Slave同時倒掉,會丟失十幾分鐘的資料,啟動指令碼也要比較兩個Master/Slave中的RDB檔案以便載入較新的檔案。