首頁  >  文章  >  資料庫  >  Redis的持久化與主從複製機制介紹

Redis的持久化與主從複製機制介紹

青灯夜游
青灯夜游轉載
2019-02-26 10:09:222102瀏覽

這篇文章帶給大家的內容是介紹redis的持久化和主從複製機制,有一定的參考價值,有需要的朋友可以參考一下,希望對你有幫助。

Redis持久化

Redis 提供了多種不同層級的持久化方式:

RDB 持久化可以在指定的時間間隔內產生資料集的時間點快照(point-in-time snapshot)

AOF 持久化記錄伺服器執行的所有寫入操作命令,並在伺服器啟動時,透過重新執行這些命令來還原資料集。 AOF 檔案中的指令全部以 Redis 協定的格式來儲存,新指令會被追加到檔案的結尾。 Redis 也可以在背景對 AOF 檔案進行重寫(rewrite),使得 AOF 檔案的體積不會超出保存資料集狀態所需的實際大小。

Redis 還可以同時使用 AOF 持久化和 RDB 持久化。在這種情況下, 當 Redis 重新啟動時, 它會優先使用 AOF 檔案來還原資料集, 因為 AOF 檔案保存的資料集通常比 RDB 檔案所保存的資料集更完整。
你甚至可以關閉持久化功能,讓資料只在伺服器運作時存在。

RDB(Redis DataBase)

#Rdb:在指定的時間間隔內將記憶體中的資料集快照寫入磁碟,也就是行話講的snapshot 快照,它恢復時就是將快照檔案直接讀到記憶體裡。

Redis 會單獨的創建(fork) 一個子進程來進行持久化,會先將資料寫入到一個臨時檔案中,待持久化過程結束了,再用這個臨時檔案替換上次持久化還的文件。整個過程總,主進程是不進行任何IO 操作,這就確保了極高的性能,如果需要進行大規模的資料恢復,且對於資料恢復的完整性不是非常敏感,那RDB 方法要比AOF 方式更加的高效能。 RDB 的缺點是最後一次持久化後的資料可能會遺失。

Fork 的作用是複製一個與當前進程一樣的進程,新進程的所有資料(變數、環境變數、程式計數器等)數值都和原始進程一致,但是是一個全新的進程,並作為原進程的子程序

隱患:若目前的進程的資料量龐大,那麼fork 之後資料量*2,此時就會造成伺服器壓力大,運作效能降低。

Rdb 儲存的是dump.rdb 檔案

Redis的持久化與主從複製機制介紹

#在測試:執行flushAll 指令, 使用shutDown直接關閉進程時,第二次開啟時redis 會自動讀取dump.rdb 文件,但恢復時,全為空。 (此時的原因:在關閉時刻,redis 系統會保存空的dump.rdb 替換原來的快取檔案。所以第二次開啟的redis系統時候,自動讀取的是空值檔案)

RDB save 操作

Rdb 是整個記憶體的壓縮的snapshot,RDB 的資料結構,可以配置符合快照觸發條件,預設的是1 分鐘內改變1萬次,或5 分鐘改動10 次,或是15 分鐘改動一次;
Save 停用:如果想要停用RDB 持久化的策略,只要不設定任何save 指令,或是給save 傳入一個空字串參數也可以。

Redis的持久化與主從複製機制介紹

-----> save 指令:即時儲存操作物件

如何觸發RDB 快照

Save:save 時只管保存,其他不管,全部阻塞。

Bgsave:redis 會在背景進行快照操作,快照操作的同時還可以回應客戶端的請求,可以透過 lastsave 指令取得最後一次成功執行快照的時間。

執行 fluhall 指令,也會產生 dump.rdb 文件,但裡面是空的。

如何恢復:

將備份檔案(dump.rdb)移至redis 安裝目錄並啟動服務即可
Config get dir 指令可取得目錄

如何停止

動態停止RDB 儲存規則的方法:redis -cli config set save “”

AOF(Append Only File)

以日誌的形式倆記錄每個寫入操作,將redis 執行過的所有寫入指令記錄下來(讀取操作不記錄)。只許追加文件但不可以改寫文件,redis 啟動之初會讀取該文件重新構建數據,換言之,redis重啟的話就根據日誌文件的內容將寫指令從前到後執行一次一完成數據恢復工作。
======APPEND ONLY MODE=====

開啟aof :appendonly yes  (預設為no)

Redis的持久化與主從複製機制介紹

注意:

在實際工作生產的時候往往會出現:aof 檔案損壞(網路傳輸或其他問題導致aof 檔案破壞)

Redis的持久化與主從複製機制介紹

