1. 程式人生 > 實用技巧 >【Redis】05 持久化

【Redis】05 持久化

持久化概述

Redis提供了不同的永續性選項:

1、RDB永續性按指定的時間間隔執行資料集的時間點快照。

2、AOF永續性會記錄伺服器接收的每個寫入操作,這些操作將在伺服器啟動時再次播放,以重建原始資料集。使用與Redis協議本身相同的格式記錄命令,並且僅採用追加方式。當日志太大時,Redis可以在後臺重寫日誌。

3、如果您希望,只要您的資料在伺服器執行時就一直存在,則可以完全禁用永續性。

4、可以在同一例項中同時合併AOF和RDB。請注意,在這種情況下,當Redis重新啟動時,由於可以保證AOF檔案是最完整的,因此它將用於重建原始資料集。

要理解的最重要的事情是RDB和AOF永續性之間的不同權衡。

讓我們從RDB開始:

RDB【Redis DataBase】

優勢

1、RDB是Redis資料的非常緊湊的單檔案時間點表示。RDB檔案非常適合備份。例如,您可能希望在最近的24小時內每小時存檔一次RDB檔案,並在30天之內每天儲存一次RDB快照。這使您可以在發生災難時輕鬆還原資料集的不同版本。

2、RDB對災難恢復非常有用,它是一個緊湊的檔案,可以傳輸到遠端資料中心或Amazon S3(可能已加密)上。

3、RDB最大限度地提高了Redis的效能,因為Redis父程序為了持久化而需要做的唯一工作就是分叉一個孩子,其餘所有工作都要做。父例項將永遠不會執行磁碟I / O或類似操作。

4、與AOF相比,RDB允許大型資料集更快地重啟。

缺點

1、如果您需要在Redis停止工作(例如斷電後)時最大程度地減少資料丟失的機會,那麼RDB不好。您可以配置生成RDB的不同儲存點(例如,在至少五分鐘後,對資料集進行100次寫操作,但是您可以有多個儲存點)。但是,通常會每隔五分鐘或更長時間建立一次RDB快照,因此,如果Redis出於任何原因在沒有正確關閉的情況下停止工作,則應該準備丟失最新的資料分鐘。

2、RDB需要經常使用fork()才能使用子程序將其持久化在磁碟上。如果資料集很大,Fork()可能很耗時,並且如果資料集很大且CPU效能不佳,則可能導致Redis停止為客戶端服務幾毫秒甚至一秒鐘。AOF還需要fork(),但您可以調整要重寫日誌的頻率,而無需在永續性上進行權衡。

AOF【Append Only File】

優勢

1、使用AOF Redis更加持久:您可以有不同的fsync策略:完全沒有fsync,每秒fsync,每個查詢fsync。使用fsync的預設策略,每秒的寫入效能仍然很好(使用後臺執行緒執行fsync,並且在沒有進行fsync的情況下,主執行緒將盡力執行寫入操作。)但是您只能損失一秒鐘的寫入時間。

2、AOF日誌是僅追加的日誌,因此,如果斷電,則不會出現尋道或損壞問題。即使由於某種原因(磁碟已滿或其他原因)以半寫命令結束日誌,redis-check-aof工具也可以輕鬆修復它。

3、Redis太大時,Redis可以在後臺自動重寫AOF。重寫是完全安全的,因為Redis繼續追加到舊檔案時,會生成一個全新的檔案,其中包含建立當前資料集所需的最少操作集,一旦準備好第二個檔案,Redis會切換這兩個檔案並開始追加到新的那一個。

4、AOF以易於理解和解析的格式包含所有操作的日誌。您甚至可以輕鬆匯出AOF檔案。例如,即使您使用FLUSHALL命令重新整理了所有錯誤檔案,如果在此期間未執行任何日誌重寫操作,您仍然可以儲存資料集,只是停止伺服器,刪除最新命令並重新啟動Redis。

缺點

1、對於同一資料集,AOF檔案通常大於等效的RDB檔案。

2、根據確切的fsync策略,AOF可能比RDB慢。通常,在將fsync設定為每秒的情況下,效能仍然很高,並且在禁用fsync的情況下,即使在高負載下,它也應與RDB一樣快。即使在巨大的寫負載情況下,RDB仍然能夠提供有關最大延遲的更多保證。

3、過去,我們在特定命令中遇到過罕見的錯誤(例如,其中一個涉及阻止命令,例如BRPOPLPUSH),導致生成的AOF在過載時無法重現完全相同的資料集。這些錯誤很少見,我們在測試套件中進行了測試,自動建立了隨機的複雜資料集,然後重新載入它們以檢查一切是否正常。但是,RDB永續性幾乎是不可能的。為了更清楚地說明這一點:Redis AOF通過增量更新現有狀態來工作,就像MySQL或MongoDB一樣,而RDB快照一次又一次地建立所有內容,從概念上講更健壯。但是-1)應當注意,每次Redis重寫AOF時,都會從資料集中包含的實際資料開始從頭開始重新建立AOF,與始終附加AOF檔案(或重寫為讀取舊的AOF而不是讀取記憶體中的資料)相比,提高了對錯誤的抵抗力。2)我們從未收到過有關真實環境中檢測到的AOF損壞的使用者報告。


實際應用:

通常的指示是,如果您希望獲得與PostgreSQL可以提供的功能相當的資料安全性,則應同時使用兩種永續性方法。

