Redis篇 - 5. redis 持久化之 RDB & AOF

Redis 持久化實現方式ios


  • 快照
    對數據某一時間點的完整備份。例如Linux 快照備份、Redis RDB、MySQL Dump。
  • 日誌
    將數據的全部操做都記錄到日誌中,須要恢復時,將日誌從新執行一次。MySQL biglog、Redis AOF。
RDB

什麼是 RDB

將redis內存中的數據,完整的生成一個快照,以.rdb結尾的文件保存在硬盤上,當須要恢復時,再從文件加載到內存中。redis

RDB 三種觸發方式
  • save命令觸發(同步)
[vagrant@tmwy ~]$ redis-cli
127.0.0.1:6379> save
OK

save執行時,會形成Redis的阻塞。全部數據操做命令都要排隊等待它完成。
文件策略:新生成一個新的臨時文件,當save執行完後,用新的替換老的。緩存

  • bgsave命令觸發(異步)
[vagrant@tmwy ~]$ redis-cli
127.0.0.1:6379> bgsave
Background saving started

客戶端對Redis服務器下達bgsave命令時,Redis會fork出一個子進程進行rdb文件的生成。當文件生成完畢後,子進程再反饋給主進程。fork子進程時也會阻塞,不過正常狀況下fork過程都很是快的。
文件策略:與save命令相同。安全

  • 配置文件配置規則自動觸發
配置 seconds changes 做用
save 900 1 900秒內改變1條數據、自動生成rdb文件
save 300 10 300秒內改變10條數據、自動生成rdb文件
save 60 10000 60秒內改變10000條數據、自動生成rdb文件

PS: 這三種規則都不建議使用。服務器

RDB 自動規則配置

# 配置自動生成規則。通常不建議配置自動生成rdb文件
save 900 1
save 300 10
save 60 10000
# 指定rdb文件名
dbfilename dump-${port}.rdb
# 指定rdb文件目錄
dir /opt/redis/data
# bgsave發生錯誤,中止寫入
stop-writes-on-bgsave-error yes
# rdb文件採用壓縮格式
rdbcompression yes
# 對rdb文件進行校驗
rdbchecksum yes
RDB 不容忽略的觸發方式

  • 全量複製
    主從複製時,主會自動生成rdb文件(主從就是依據rdb文件進行數據同步)。
  • debug reload
    redis提供了debug級的重啓,不清空內存的一種重啓方式,也會生成rdb文件。
  • shutdown
    關閉redis會觸發rdb文件生成。
RDB 存在的問題

  • 耗時、耗內存、耗IO性能
    將內存中的數據所有dump到硬盤當中,耗時。bgsave的方式fork()子進程耗額外內存。大量的硬盤讀寫耗費IO性能。
  • 不可控、丟失數據
    宕機時,上次快照以後寫入的內存數據,將會丟失。
RDB 總結

  • RDB是Redis內存到硬盤的快照,用於持久化。
  • save一般會阻塞redis。
  • bgsave一般不會阻塞redis,可是會fork新進程。
  • save自動配置知足任一就會被執行。
  • 耗時、耗內存、耗IO性能
  • 不可控、丟失數據
AOF

什麼是 AOF

就是寫日誌,每次執行Redis寫命令,讓命令同時記錄日誌(以.aof結尾的日誌文件)。Redis宕機時,只要進行日誌回放就能夠恢復數據。微信

AOF 三種策略

首先redis執行寫命令將命令刷新到硬盤緩衝區中網絡

  • always
    老是讓緩衝區文件刷新到硬盤(即便性)。
  • everysec(推薦)
    每秒刷新一次緩衝區同步硬盤數據。
    對比always,在高寫入量的狀況下,能夠保護硬盤。出故障時會丟失一秒數據
  • no
    刷新策略讓系統決定(不可控)。
  • 三種策略對比
命令 優勢 缺點
always 不丟失數據 IO開銷大,通常的sata盤只有幾百TPS
everysec 只丟一秒數據 丟了一秒數據
no 系統決定 不可控,不知道何時刷盤,也不知道會丟失多少數據

一般使用everysec策略,這也是AOF的默認策略。app

AOF 重寫

AOF重寫就是把過時的、沒用的、重複的以及可優化的命令,進行化簡。只取最終有價值的結果。雖然寫入操做很頻繁,但系統定義的key的量是相對有限的。
AOF重寫能夠大大壓縮最終日誌文件的大小。從而減小磁盤佔用量,加快數據恢復速度。好比咱們有個計數的服務,有不少自增的操做,好比有一個key自增到1個億,對AOF文件來講就是一億次incr。AOF重寫就只用記1條記錄。運維

