Redis基礎篇(四)持久化:內存快照(RDB)


AOF好處是每次執行只需要記錄操作命令,記錄量不大。但在故障恢復時,需要逐一執行AOF的操作命令,如果日志很大,恢復就很慢。

今天學習另一種持久化方式:內存快照。內存快照,是Redis某一時刻的狀態,以文件的形式保存在磁盤上。這個快照文件就稱為RDB文件,其中RDB就是Redis Database的縮寫。

當故障恢復時,只要把RDB文件讀入內存即可,恢復速度很快。但是內存快照並不是最優選項,為什么呢?

我們還需要考慮兩個問題:

  • 對哪些數據做快照?這關系到快照的執行效率;
  • 做快照時,數據還能被增刪改嗎?這關系到Redis是否被阻塞,能否同時正常處理請求。

對哪些數據做快照?

Redis的數據都在內存中,為了提供所有數據的可靠性保證,它執行的是全量快照。

Redis提供兩個命令生成RDB文件:

  • save:在主線程中執行,但會導致阻塞;
  • bgsave:創建一個子進程,專門用於寫入RDB文件,避免了主線程的阻塞。也是Redis RDB文件生成的默認配置。

做快照時,數據還能被增刪改嗎?

如果快照執行期間數據不能被修改,是會有潛在問題的。假如做快照的20s時間里,如果數據不能被修改,Redis就不能處理對這些數據的寫操作,那無疑就會給業務服務造成巨大影響。

Redis借助操作系統提供的寫時復制技術(Copy-On-Write,COW),在執行快照的同時,正常處理寫操作。

bgsave流程圖

bgsave子進程是由主線程fork生成的,可以共享主線程的所有內存數據。

當主線程要修改數據時,通過COW復制一份副本出來給bgsave子進程。

這既保證快照的完整性,也允許主線程同時對數據進行修改,避免了對正常業務的影響。

可以每秒做一次快照嗎?

如果內存快照每隔幾分鍾執行一次,這樣就可能出現丟失數據的風險。那么是否可以每秒做一次快照嗎?

如果頻繁地執行全量快照,會帶來兩方面開銷:

  • 一是頻繁將全量數據寫入磁盤,會給磁盤帶來很大壓力。
  • 二是bgsave子進程需要從主線程fork出來,fork創建過程本身會阻塞主線程,而且主線程的內存越大,阻塞時間越長。

既然頻繁執行全量快照不行,那還有什么其他好方法嗎?

第一個方法是做增量快照

在第一次做完全量快照后,T1和T2時刻如果再做快照,只需要將被修改的數據寫入快照文件就行了。如下圖所示:

image

第二個方法是Redis 4.0提出一個混合使用AOF日志和RDB快照的方法:RDB快照以一定的頻率執行,在兩次快照之間,使用AOF日志記錄這期間的所有命令操作。

T1和T2時刻的修改,用AOF日志記錄,等到第二次做全量快照時,就可以清空AOF日志,因為此時的修改都已經記錄到快照中了。如下圖所示:

image

拓展

使用一個2核CPU、4GB內存、500GB磁盤的雲主機運行Redis,Redis數據庫的數據量大小差不多是2GB,使用了RDB做持久化保證。當時Redis的運行負載以修改操作為主,寫讀比例差不多在8:2左右,也就是說,如果有100個請求,80個請求執行的是修改操作。在這個場景下,用RDB做持久化有什么風險嗎?

主要有兩方面風險:內存資源風險CPU資源風險

內存資源風險

Redis fork子進程做RDB持久化,由於寫的比例為80%,那么在持久化過程中,“寫時復制”會重新分配整個實例80%的內存副本,大約需要重新分配1.6GB內存空間,這樣整個系統的內存使用接近飽和。

如果此時父進程又有大量新key寫入,很快機器內存就會被吃光,如果機器開啟了Swap機制,那么Redis會有一部分數據被換到磁盤上。

當Redis訪問這部分在磁盤上的數據時,性能會急劇下降,已經達不到高性能的標准。

如果沒有開啟Swap,會直接觸發OOM,父子進程會面臨被系統kill掉的風險。

CPU資源風險

雖然子進程在做RDB持久化,但生成RDB快照過程會消耗大量的CPU資源。

雖然Redis處理請求是單線程的,但Redis Server還有其他線程在后台工作,例如AOF每秒刷盤、異步關閉文件描述符這些操作。

由於機器只有2核CPU,這也就是意味着父進程占用了超過一半的CPU資源。

此時子進程做RDB持久化,可能會產生CPU競爭,導致的結果是父進程處理請求延遲增大,子進程生成RDB快照的時間也會變長,整個Redis Server性能下降。

如果Redis進程綁定了CPU,那么子進程會繼續父進程的CPU親和性屬性,子進程必然會與父進程爭奪同一個CPU資源,整個Redis Server的性能必然會受到影響。

因此如果Redis需要開啟定時RDB和AOF重寫,進程一定不要綁定CPU。

參考資料


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM