08.04 Redis入門(三):Redis 持久化

Redis 持久化

  • 什麼是持久化 Redis的數據操作都是在內存中進行的,如果服務掛掉的話,數據會丟失。所謂持久化,就是將redis保存在內存中的數據,異步保存到磁盤上,以便在需要的時候,對數據進行恢復。
  • redis數據持久化方式 快照(RDB); 寫日誌(AOF)
  • Redis 還可以同時使用 AOF 持久化和 RDB 持久化。 在這種情況下, 當 Redis 重啟時, 它會優先使用 AOF 文件來還原數據集, 因為 AOF 文件保存的數據集通常比 RDB 文件所保存的數據集更完整
  • 持久化功能是可以關閉的,讓數據只在服務器運行時存在

RDB

  • 什麼是RDB
  • RDB Redis Database File, 將Redis內存中的數據,完整的生成一個快照,以二進制格式文件(.rdb文件)保存在硬盤當中。當需要進行恢復時,再從硬盤加載到內存中。
Redis入門(三):Redis 持久化

  • RDB的觸發方式

save(同步)

Redis入門(三):Redis 持久化

  • save命令觸發RDB快照持久化,命令會阻塞Redis服務,直至rdb文件生成結束
  • 如果已經存在rdb文件,則新生成的rdb文件會替換舊的rdb文件

bgsave(異步)

Redis入門(三):Redis 持久化

  • bgsave命令在觸發RDB持久化時,在fork()函數產生子進程的過程中,依然有可能短暫阻塞Redis服務
  • fork()出子進程,會消耗額外的內存,但是基本不會阻塞redis命令
  • config(滿足條件,自動觸發)
  • 在redis配置文件中,添加如下配置,在滿足條件時,會自動觸發RDB快照
  • 一般不推薦配置自動觸發RDB快照的持久化方式
  • # 配置自動生成規則。一般不建議配置自動生成RDB文件
  • save 900 1 #900秒內改變1條數據,自動生成RDB文件
  • save 300 10 #300秒內改變10條數據,自動生成RDB文件
  • save 60 10000 #60秒內改變1萬條數據,自動生成RDB文件
  • # 指定rdb文件名
  • dbfilename dump.rdb
  • # 指定rdb文件目錄
  • dir /opt/redis/data
  • # bgsave發生錯誤,停止寫入
  • stop-writes-on-bgsave-error yes
  • # rdb文件採用壓縮格式
  • rdbcompression yes
  • # 對rdb文件進行校驗
  • rdbchecksum yes

AOF

什麼是AOF

  • AOF Append Only File, 持久化記錄服務器執行的所有寫操作命令,並在服務器啟動時,通過重新執行這些命令來還原數據集。 AOF 文件中的命令全部以 Redis 協議的格式來保存,新命令會被追加到文件的末尾。 Redis 還可以在後臺對 AOF 文件進行重寫(rewrite),使得 AOF 文件的體積不會超出保存數據集狀態所需的實際大小。
Redis入門(三):Redis 持久化

  • 所有的寫入命令會追加到aof_buf(緩衝區)中
  • AOF緩衝區根據配置的策略向硬盤做同步操作
  • 隨著AOF文件越來越大,需要定期對AOF文件進行重寫,重寫可以壓縮AOF文件,也能使文件被更快的加載
  • 當Redis服務重啟時,可以加載AOF文件進行數據恢復
  • 命令寫入
  • Redis執行寫命令,將命令刷新到硬盤緩衝區當中
  • 所有寫入命令都包含追加操作,直接採用協議格式,避免二次處理開銷
  • 緩衝同步
  • always 命令寫入緩衝區後,立即調用同步操作,將寫命令追加到AOF文件,追加完成後,線程返回
  • everysec 讓緩衝區中的數據每秒刷新一次到AOF文件,相比always,在高寫入量的情況下,可以保護硬盤。出現故障可能會丟失一秒數據(這也是AOF的默認策略)
  • no 刷新策略讓操作系統來決定

AOF重寫

  • 隨著時間的推移,命令的逐步寫入。AOF文件也會逐漸變大。當我們用AOF來恢復時會很慢,而且當文件無限增大時,對硬盤的管理,對寫入的速度也會有產生影響。Redis當然考慮到這個問題,所以就有了AOF重寫
  • 原生AOF
  • set hello world
  • set hello java
  • set hello python
  • incr counter
  • incr counter
  • rpush mylist a
  • rpush mylist b
  • rpush mylist c
  • 過期數據
  • 重寫後的AOF
  • set hello python
  • set counter 2
  • rpush mylist a b c

AOF重寫的方式

  • bgrewriteaof 類似於RDB快照中,bgsave的執行過程;redis客戶端向Redis發bgrewriteaof命令,redis服務端fork一個子進程去完成AOF重寫。這裡的AOF重寫,是將Redis內存中的數據進行一次回溯,回溯成AOF文件。而不是重寫AOF文件生成新的AOF文件去替換
Redis入門(三):Redis 持久化

  • aof重寫配置 auto-aof-rewrite-min-size:AOF文件重寫需要的尺寸 auto-aof-rewrite-percentage:AOF文件增長率 redis提供了aof_current_size和aof_base_size,分別用來統計AOF當前尺寸(單位:字節)和AOF上次啟動和重寫的尺寸(單位:字節) AOF自動重寫的觸發時機,同時滿足以下兩點:
  • aof_current_size > auto-aof-rewrite-min-size
  • aof_current_size - aof_base_size/aof_base_size > auto-aof-rewrite-percentage
  • # 開啟正常AOF的append刷盤操作
  • appendonly yes
  • # AOF文件名
  • appendfilename "appendonly.aof"
  • # 每秒刷盤
  • appendfsync everysec
  • # 文件目錄
  • dir /opt/redis/data
  • # AOF重寫增長率
  • auto-aof-rewrite-percentage 100
  • # AOF重寫最小尺寸
  • auto-aof-rewrite-min-size 64mb
  • # AOF重寫期間是否暫停append操作。AOF重寫非常消耗磁盤性能,而正常的AOF過程中也會往磁盤刷數據。
  • # 通常偏向考慮性能,設為yes。萬一重寫失敗了,這期間正常AOF的數據會丟失,因為我們選擇了重寫期間放棄了正常AOF刷盤。
  • no-appendfsync-on-rewrite yes

持久化最佳策略

  • RDB最佳策略
  • 建議關閉RDB,無論是Redis主節點,還是從節點,都建議關掉RDB。但是關掉不是絕對的,主從複製時還是會藉助RDB
  • 用作數據備份,RDB雖然是很重的操作,但是對數據備份很有作用。文件大小比較小,可以按天或按小時進行數據備份
  • 在極個別的場景下,需要在從節點開RDB,可以再本地保存這樣子的一個歷史的RDB文件。雖然從節點不進行讀寫,但是Redis往往單機多部署,由於RDB是個很重的操作,所以還是會對CPU、硬盤和內存造成一定影響。根據實際需求進行設定
  • AOF最佳策略
  • 建議開啟AOF,如果Redis數據只是用作數據源的緩存,並且緩存丟失後從數據源重新加載不會對數據源造成太大壓力,這種情況下,AOF可以關
  • AOF重寫集中管理,單機多部署情況下,發生大量fork可能會內存爆滿
  • everysec 建議採用每秒刷盤策略

reference

  • http://redisdoc.com/topic/persistence.html
  • Redis持久化


分享到:


相關文章: