Redis應用學習(五)——Redis持久化的選擇與取捨

1. 持久化的做用

    1. 持久化:Redis運行時全部的數據都保存在內存中,對數據的更新將會異步的存儲到磁盤中,當Redis須要恢復數據時就加載磁盤中的數據linux

    2. 持久化的實現方式:redis

  • 快照:簡單來講,就相似於用一個照相機將某個時間點的Redis中的數據「拍攝」下來保存在「照片」中,「照片」就是快照文件,將快照保存在磁盤中,即實現持久化,具體實現好比MySQL數據庫中的MySQL  Dump功能和Redis  RDB功能
  • 日誌文件記錄:將對數據的更新操做所有記錄在一個日誌文件中,當須要恢復數據時,只須要從新執行一遍日誌中的操做便可,具體實現好比MySQL數據庫中的MySQL  Binlog功能和Redis  AOF功能

2. Redis中的數據持久化方式——RDB

    1. RDB:以快照方式來實現Redis數據的持久化操做,Redis執行一條RDB指令,生成一個RDB文件(二進制)並保存到硬盤中,該文件中保存了生成該文件時Redis中存儲的全部數據,當Redis須要恢復這些數據時(好比重啓)就能夠從新加載這個RDB文件來恢復數據。RDB文件還有另外一個用處,就是可使用該文件來實現數據複製。數據庫

    2. 生成RDB文件的觸發條件安全

  • save(同步):save,直接在客戶端中執行該命令,Redis就會生成一個RDB文件,同步執行指的是該命令會與普通命令同樣,在惟一的命令隊列(單線程)裏排隊,直到該命令執行完成以後(RDB文件生成完畢以後),纔會執行save命令以後的命令,也就是會發生同步阻塞,儘可能不用該命令來生成RDB文件,由於若是數據量過多,會引發長時間的阻塞;若是RDB文件存儲的目標路徑下有舊的RDB文件,那麼就會將新的RDB替換舊的;save操做的時間複雜度爲O(n)
  • bgsave(異步):bgsave,直接在客戶端中執行該命令,Redis就會生成一個RDB文件,異步執行指的是該命令不會與普通命令同樣佔用Redis的單線程執行,而是利用linux中的fork()函數(該函數依然會阻塞Redis主進程,不過該過程基本都很是快速)開闢一個Redis子進程來執行生成RDB文件,生成完成以後再返回給主進程RDB文件生成成功,在子進程生成RDB文件時,Redis會繼續處理命令隊列後續的命令;若是RDB文件存儲的目標路徑下有舊的RDB文件,那麼就會將新的RDB替換舊的;save操做的時間複雜度爲O(n)
  • 自動:自動即指不須要執行命令便可自動生成RDB文件,不過須要配置必定條件來觸發,須要配置seconds和changes兩個參數,表示在seconds秒內對Redis中的數據修改的changes條時就會生成RDB文件;該方式有必定的問題,就是有可能形成生成RDB文件頻率太高,進而致使對硬盤有必定的壓力,並且阻塞時間也會變多。

    3. 在redis.conf文件中對生成RDB文件的一些參數配置app

  • 自動生成RDB文件的seconds和changes兩個參數設置

  • 配置生成的RDB文件的文件名,默認爲dump.rdb

  • 配置RDB文件的存儲路徑,默認爲 ./ ,表示與redis.conf同級目錄下

  • 配置若是bgsave操做過程當中出現異常錯誤,則當即中止寫入數據到RDB文件中,默認爲yes,不建議改動
  • 生成RDB文件是否採用壓縮的格式,默認爲yes,不建議改動

  • 在加載RDB文件時是否對RDB文件進行校驗,默認爲yes,不建議改動

    4. 配置參數建議:異步

  • 刪除RDB自動生成配置參數,也就是把seconds和changes兩個參數設置所有刪除
  • 把dbfilename的參數設置爲dump-port.rdb,由於Redis是單線程,因此一臺機器上每每會部署多個Redis以充分利用多核處理器,而每一個Redis運行時會佔用不一樣的端口,因此須要依據不一樣端口來生成對應的RDB文件名,防止重複,好比dump-6379.rdb

    5. 必定會生成RDB文件的觸發條件函數

  • 全量複製:在進行主從複製時,主節點會自動生成RDB文件
  • debug reload:Redis中提供了一個debug級別的重啓方式,該方式不會清空內存中的數據,可是會生成一個RDB文件
  • shutdown:經過客戶端shutdown命令關Redis時,會自動生成一個RDB文件

    6. RDB存在的問題:性能

  • 耗時並且耗費性能:耗時是由於RDB文件生成時會將Redis中的全部數據所有存儲的RDB文件中,並且若是是採用save命令執行的話,耗時會更久;若是使用bgsave生成RDB文件,又會由於fork()函數消耗更多的性能;其次,自己生成RDB文件就是一個IO操做,若是數據量過多,那麼會形成很嚴重的性能消耗
  • 不可控,會發生數據丟失