伺服器啟動報錯(但是dump.rdb 檔案是完整的) 說明啟動先載入aof 檔案

解決方案:執行指令redis-check-aof --fix aof 檔案[自動檢查刪除不和aof 語法的欄位]

Aof策略

Redis的持久化與主從複製機制介紹

#Appendfsync 參數:

Always 同步持久化每次發生資料變更會立即記錄到磁碟,效能較差但資料完整性較好。
Everysec: 出廠預設推薦,非同步操作,每秒記錄,日過一秒宕機,有資料遺失
No:從不 fsync :將資料交給作業系統來處理。更快,也更不安全的選擇。

Rewrite

概念:AOF 採用檔案追加方式,檔案會越來越來大為避免此種情況,新增了重寫機制,aof 檔案的大小超過設定的閾值時,redis 就會自動aof 檔案的內容壓縮,值保留可以恢復資料的最小指令集,可以使用指令bgrewirteaof。

重寫原理:aof 檔案持續成長而大時,會fork 出一條新進程來將檔案重寫(也就
是先寫臨時檔案最後再rename),遍歷新進程的內存中的數據,每筆記錄有一條set 語句,重寫aof 文件的操作,並沒有讀取舊的的aof 文件,而是將整個內存的數據庫內容用命令的方式重寫了一個新的aof 文件,這點和快照有點類似。

觸發機制:redis 會記錄上次重寫的aof 的大小,預設的設定當aof 檔案大小上次rewrite 後大小的一倍且檔案大於64M 觸發(3G)

Redis的持久化與主從複製機制介紹

#no-appendfsync-on-rewrite no : 重寫時是否可以運用Appendfsync 用預設no 即可,確保資料安全
auto-aof-rewrite-percentage  倍數設定基準值
auto-aof-rewrite-min-size  設定基準值大小

AOF優點

使用AOF 持久化會讓Redis 變得非常耐久性:你可以設定不同的fsync 策略,例如無fsync ,每秒鐘一次fsync ,或是每次執行寫入指令時fsync 。 AOF 的預設策略為每秒鐘fsync 一次,在這種配置下,Redis 仍然可以保持良好的效能,並且就算發生故障停機,也最多只會丟失一秒鐘的資料( fsync 會在後台執行緒執行,所以主線程可以繼續努力地處理命令請求)。

AOF 檔案是一個只進行追加操作的日誌檔案(append only log), 因此對AOF 檔案的寫入不需要進行seek , 即使日誌因為某些原因而包含了未寫入完整的命令(例如寫入時磁碟已滿,寫入中途停機,等等), redis-check-aof 工具也可以輕易地修復這種問題。

Redis 可以在 AOF 檔案體積變得過大時,自動地在背景對 AOF 進行重寫: 重寫後的新 AOF 檔案包含了恢復目前資料集所需的最小指令集。整個重寫操作是絕對安全的,因為Redis 在建立新AOF 檔案的過程中,會繼續將命令追加到現有的AOF 檔案裡面,即使重寫過程中發生停機,現有的AOF 檔案也不會遺失。而一旦新 AOF 文件創建完畢,Redis 就會從舊 AOF 文件切換到新 AOF 文件,並開始對新 AOF 文件進行追加操作。

AOF 檔案有序地保存了對資料庫執行的所有寫入操作, 這些寫入操作以Redis 協定的格式保存, 因此AOF 檔案的內容非常容易被人讀懂, 對檔案進行分析( parse)也很輕鬆。匯出(export) AOF 檔案也非常簡單: 舉個例子, 如果你不小心執行了FLUSHALL 指令, 但只要AOF 檔案未被重寫, 那麼只要停止伺服器, 移除AOF 檔案末尾的FLUSHALL 指令, 並重啟Redis ,就可以將資料集還原到FLUSHALL 執行之前的狀態。

AOF缺點

對於相同的資料集來說,AOF 檔案的體積通常大於 RDB 檔案的體積。

根據所使用的 fsync 策略,AOF 的速度可能會慢於 RDB 。在一般情況下, 每秒 fsync 的效能依然非常高, 而關閉 fsync 可以讓 AOF 的速度和 RDB 一樣快, 即使在高負載之下也是如此。不過在處理巨大的寫入載入時,RDB 可以提供更有保證的最大延遲時間(latency)。

AOF 在過去曾經發生過這樣的 bug : 因為個別指令的原因,導致 AOF 檔案在重新載入時,無法將資料集還原成保存時的原樣。 (舉個例子,阻塞指令 BRPOPLPUSH 就曾經引起過這樣的 bug 。)

