解密Redis的持久化和主從複製機制

来源:http://www.cnblogs.com/shsxt/archive/2017/11/28/7911591.html
-Advertisement-
Play Games

各位小伙伴,上次講了《深入淺出Redis》和《Redis安裝和實際應用》本篇文章將為大家解密redis的持久化和主從複製機制。 Redis持久化 Redis 提供了多種不同級別的持久化方式: RDB 持久化可以在指定的時間間隔內生成數據集的時間點快照(point-in-time snapshot)。 ...


各位小伙伴,上次講了《深入淺出Redis》和《Redis安裝和實際應用》本篇文章將為大家解密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 文件
 

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

 
RDB save 操作
Rdb 是整個記憶體的壓縮的 snapshot,RDB 的數據結構,可以配置符合快照觸發條件,預設的是 1 分鐘內改動 1 萬次,或者 5 分鐘改動 10 次,或者是 15 分鐘改動一次;
Save 禁用:如果想禁用 RDB 持久化的策略,只要不設置任何 save 指令,或者是給 save 傳入一個空字元串參數也可以。
 
 -----> 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)
 
 
 
 
註意:
 
 
在實際工作生產的時候往往會出現:aof 文件損壞(網路傳輸或者其他問題導致 aof 文件破壞)
 
 
 
 
 
伺服器啟動報錯(但是 dump.rdb 文件是完整的) 說明啟動先載入 aof 文件
解決方案:執行命令 redis-check-aof --fix aof 文件 [自動檢查刪除不和 aof 語法的欄位]
 

Aof策略


 

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

Rewrite

概念:AOF 採用文件追加方式,文件會越來越來大為避免出現此種情況,新增了重寫機制,aof 文件的大小超過所設定的閾值時,redis 就會自動 aof 文件的內容壓縮,值保留可以恢複數據的最小指令集,可以使用命令 bgrewirteaof。
重寫原理:aof 文件持續增長而大時,會 fork 出一條新進程來將文件重寫(也就
是先寫臨時文件最後再 rename),遍歷新進程的記憶體中的數據,每條記錄有一條 set 語句,重寫 aof 文件的操作,並沒有讀取舊的的 aof 文件,而是將整個記憶體的資料庫內容用命令的方式重寫了一個新的 aof 文件,這點和快照有點類似。
觸發機制:redis 會記錄上次重寫的 aof 的大小,預設的配置當 aof 文件大小上次 rewrite 後大小的一倍且文件大於 64M 觸發(3G)
 

 
 
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
OK

只讀從伺服器

從 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>
 
 
好了本篇文章就為大家講解到這裡,感興趣的同學可以繼續關註我們,下一篇文章將為大家解密redis的sentinel(哨兵)機制和集群模式,小伙伴們期待下次見面good-bye!


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 平時都是用AS敲命令獲取簽名信息。。。還沒有在代碼中獲取過簽名~ 也算是老編程了,沒做過這個稍微有點尷尬。。。本著有好輪子就用的原則,網上找了幾篇博客,這塊內容已經很完善了,我也沒什麼可以優化的。。。 主要參(zhao)考(chao)了http://blog.csdn.net/hcwfc/artic ...
  • 開發中顏色的使用也是非常頻繁的,這裡推薦一個dsxNiubility大牛寫的顏色庫:Wonderful;它的好用就是很清楚的把每個常用的顏色進行了由淺到深的分層,讓我們使用時可以根據自己對顏色的深淺直接取顏色值;其中的功能我比較常用的就是顏色、跑馬燈和顏色漸變,裡面還有其他的功能,感興趣的可以去看下 ...
  • UIButton的預設佈局是:title在右,image在左; 很多時候我們需要的是title在左邊,或者title在下麵,這時就需要調整UIButton的TitleLabel和ImageView的位置了,查了很多資料,要麼零零散散的介紹,要麼就是特別複雜的實現;經過一段時間的學習,在這裡總結一下實 ...
  • 一個Hybrid APP,如何做離線緩存策略?也可以簡單來說,你的APP只是一個殼,裡面真正載入的內容是H5,如果優化載入內容的速度? ...
  • APP搜索頁基本上是少不了的,熱門搜索、搜索記錄等;這裡推薦一個大牛ko1o寫的:PYSearch,他還有一個不錯的圖片瀏覽開源:PYPhotoBrowser;這個也不錯,感興趣的可以瞭解下;下麵說下PYSearch的主要功能及(原Gitdemo)效果; 熱門搜索風格 PYHotSearchStyl ...
  • 新建一個OC語言的項目,然後添加一個基於NSObject的Swift文件SwiftFileModel類 .swift 這時會提示你是否添加橋接文件,點擊創建後體統會自動創建一個橋接文件,但是如果點擊取消後,就需要自己建橋接文件; 手動創建橋接文件 新建h文件,名字隨便起,但最好專業些,我這裡不專業 ...
  • 一、Mysql邏輯架構 引用自《高性能Mysql》 二、併發控制讀寫鎖:讀鎖是共用的,寫鎖是排他的,會阻塞其他的寫鎖和讀鎖。鎖粒度:表鎖、行級鎖三、事務事務(ACID特性):原子性、一致性、隔離性、持久性隔離級別 Read uncommitted未提交讀 事務中的修改,即使沒有提交,其他事務也是可見... ...
  • 一、配置MySQL資料庫 1、解壓綠色版mysql,並改名為mysql5.7,如下圖 對比一下下圖5.6以前的版本,少data目錄(存放數據)和my-default.ini文件(配置信息) 二、安裝服務 1、運行cmd(管理員版本,否則沒有許可權),如下圖 2、對於新版mysql5.7沒有了data目 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...