3. Redis中的數據持久化方式——AOF

    1. AOF原理:以日誌文件記錄分數來實現數據持久化,即每當一條數據修改命令被執行後,都會將該命令寫入AOF文件中,當Redis須要回覆數據時,只須要從AOF文件中一條條的將命令取出並執行。優化

    2. AOF三種配置參數spa

  • always:每執行一條數據修改命令,都會將該命令寫入AOF文件中,不會丟失數據,可是性能不好,對於IO的開銷很大
  • everysec:每隔一秒將數據修改命令寫入AOF文件中,每次寫入AOF文件意味着會丟失至少一秒的數據,性能稍好,默認該AOF配置參數
  • no:由操做系統決定何時將數據修改命令寫入AOF文件,不可控

    3. AOF重寫:若是對一個文件持續不停地寫入數據,隨着文件愈來愈大,那麼IO速度也會愈來愈低,Redis提供了一個AOF重寫的功能來下降AOF文件大小的增加速度;在記錄的命令中,有不少是重複的、無用的、過時的命令,能夠將這些命令進行一些優化和刪減,好比對同一個key-value數據進行屢次set命令,那麼只須要記錄最後一次set命令便可,好比某個數據已通過期(expire),那麼該數據的相關語句就能夠刪除;經過對AOF文件進行AOF重寫就能夠減小磁盤佔用量,增長數據恢復速度

    4. AOF重寫的實現方式

  • bgrewriteaof:是一條客戶端執行命令,執行成功會返回給客戶端ok,和bgsave相似,會經過fork開闢一個子進程來進行AOF重寫,
  • 使用配置文件:在Redis的配置文件redis.conf中能夠經過auto-aof-rewrite-percentage(AOF文件增加率)和auto-aof-rewrite-min-size(AOF文件最大字節長度)兩個配置參數來實現自動AOF重寫;若是AOF文件的大小已經達到了auto-aof-rewrite-min-size,而且AOF文件大小的增加速度到達了auto-aof-rewrite-percentage,則會進行一次重寫。好比下圖中的配置參數auto-aof-rewrite-min-size 64mb表示AOF文件的大小要超過64mb,auto-aof-rewrite-percentage 100表示增加率要達到100%(若是上一次進行AOF重寫時AOF文件的大小爲100mb,那麼下一次AOF文件的大小爲200mb時就表示增加率爲100%),這兩個條件同時知足就會執行一次AOF重寫

    5. AOF功能的相關配置參數:在Redis的配置文件redis.conf中,除了上面的auto-aof-rewrite-percentage和auto-aof-rewrite-min-size

  • 修改appendonly爲yes;修改appendfilename爲"appendonly-port.aof"
  • port處寫Redis運行所佔用的端口號,該參數表示生成的AOF文件的名稱
  • 能夠修改appendfsync,但建議使用默認everysec
  • 修改dir,配置AOF文件的存儲目錄路徑,該目錄下也存儲RDB文件
  • 修改no-appendfsync-on-rewrite爲yes,表示是否在進行AOF重寫的同時,能夠進行AOF普通的命令append操做,yes表示不能進行(這樣會有更好的性能),具體取決因而否容許在AOF重寫期間丟失Redis執行的一些數據修改命令

4. Redis中的數據持久化方式AOF與RDB的選擇

    1. 比較RDB與AOF:

  • 加載優先級:Redis會優先加載AOF文件來恢復數據,其次是RDB文件
  • 文件體積:RDB文件較小,AOF文件較大,由於RDB文件採用二進制存儲,並且採用壓縮格式,因此體積較小
  • 數據恢復速度:RDB較快,AOF較慢
  • 安全性:AOF的存儲策略不一樣,不必定會丟失數據,好比always就不會丟失,但everysec就會丟失至少1秒的數據;RDB必定會丟失數據
  • RDB的讀寫操做性能消耗較大,而AOF的讀寫性能消耗相對小一點

    2. 依據以上對比,根據實際應用環境來進行選擇。

相關文章
相關標籤/搜索