測試套件裡為這種情況添加了測試: 它們會自動產生隨機的、複雜的資料集,並透過重新載入這些資料來確保一切正常。雖然這種 bug 在 AOF 檔案中並不常見, 但對比來說, RDB 幾乎是不可能出現這種 bug 的。

備份Redis 資料

一定要備份你的資料庫!

磁碟故障, 節點失效, 諸如此類的問題都可能讓你的資料消失不見, 不進行備份是非常危險的。

Redis 對於資料備份是非常友善的, 因為你可以在伺服器運行的時候對 RDB 檔案進行複製: RDB 檔案一旦被創建, 就不會進行任何修改。當伺服器要建立新的 RDB 檔案時, 它先將檔案的內容保存在一個暫存檔案裡面, 當暫存檔案寫入完畢時, 程式才使用 rename(2) 原子地用暫存檔案取代原來的 RDB 檔案。

這也就是說, 無論何時, 複製 RDB 檔案都是絕對安全的。

建議:

建立一個定期任務(cron job), 每小時將一個RDB 檔案備份到一個資料夾,並且每天將一個RDB 檔案備份到另一個資料夾。

確保快照的備份都帶有相應的日期和時間信息, 每次執行定期任務腳本時, 使用find 命令來刪除過期的快照: 例如說, 你可以保留最近48 小時內的每小時快照, 還可以保留最近一兩個月的每日快照。

至少每天一次, 將 RDB 備份到你的資料中心之外, 或至少是備份到你執行 Redis 伺服器的實體機器之外。

容災備份

Redis 的容災備份基本上就是對資料進行備份, 並將這些備份傳送到多個不同的外部資料中心。

容災備份可以在 Redis 運作並產生快照的主資料中心發生嚴重的問題時, 仍然讓資料處於安全狀態。

有的Redis 用戶是創業者, 他們沒有大把大把的錢可以浪費, 所以下面介紹的都是一些實用又便宜的容災備份方法:

Amazon S3 ,以及其他類似S3 的服務,是建立災難備份系統的好地方。最簡單的方法就是將你的每小時或每日 RDB 備份加密並傳送到 S3 。資料的加密可以透過 gpg -c 指令來完成(對稱加密模式)。記得把你的密碼放到幾個不同的、安全的地方去(例如你可以把密碼複製給你組織裡最重要的人物)。同時使用多個儲存服務來保存資料文件,可以提升資料的安全性。

傳送快照可以使用 SCP 來完成(SSH 的元件)。以下是簡單且安全的傳送方法: 買一個離你的資料中心非常遠的VPS(虛擬專用伺服器) , 裝上SSH , 建立一個無口令的SSH 客戶端key , 並將這個key 新增到VPS 的authorized_keys 檔案中, 這樣就可以傳送快照備份檔到這個VPS 到了。為了達到最好的資料安全性,至少要從兩個不同的供應商那裡各購買一個 VPS 來進行資料容災備份。

要注意的是, 這類容災系統如果沒有小心處理的話, 是很容易失效的。

最低限度下, 你應該在檔案傳送完畢之後, 檢查所傳送備份檔案的體積和原始快照檔案的體積是否相同。如果你使用的是 VPS , 那麼也可以透過比對檔案的 SHA1 校驗和來確認檔案是否傳送完整。

另外, 你還需要一個獨立的警報系統, 讓它在負責傳送備份檔案的傳送器(transfer)失靈時通知你。

Redis 主從複製

Redis 支援簡單且易用的主從複製(master-slave replication)功能, 此功能可以讓從伺服器(slave server)成為主伺服器(master server)的精確複製。

以下是 Redis 複製功能的幾個重要面向:

Redis 使用非同步複製。從 Redis 2.8 開始, 從伺服器會以每秒一次的頻率向主伺服器報告複製流(replication stream)的處理進度。

一個主伺服器可以有多個從伺服器。

不只主伺服器可以有從伺服器, 從伺服器也可以有自己的從伺服器, 多個從伺服器之間可以構成一個圖狀結構。

複製功能不會阻塞主伺服器: 即使有一個或多個從伺服器正在進行初次同步, 主伺服器也可以繼續處理命令請求。

複製功能也不會阻塞從伺服器: 只要在 redis.conf 檔案中進行了相應的設置, 即使從伺服器正在進行初次同步, 伺服器也可以使用舊版本的資料集來處理命令查詢。

不過, 在從伺服器刪除舊版資料集並載入新版本資料集的那段時間內, 連線請求會被阻塞。

你也可以設定從伺服器, 讓它在與主伺服器之間的連線中斷時, 傳送一個錯誤到客戶端。

