redis持久化與可用性

dy83 9年前發布 | 17K 次閱讀 Redis NoSQL數據庫

  redis對于持久化有快照及aof日志文件兩種形式。

  快照db文件,優點是二進制,大小比aof日志文件小。但會丟失最后一次成功備份時間到down機時間的數據。

  aof相比而言文件大小就大了點,但相對快照來講,不大容易丟失文件。

  目前redis檢查數據文件是否有錯對于快照及aof都能夠支持,但修復則只對aof文件有效。

 

  快照文件每次備份都是全量備份,原理是先fork出一個子進程,父子進程共享數據域。接著子進程開始將共享數據域中的數據寫入到一個臨時文件,寫完之后原子性的替換掉原先的備份db文件。如果在備份過程中,有新的寫請求進來,這時創建一個當前寫請求對應數據的副本頁面,新的寫請求更新在副本頁上。這就是 copy-on-write。這種方式當文件特別大時,不至于把內存撐爆。

  快照文件可以用bgsave及save來進行觸發,當然也可以配置每多少秒有多少寫請求就觸發備份,如 配置 save 100 1000 表示在100秒中有1000次寫就觸發備份。

 aof文件,是追加式的加入到aof未尾。每次redis接收到寫請求都會先寫入到內存中的buffer中,然后刷新到磁盤文件中。什么時刷新到磁盤文件中可以用appendfsync來進行配置。

 appendfsync的值可以是always,second,no。always表示寫請求進來時,馬上把數據寫到磁盤,這種方式當大量寫請求時會造成磁盤等待。second表示每秒中操作系統將buffer中的數據寫到磁盤。no,表明完全由操作系統控制寫入到磁盤的時間(這比較危險,不知道會失多少數據)。

 實際項目中用aof文件,定期做整理,aofrewrite,可以配置當aof文件增加多少倍或者達到最小大小時進行整理。

 

 前面是持久化內容,考慮如果讀請求很大,單臺redis無法提供高性能服務時。這時可以使用主/備服務,主redis負責接收寫請求與讀請求,并將寫請求同步到從redis。從redis只可讀。

 主/從redis同步數據,原理比較簡單,步聚如下:

 1.從redis發送一個sync命令給主master (從redis可以對外接受讀請求,也可以不接受)

 2.主master執行一個bgsave,生成最新的備份文件,這個過程中如果有新的寫請求則將它寫入到backlog。

 3.當主master生成最新備份db文件后,主master將它發送到從redis服務器

 4. 從redis服務器接收完備份文件后,替換掉原從redis內存中的數據,然后ack給主master

 5.主master最后將接受sync請求并且開始做bgsave起到從redis發回ack后這段時間的所有數據backlog發回到從redis

 6.從redis解析backlog,并放入到內存當中


 實踐過程中發現,當主/從進行同步時,主redis必定會生成一個最新的db后綴的備份文件。而aof文件則是只有當主master配置了appendonly為yes時這會

產生。假如主redis下同時存在aof和db備份文件,這時根據從redis是否支持aof來決定是否同步aof文件。

 還有一點需要特別注意的是,每次從slave重啟,那同步的數據文件是主master下整個文件。

 關于這點,可以自己實現解析aof文件來實現增量同步。

故障恢復:
主redis為 10.45.9.114,端口6001
從redis為 10.45.9.111,端口為6002


當主master掛了時,選擇slave做為主master,命令如下:
在slave上執行:
bgsave,并執行 slaveof no one
這里的slaveof no one不會序列化到配置文件,重啟后還是以配置文件中的設置為準

之后更新客戶端,使其指向新的master,即10.45.9.111這臺redis

master 10.45.9.114恢復后,將其做為新master的slave

這時查看數據文件是否損壞,這里用的是aof備份,因此使用命令:
./redis-check-aof /home/jbossas/Data/redis/redis-data/appendonly.aof
結果如下:
AOF analyzed: size=245, ok_up_to=245, diff=0
AOF is valid

如果aof文件損壞的壞,則需要使用以下命令來恢復:
./redis-check-aof --fix /home/jbossas/Data/redis/redis-data/appendonly.aof

之后設置10.45.9.114這臺機子的redis配置文件 slaveof為 slaveof 10.45.9.111 6002
 
之后重啟即可


redis優化

減少內存,redis在對以下集合:
 ZSETS,LISTS,HASHS
 當它們的元素數量及value大小小于某個限值時,會用zipList(數組)來減少內存存儲
 設置參數:
 list-max-ziplist-entries 512
 list-max-ziplist-value 64

 對于SETS也當元素個數小于某個限值時,也會存儲成一個數組,intSet
 設置參數:
 set-max-intset-entries 512


對于原有的集合,redis存儲數據時會比較占空間。

如list集合,redis采用一個鏈表來存

每個結點存儲一個數據,而這個結點需要額外的三個指針。這三個指針分別指向前結點,后結點以及當前數據域

 本文由用戶 dy83 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!