天天看點

Redis持久化方式的選擇

本文将介紹Redis持久化的兩種方式:快照持久化和AOF持久化,并對兩種方法進行分析和對比,友善在實際中做出選擇。

Redis所有資料儲存在記憶體中,對資料的更新将異步地儲存到磁盤上,使得資料在Redis重新開機之後仍然存在。這麼做這有什麼實際意義呢?将資料存儲到硬碟是為了以後可以重用資料,将資料進行備份,可以在系統故障的時候從備份進行恢複。還有一點,存儲在Redis裡面的資料可能是經過複雜運算而得出的結果,把這些資料進行存儲,友善後續的使用,以達到“空間換時間”的效果。

Redis提供了兩種不同的持久化方法将資料儲存到硬碟裡面。

快照持久化:将Redis某一時刻存在的所有資料都寫入硬碟。

AOF持久化:AOF的全稱叫append-only file,中文意思是隻追加檔案。當使用AOF持久化方式的時候,Redis執行寫指令的時候,将被執行的寫指令複制到硬碟裡面,說的通俗一點就是寫日志。

Redis通過建立快照來獲得存儲在記憶體裡面的資料在某個時間節點上的副本。

save(同步)

bgsave(異步)

自動

save指令:用戶端向Redis發送save指令來建立一個快照檔案。

執行save指令的時候,如果存在老的快照檔案,新的将會替換老的。

bgsave指令:用戶端向Redis發送bgsave指令,Redis調用fork建立一個子程序,然後子程序負責将快照寫入硬碟,而父程序則繼續處理指令請求。

save指令和bgsave指令對比:

<col>

指令

save

bgsave

IO類型

同步

異步

是否阻塞

複雜度

O(n)

優點

不會消耗額外記憶體

不阻塞用戶端指令

缺點

阻塞用戶端指令

需要fork,消耗記憶體

自動生成:通過配置,滿足任何一個條件就會建立快照檔案。

快照持久化選項:

最佳配置:

耗時、耗性能:通過bgsave指令進行持久化的的時候,需要fork一個子程序,如果資料量很大的話,需要的記憶體也會相應的變大,記憶體的占用會導緻Redis性能降低。

不可控、丢失資料:舉個例子,上一次建立快照是11:00開始建立并建立成功。如果Redis在12:00開始建立新的快照,如果系統在未完成建立快照之前崩潰,11:00-12:00寫入的資料将會丢失;如果系統在快照建立完成之後崩潰,那麼12:00之後,建立快照的過程中的資料将會丢失。

AOF持久化将被執行的寫指令寫到AOF檔案的末尾,以達到記錄資料的目的。Redis隻要從頭到尾重新執行一次AOF所有的指令就可以恢複資料。

always:每條Redis寫指令都同步寫入硬碟。

everysec:每秒執行一次同步,将多個指令寫入硬碟。

no:由作業系統決定何時同步。

三種政策對比:生産環境中需要根據實際的需求進行選擇。

always

everysec

no

不丢失資料

每秒一次fsync

不用管

IO開銷較大,一般的SATA盤隻有幾百TPS

丢1s資料

不可控

随着Redis的運作,被執行的寫指令不斷同步到AOF檔案中,AOF檔案的體積越來越大,極端情況将會占滿所有的硬碟空間。如果AOF檔案體積過大,還原的過程也會相當耗時。為了解決AOF檔案不斷膨脹的問題,需要移除AOF檔案中的備援指令來重寫AOF。

原生AOF

AOF重寫

set hello world

set hello java

set hello redis

incr counter

inct counter

rpush mylist a

rpush mylist b

rpush mylist c

過期資料

set counter 2

rpush mylist a b c

AOF重寫的兩種實作方式:

bgrewriteaof指令

bgrewriteaof指令和bgsave指令的工作原理相似:Redis建立一個子程序,然後由子程序負責對AOF檔案進行重寫。

AOF重寫配置

配置參數說明:

名稱

含義

auto-aof-rewrite-min-size

AOF檔案重寫需要的尺寸

auto-aof-rewrite-percentage

AOF檔案增長率

具體配置:

快照持久化

AOF持久化

啟動優先級

體積

恢複速度

資料安全性

丢資料

根據政策決定

輕重

在實際生産環境中,根據資料量、應用對資料的安全要求、預算限制等不同情況,會有各種各樣的持久化政策;如完全不使用任何持久化、使用快照持久化或AOF持久化的一種,或同時開啟快照持久化和AOF持久化等。此外,持久化的選擇必須與Redis的主從政策一起考慮,因為主從複制與持久化同樣具有資料備份的功能,而且主機master和從機slave可以獨立的選擇持久化方案。

(1)如果Redis中的資料完全丢棄也沒有關系(如Redis完全用作DB層資料的cache),那麼無論是單機,還是主從架構,都可以不進行任何持久化。

(2)在單機環境下(對于個人開發者,這種情況可能比較常見),如果可以接受十幾分鐘或更多的資料丢失,選擇快照持久化對Redis的性能更加有利;如果隻能接受秒級别的資料丢失,應該選擇AOF。

(3)但在多數情況下,我們都會配置主從環境,slave的存在既可以實作資料的熱備,也可以進行讀寫分離分擔Redis讀請求,以及在master宕掉後繼續提供服務。在這種情況下,一種可行的做法是:master:完全關閉持久化,這樣可以讓master的性能達到最好slave:關閉快照持久化,開啟AOF(如果對資料安全要求不高,開啟快照持久化關閉AOF也可以),并定時對持久化檔案進行備份(如備份到其他檔案夾,并标記好備份的時間);然後關閉AOF的自動重寫,然後添加定時任務,在每天Redis閑時(如淩晨12點)調用bgrewriteaof。

[1] Josiah L.Carlson. Redis實戰[M]. 陳健宏譯. 北京:人民郵電出版社,2015.

[2] Redis持久化方案該如何選型

[3] 一站式學習Redis-從入門到高可用分布式實踐

由于部落客也是在攀登的路上,文中可能存在不當之處,歡迎各位多指教! 如果文章對您有用,那麼請點個”推薦“,以資鼓勵!

繼續閱讀