複製功能可以單純地用於資料冗餘(data redundancy), 也可以透過讓多個從伺服器處理唯讀指令請求來提升擴充功能(scalability): 例如說, 繁重的SORT 指令可以交給附屬節點去運行。
可以透過複製功能來讓主伺服器免於執行持久化操作: 只要關閉主伺服器的持久化功能, 然後由伺服器去執行持久化操作即可。

關閉主伺服器持久化時,複製功能的資料安全。

當配置Redis複製功能時,強烈建議開啟主伺服器的持久化功能。否則的話,由於延遲等問題,部署的服務應該要避免自動拉起。

案例:

  1. 假設節點A為主伺服器,並且關閉了持久化。並且節點B和節點C從節點A複製資料

  2. 節點A崩潰,然後由自動拉起服務重啟了節點A. 由於節點A的持久化被關閉了,所以重啟之後沒有任何數據

  3. 節點B和節點C將從節點A複製數據,但是A的數據是空的, 於是就把自身保存的數據副本刪除。

在關閉主伺服器上的持久化,並同時開啟自動拉起進程的情況下,即便使用Sentinel來實現Redis的高可用性,也是非常危險的。因為主伺服器可能拉起得非常快,以至於Sentinel在配置的心跳時間間隔內沒有偵測到主伺服器已重啟,然後還是會執行上面的資料遺失的流程。

無論何時,資料安全都是極為重要的,所以應該禁止主伺服器關閉持久化的同時自動拉起。

從伺服器設定

設定一個從伺服器非常簡單, 只要在設定檔中增加以下的這一行就可以了:
slaveof 192.168.1.1 6379
另外一種方法是呼叫SLAVEOF 命令,輸入主伺服器的IP 和端口,然後同步就會開始
127.0.0.1:6379> SLAVEOF 192.168.1.1 10086

只讀從伺服器

從Redis 2.6 開始, 從伺服器支援唯讀模式, 且該模式為從伺服器的預設模式。

唯讀模式由 redis.conf 檔案中的 slave-read-only 選項控制, 也可以透過 CONFIG SET 指令來開啟或關閉這個模式。

只讀從伺服器會拒絕執行任何寫入命令, 所以不會出現因為操作失誤而將資料不小心寫入到了從伺服器的情況。

另外,對一個從屬伺服器執行指令 SLAVEOF NO ONE 將使得這個從屬伺服器關閉複製功能,並從從屬伺服器轉變回主伺服器,原來同步所得的資料集不會被丟棄。

利用『 SLAVEOF NO ONE 不會丟棄同步所得資料集』這個特性,可以在主伺服器失敗的時候,將從屬伺服器用作新的主伺服器,從而實現無間斷運作。

從伺服器相關配置:

如果主伺服器透過requirepass 選項設定了密碼, 那麼為了讓從伺服器的同步操作可以順利進行, 我們也必須為從伺服器進行相應的身份驗證設定。

對於一個正在運行的伺服器, 可以使用客戶端輸入以下命令:

config set masterauth
要永久地設定這個密碼, 那麼可以將它加入到設定檔中:
masterauth

主伺服器只在有至少N 個從伺服器的情況下,才執行寫入操作

從Redis 2.8 開始, 為了確保資料的安全性,可以透過配置, 讓主伺服器只在有至少N 個目前已連接從伺服器的情況下, 才執行寫入指令。

不過, 因為 Redis 使用非同步複製, 所以主伺服器發送的寫入資料不一定會被從伺服器接收到, 因此, 資料遺失的可能性仍然是存在的。

以下是這個特性的運作原理:

#從伺服器以每秒一次的頻率PING 主伺服器一次, 並報告複製流的處理情況。

主伺服器會記錄各個從伺服器最後一次傳送 PING 到它的時間。

使用者可以透過配置, 指定網路延遲的最大值 min-slaves-max-lag , 以及執行寫入操作所需的至少從伺服器數量 min-slaves-to-write 。

如果至少有min-slaves-to-write 個從伺服器, 且這些伺服器的延遲值都少於min-slaves-max-lag 秒, 那麼主伺服器就會執行客戶端請求的寫入操作。

另一方面, 如果條件無法達到min-slaves-to-write 和min-slaves-max-lag 所指定的條件, 那麼寫入操作就不會被執行, 主伺服器會向請求執行寫入操作的客戶端回傳一個錯誤。

以下是這個特性的兩個選項和它們所需的參數:

min-slaves-to-write <number of slaves>
min-slaves-max-lag <number of seconds>

以上就是這篇文章的全部內容,希望能對大家的學習有所幫助。更多精彩內容大家可以追蹤php中文網相關教學欄位! ! !

以上是Redis的持久化與主從複製機制介紹的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:https://segmentfault.com/a/1190000012196599。如有侵權,請聯絡admin@php.cn刪除