redis主從持久化討論


Redis有兩種持久化方式,AOF和RDB,AOF持久化是指追加寫命令到aof文件的方式,RDB是指定期保存內存快照到rdb文件的方式。

 

RDB雖然可以通過bgsave指令后台保存快照,但fork()子進程是有開銷的,在內存數據集較大的情況下會占用很長的cpu時間,fork新進程時,雖然可共享的數據內容不需要復制,但會復制之前進程空間的內存頁表,如果內存空間有40G(考慮每個頁表條目消耗 8 個字節),那么頁表大小就有80M,這個復制是需要時間的,在有的服務器結點上測試,35G的數據bgsave瞬間會阻塞200ms以上,一般建議Redis使用內存不超過20g。I/O消耗,我們線上是在Slave節點開啟rdb持久化,磁盤性能一般,1.2g的rdb文件持久化一分鍾一次,一次大概耗時30s左右,所以rdb的頻率也不能太頻繁,需要根據情況做好配置。

 

AOF是追加寫命令到aof文件的方式,優點是可以基本做到數據無損,缺點是文件增長較快,需要間歇性bgrewrite,bgrewrite也是一個既耗cpu又耗磁盤IO的操作,單cpu利用率最高可達100%。bgrewrite期間可以設置將新的寫請求暫時緩存,bgrewrite完成后同步寫盤,同步會暫時停止處理客戶端請求,如果bgrewrite時間較長,緩沖區積壓數據較多,核心阻塞時間會很長,所以如果必須要開啟aof,一般建議找幾個空閑時段設置腳本來做bgrewrite。

 

AOF還有一個比較坑的地方是刷盤策略fsync的設置,這個設置一般有3種方式:always、everysec、no,如果設置為no,就將寫盤的時機交給操作系統,這在很大程度上犧牲了aof數據無損的優勢,如果設置為always就意味着每條命令都會同步刷盤,會造成頻繁I/O,所以一般建議是設置everysec,Redis會默認每隔一秒進行一次fsync調用,將緩沖區中的數據寫到磁盤。但是當這一次的fsync調用時長超過1秒時。Redis會采取延遲fsync的策略,再等一秒鍾。也就是在兩秒后再進行fsync,這一次的fsync就不管會執行多長時間都會進行。這時候由於在fsync時文件描述符會被阻塞,所以當前的寫操作就會阻塞,因為是同步操作所以核心處理阻塞,開啟aof且要求Redis性能無損對磁盤有極高要求。下圖是我們一段時間內的磁盤監控截圖:

 

這種間歇性的磁盤IO毛刺就會使fsync阻塞,fsync阻塞時一般會輸出如下日志:


 

持久化為Redis提供了異常情況下的數據恢復機制,但開啟持久化是有代價的,哪一種持久化都可能造成CPU卡頓,影響對客戶端請求的處理。不開啟持久化又存在風險,如果一旦誤重啟master節點,或者試想這樣一種場景,主從切換失敗,很可能因為疏忽直接重啟master,這時沒有開啟持久化的master會把所有slave的數據清0。所以是否開啟持久化,怎樣開啟持久化是一個難題。和運維同事探討了一些方案,這里總結一下供大家參考:

 

1、極端情況下可以容忍全量數據丟失,那么建議master關閉持久化,slave關閉持久化;

 

2、極端情況下不能容忍全量數據丟失,但可以容忍部分數據丟失,如果內存數據集較小且不會增長建議master開啟rdb,slave開啟rdb;如果數據集很大,或不確定數據集增長趨勢,建議master關閉持久化,slave開啟rdb

開啟rdb需要cpu和磁盤性能保障。如果master關閉持久化,slave開啟rdb需要保證slave的rdb不會被master誤重啟所覆蓋,這里提供幾種方案:

 

  • 重啟腳本包一層命令先網絡請求加載備機備份目錄下的rdb文件后再執行start,可以防止誤重啟,但備機調整部署可能需要調整腳本,主機打開持久化也需要調整腳本

  • 定時將rdb文件通過網絡io傳給master節點(文件大比較耗時,文件增長需要考慮定時腳本執行間隔,否則會造成持續的網絡io),而且也會有一定數據損失

  • 定時備份Slave的rdb到備份目錄,不做任何其他操作,誤重啟時人工拷貝rdb到master節點(會有一定數據損失)

 

3、最大限度需要數據無損,建議master開啟aof,slave開啟aof

開啟aof需要cpu和磁盤性能保障。開啟aof建議fsync同步刷盤使用everysec,自定義腳本在應用空閑時定時做bgrewrite,bgrewrite期間增量數據做緩沖。

 

目前大部分業務都允許部分數據丟失,為使Redis性能最大化,關閉了Master持久化,slave開啟rdb,為防止誤重啟對rdb做了5分鍾一次備份,保留最近1小時的備份文件,必要時人工copy到master數據目錄下恢復數據。后續硬件性能提升后,看情況再調整持久化機制

 

tips:注意,一般是在命令行做主從,同時主關閉持久化

做主從:

redis-cli -h ip -p 6379
ip:6379>slaveof ip 6379

關閉持久化:

config set save ""

 


免責聲明!

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



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