這篇文章咱們來介紹Redis高可用相關的機制。Redis要想實現高可用,主要有如下方面來保證:redis
這篇文章咱們先介紹Redis的高可用保障的基礎:數據持久化。由於Redis的主從複製和自動故障恢復,都須要依賴Redis持久化相關的東西。同時,Redis的數據持久化也能夠用來作數據備份,用來保障數據的安全性。數據庫
Redis是一個內存數據庫,它的數據都保存在內存中,若是實例宕機,那麼數據則所有丟失。如何保證數據的完整性和安全性也是提升服務高可用的重要機制之一。安全
Redis提供了完善的持久化機制,能夠把內存中的數據持久化到磁盤上,方便咱們進行備份數據和快速恢復數據。app
這篇文章咱們就來分析Redis的數據持久化是如何實現的?咱們常常聽的RDB和AOF有什麼區別?以及它們不一樣的使用場景。性能
Redis提供的數據持久化方式主要有2種:spa
它們分別對應了不一樣的使用場景,下面咱們就來依次分析。操作系統
介紹3d
RDB全稱 Redis Database Backup file(Redis數據備份文件),也被叫作 Redis 數據快照。日誌
咱們能夠經過執行save或bgsave命令讓 Redis 在本地生成RDB快照文件,這個RDB文件包含了整個實例接近完整的數據內容。它的優勢以下:code
它的缺點也很明顯:
所以RDB比較適用於如下場景:
Redis主從全量同步數據就是使用RDB文件進行的,咱們會在後面的文章詳細講到。
由此能夠看出,RDB很是適合作數據備份,咱們能夠定時讓Redis生成RDB文件,而後備份這個快照文件便可。
Redis也提供了定時觸發生成RDB文件的配置項:
# 最近15分鐘內 至少產生1次寫入 save 900 1 # 最近5分鐘內 至少產生10次寫入 save 300 10 # 最近1分鐘內 至少產生10000次寫入 save 60 10000
若是達到以上任意條件,則Redis會自動生成新的RDB文件,下降RDB數據內容與實例數據的差別。
在Redis上執行save和bgsave命令均可以生成RDB文件,但前者是在前臺執行的,也就是說在生成RDB文件時,會阻塞整個實例,在RDB未生成以前,任何請求都是沒法處理的,對於內存很大的實例,生成RDB文件很是耗時,顯然這是咱們不能接受的。
因此一般咱們會選擇執行bgsave讓Redis在後臺生成RDB文件,這樣Redis依舊能夠處理客戶端請求,不會阻塞整個實例。
但不是說後臺生成RDB就是沒有代價的,Redis爲了實現後臺把內存數據的快照寫入文件,採用了操做系統提供的Copy On Write技術,也就是咱們熟知的fork系統調用。
fork 系統調用會產生一個子進程,它與父進程共享相同的內存地址空間,這樣子進程在這一時刻就能擁有與父進程的相同的內存數據。
雖然子進程與父進程共享同一塊內存地址空間,但在fork子進程時,操做系統須要拷貝父進程的內存頁表給子進程,若是整個Redis實例內存佔用很大,那麼它的內存頁表也會很大,在拷貝時就會比較耗時,同時這個過程會消耗大量的CPU資源。在完成拷貝以前父進程也處於阻塞狀態,沒法處理客戶端請求。
fork執行完以後,子進程就能夠掃描自身全部的內存數據,而後把所有數據寫入到RDB文件中。
以後父進程依舊處理客戶端的請求,當在處理寫命令時,父進程會從新分配新的內存地址空間,從操做系統申請新的內存使用,再也不與子進程共享,這個過程就是Copy On Write(寫實複製)名字的由來。這樣父子進程的內存就會逐漸分離,父進程申請新的內存空間並更改內存數據,子進程的內存數據不受影響。
由此能夠看出,在生成RDB文件時,不只消耗CPU資源,還有須要佔用最多一倍的內存空間。
咱們在 Redis 執行info命令,能夠看到fork子進程的耗時,能夠經過這個耗時來評估fork時間是否符合預期。同時咱們應該保證Redis機器擁有足夠的CPU和內存資源,併合理設置生成RDB的時機。
介紹
AOF全稱爲Append Only File(追加日誌文件)。它與RDB不一樣的是,AOF中記錄的是每個命令的詳細信息,包括完整的命令類型、參數等。只要產生寫命令,就會實時寫入到AOF文件中。
咱們能夠經過配置文件開啓AOF:
# 開啓AOF appendonly yes # AOF文件名 appendfilename "appendonly.aof" # 文件刷盤方式 appendfsync everysec
開啓AOF後,Redis會把每一個寫操做的命令記錄到文件並持久化到磁盤中,爲了保證數據文件的安全性,Redis還提供了文件刷盤的時機:
以上能夠看出AOF相對於RDB的優勢是,AOF數據文件更新比較及時,比RDB保存更完整的數據,這樣在數據恢復時可以恢復儘可能完整的數據,下降丟失數據的風險。
若是同時存在RDB文件和AOF文件,Redis會優先使用AOF文件進行數據恢復。
但它的缺點也很易見:
針對第一種狀況,Redis提供了AOF瘦身的功能,能夠設置在AOF文件很大時,自動觸發AOF重寫,Redis會掃描整個實例的數據,從新生成一個AOF文件達成瘦身的效果。但這個重寫過程也須要消耗大量的CPU資源。
# AOF文件距離上次文件增加超過多少百分比則觸發重寫 auto-aof-rewrite-percentage 100 # AOF文件體積最小多大以上才觸發重寫 auto-aof-rewrite-min-size 64mb
因爲AOF能夠最大可能下降丟失數據的風險,因此它通常適用於對丟失數據很敏感的業務場景,例如涉及金錢交易的業務。
若是AOF的刷盤時機設置爲每次寫入都刷盤,那麼會大大下降Redis的寫入性能,由於每次寫命令都須要寫入文件並刷到磁盤中才會返回,當寫入量很大時,會增長磁盤IO的負擔。性能與數據安全不能兼得,雖然Redis提供了實時刷盤的機制,可是在真正場景中使用的很少。
一般咱們會選擇每秒刷盤這種方式,既能保證良好的寫入性能,在實例宕機時最多丟失1秒的數據,作到性能和安全的平衡。
咱們對RDB和AOF的總結以下表。咱們須要針對不一樣的業務場景選擇合適的持久化方式,也能夠根據RDB和AOF的優勢配合使用,保證Redis數據的安全性,又能夠兼顧它的性能。
做者:Kaito
連接:http://kaito-kidd.com/2020/06...