AOF 重寫兩種方式

  • bgrewriteaof 命令觸發AOF重寫
    redis客戶端向Redis發bgrewriteaof命令,redis服務端fork一個子進程去完成AOF重寫。這裏的AOF重寫,是將Redis內存中的數據進行一次回溯,回溯成AOF文件。而不是重寫AOF文件生成新的AOF文件去替換。
  • AOF 重寫配置異步

    • auto-aof-rewrite-min-size:AOF文件重寫須要的尺寸
    • auto-aof-rewrite-percentage:AOF文件增加
    • aof_current_size:統計AOF當前尺寸(單位:字節)
    • aof_base_size:AOF上次啓動和重寫的尺寸(單位:字節)
  • AOF自動重寫的觸發時機,需同時知足如下兩點:

    • aof_current_size > auto-aof-rewrite-min-size
    • aof_current_size - aof_base_size/aof_base_size > auto-aof-rewrite-percentage
AOF 重寫配置

# 開啓正常AOF的append刷盤操做
appendonly yes
# AOF文件名
appendfilename "appendonly-${port}.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 & AOF

RDB 對比 AOF

命令 RDB AOF 說明
啓動優先級 RDB和AOF都開啓的狀況下,Redis重啓後,選擇AOF進行恢復。大部分狀況下它保存了比RDB更新的數據
體積 RDB二進制模式存儲,並且作了壓縮。AOF雖然有AOF重寫,可是體積相對仍是大不少,畢竟它是記日誌形式
恢復速度 RDB體積小,恢復速度快。AOF體積大,恢復速度慢
數據安全 丟數據 根據策略決定 RDB丟上次快照後的數據,AOF根據always、everysec、no策略決定是否丟數據
輕重 AOF是追加日誌,因此比較輕的操做。而RDB是CPU密集型操做,對磁盤,以及fork時對內存的消耗都比較大
RDB 最佳策略

  • 建議關閉RDB
    不管是Redis主節點,仍是從節點,都建議關掉RDB。可是關掉不是絕對的,主從複製時仍是會藉助RDB。
  • 用做數據備份
    RDB雖然是很重的操做,可是對數據備份頗有做用。文件大小比較小,能夠按天或按小時進行數據備份。
  • 主從,從開?
    在極個別的場景下,須要在從節點開RDB,能夠再本地保存這樣子的一個歷史的RDB文件。雖然從節點不進行讀寫,可是Redis每每單機多部署,因爲RDB是個很重的操做,因此仍是會對CPU、硬盤和內存形成必定影響。根據實際需求進行設定。
AOF 最佳策略

  • 建議開啓AOF
    若是Redis數據只是用做數據源的緩存,而且緩存丟失後從數據源從新加載不會對數據源形成太大壓力,這種狀況下。AOF能夠關。
  • AOF重寫集中管理
    單機多部署狀況下,發生大量fork可能會內存爆滿。
  • everysec
    建議採用每秒刷盤策略
最佳策略

  • 小分片
    使用maxmemary對Redis最大內存進行規劃。
  • 緩存和存儲
    根據緩存和存儲的特性來決定使用哪一種策略
  • 監控(硬盤、內存、負載、網絡)
  • 足夠的內存
    不要把就機器所有的內存規劃給Redis。否則會出不少問題。像客戶端緩衝區等,不受maxmemary限制。規劃不當可能會產生SWAP、OOM等問題。
開發運維常見問題

fork 操做

fork是一個同步操做。執行bgsave和bgrewriteaof時都會執行fork操做

  • 改善fork

    • 優先使用物理機或者其餘能高效支持fork操做的虛擬化技術;
    • 控制Redis實例最大可用內存maxmemary;
      fork操做只是執行內存頁的拷貝,大部分狀況速度是比較快的。redis內存越大,內存頁越大。可使用maxmemary規劃redis內存,避免fork過慢。
    • 合理配置Linux內存分配策略:vm.overcommit_memory=1
      fork時若是內存不夠,會阻塞。Linux的vm.overcommit_memory默認爲0,不會分配額外內存
子進程開銷和優化

bgsave和bgrewriteaof會進行fork操做產生子進程。

  • CPU

    • 開銷:RDB和AOF文件生成屬於CPU密集型;
    • 優化:不作CPU綁定,不和CPU密集型應用部署在一塊兒;
  • 內存

    • 開銷:fork內存開銷
    • 優化:echo never > /sys/kernel/mm/transparent_hugepage/enabled
  • 硬盤

    • 開銷:AOF和RDB文件寫入,能夠結合iostat和iotao分析
    • 優化:

      • 不要和高硬盤負載服務部署在一塊兒:存儲服務、消息隊列;
      • no-appendfsync-on-rewrite=yes;
      • 根據寫入量決定磁盤類型:例如sdd;
      • 單機多實例持久化文件目錄能夠考慮分盤;
AOF 追加阻塞

AOF阻塞定位

  • redis日誌
Asynchronous AOF fsync is taking to long(disk is busy?). Writing the AOF 
buffer whitout waiting for fsync to complete, this may slow down Redis
  • info persistence
    能夠查看上述日誌發生的次數:
127.0.0.1:6379> info persistence
......
......
aof_delayed_fsync: 100
......
......

改善方式

同子進程的硬盤優化

PS: 更多文章請關注微信公衆號:浮話

相關文章
相關標籤/搜索