如果您非常關心資料,但是在災難情況下仍然可以承受幾分鐘的資料丟失,則可以僅使用RDB。

有很多使用者單獨使用AOF,但我們不建議這樣做,

因為不時擁有RDB快照對於進行資料庫備份,加快重啟速度以及AOF引擎中存在錯誤是一個好主意。

快照

預設情況下,Redis將資料集的快照儲存在磁碟上名為的二進位制檔案中

dump.rdb

如果資料集中至少有M個更改,可以將Redis配置為使其每N秒儲存一次資料集,或者可以手動呼叫SAVEBGSAVE命令。

例如,如果更改了至少1000個鍵,此配置將使Redis每60秒自動將資料集轉儲到磁碟上:


RDB:

save 900 1
save 300 10
save 60 10000

在指定的時間間隔內將記憶體中的資料集快照寫入磁碟,

也就是行話講的Snapshot快照,它恢復時是將快照檔案直接讀到記憶體裡

Redis會單獨建立(fork)一個子程序來進行持久化,會先將資料寫入到 一個臨時檔案中,待持久化過程都結束了,

再用這個臨時檔案替換上次持久化好的檔案。

整個過程中,主程序是不進行任何IO操作的,

這就確保了極高的效能 如果需要進行大規模資料的恢復,且對於資料恢復的完整性不是非常敏感,RDB方式要比AOF方式更加的高效。

RDB的缺點是最後一次持久化後的資料可能丟失。

Fork?

Fork的作用是複製一個與當前程序一樣的程序。

新程序的所有資料(變數、環境變數、程式計數器等) 數值都和原程序一致,但是是一個全新的程序,並作為原程序的子程序

資料的恢復:

將備份檔案 (dump.rdb) 移動到 redis 安裝目錄並啟動服務即可

如何獲取目錄:

訪問Redis客戶端
./redis-cli

輸入dir獲取目錄
dir

優點

適合大規模的資料恢復

對資料完整性和一致性要求不高

缺點

在一定間隔時間做一次備份,所以如果redis意外down掉的話,就 會丟失最後一次快照後的所有修改

Fork的時候,記憶體中的資料被克隆了一份,大致2倍的膨脹性需要考慮


AOF:

原理

以日誌的形式來記錄每個寫操作,將Redis執行過的所有寫指令記錄下來(讀操作不記錄),

只許追加檔案但不可以改寫檔案,redis啟動之初會讀取該檔案重新構建資料,換言之,redis

重啟的話就根據日誌檔案的內容將寫指令從前到後執行一次以完成資料的恢復工作

儲存位置 & 位置配置

Aof儲存的是appendonly.aof檔案

AOF啟動/修復/恢復

正常恢復

啟動:設定Yes  修改預設的appendonly no,改為yes將有資料的aof檔案複製一份儲存到對應目錄(config get dir)
恢復:重啟redis然後重新載入

異常恢復

啟動:設定Yes   修改預設的appendonly no,改為yes備份被寫壞的AOF檔案
修復:Redis-check-aof --fix進行修復
恢復:重啟redis然後重新載入

優勢

每修改同步:appendfsync always 同步持久化 每次發生資料變更會被立即記錄到磁碟 效能較差但資料完整性比較好
每秒同步:appendfsync everysec 非同步操作,每秒記錄 如果一秒內宕機,有資料丟失
不同步:appendfsync no 從不同步

劣勢

相同資料集的資料而言aof檔案要遠大於rdb檔案,恢復速度慢於rdb
Aof執行效率要慢於rdb,每秒同步策略效率較好,不同步效率和rdb相同

實際應用:

整理我們的理解及處理方式

1、RDB持久化方式能夠在指定的時間間隔能對你的資料進行快照儲存

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

只做快取

如果你只希望你的資料在伺服器執行的時候存在,你也可以不使用任何持久化方式.

同時開啟兩種持久化方式

1、在這種情況下,當redis重啟的時候會優先載入AOF檔案來恢復原始的資料, 因為在通常情況下AOF檔案儲存的資料集要比RDB檔案儲存的資料集要完整.

2、RDB的資料不實時,同時使用兩者時伺服器重啟也只會找AOF檔案。那要不要只使用AOF呢?作者建議不要,因為RDB更適合用於備份資料庫(AOF在不斷變化不好備份), 快速重啟,而且不會有AOF可能潛在的bug,留著作為一個萬一的手段。

效能建議

1、因為RDB檔案只用作後備用途,建議只在Slave上持久化RDB檔案,而且只要15分鐘備份一次就夠了,只保留save 900 1這條規則。

2、如果Enalbe AOF,好處是在最惡劣情況下也只會丟失不超過兩秒資料,啟動指令碼較簡單隻load自己的AOF檔案就可以了。代價一是帶來了持續的IO,二是AOF rewrite的最後將rewrite過程中產生的新資料寫到新檔案造成的阻塞幾乎是不可避免的。只要硬碟許可,應該儘量減少AOF rewrite的頻率,AOF重寫的基礎大小預設值64M太小了,可以設到5G以上。預設超過原大小100%大小時重寫可以改到適當的數值。

3、如果不Enable AOF ,僅靠Master-Slave Replication 實現高可用性也可以。能省掉一大筆IO也減少了rewrite時帶來的系統波動。代價是如果Master/Slave同時倒掉,會丟失十幾分鐘的資料,啟動指令碼也要比較兩個Master/Slave中的RDB檔案,載入較新的那個。新浪微博就選用了這種架構