一、過時(expire命令)html
設置了失效時間的元素,對於DEL/SET/GETSET/*STORE這些會刪除或者從新設置元素的命令,若是失效時間沒有到時,失效時間會被清理。對於其餘命令如,LPUSH,DECR等不會清理掉元素的失效時間。redis
能夠經過PERSIST設置元素爲非失效時間元素。數據庫
RENAME設置元素時,無論被設置的新的元素是否存在,被從新設置的新的元素都會使用原來元素的失效時間設置或者繼承原來元素的全部屬性。安全
在已經存在失效時間的元素上調用EXPIRE時,對應該元素的失效時間會被從新設置成新設置的值。bash
redis2.6以前失效時間清理的延時可能在0~1s內,以後就能夠控制在0~1ms了。redis的失效時間是經過設置絕對的系統timestamps時間,若是主從複製時,節點的時間存在大的時間差,那就會存在數據不一致的問題。服務器
redis隨機檢查20個設置了失效時間的元素,刪除已經失效的元素,若是存在25%的元素失效,那麼redis會重複這個動做。redis會在1s中重複10次這個檢查。app
主從同步時,若是元素失效時,master節點經過在AOF文件和全部的slave節點發送DEL命令,經過這種方式,由master爲中心,slave節點會等待master發送DEL命令,保證了數據的一致。在集羣中若是slave被選舉爲master,對於失效的元素,該節點作爲master就能夠當即刪除失效的元素了。工具
二、持久化post
持久化支持RDB和AOF方式性能
Redis 提供了多種不一樣級別的持久化方式:
- RDB 持久化能夠在指定的時間間隔內生成數據集的時間點快照(point-in-time snapshot)。
- AOF 持久化記錄服務器執行的全部寫操做命令,並在服務器啓動時,經過從新執行這些命令來還原數據集。 AOF 文件中的命令所有以 Redis 協議的格式來保存,新命令會被追加到文件的末尾。 Redis 還能夠在後臺對 AOF 文件進行重寫(rewrite),使得 AOF 文件的體積不會超出保存數據集狀態所需的實際大小。
- Redis 還能夠同時使用 AOF 持久化和 RDB 持久化。 在這種狀況下, 當 Redis 重啓時, 它會優先使用 AOF 文件來還原數據集, 由於 AOF 文件保存的數據集一般比 RDB 文件所保存的數據集更完整。
- 你甚至能夠關閉持久化功能,讓數據只在服務器運行時存在。
redis在啓動的時候,默認會去加載RDB文件(在AOF持久化未開啓的狀況下)快照文件,而且在完成加載後纔等待客戶端的鏈接。
[7084] 13 Jul 17:31:16.875 # Server started, Redis version 3.0.501 [7084] 13 Jul 17:31:16.875 * DB loaded from disk: 0.000 seconds [7084] 13 Jul 17:31:16.875 * The server is now ready to accept connections on port 6379
若是配置文件中設置AOF方式,即「appendonly yes」,redis會去加載aof文件,一樣是在完成加載後纔等待客戶端的鏈接,這個時候就不會加載RDB文件了。
[6540] 13 Jul 17:28:33.504 # Server started, Redis version 3.0.501 [6540] 13 Jul 17:28:45.563 * DB loaded from append only file: 12.059 seconds [6540] 13 Jul 17:28:45.563 * The server is now ready to accept connections on port 6379
三、RDB和AOF方式的優缺點
RDB 的優勢
- RDB 是一個很是緊湊(compact)的文件,它保存了 Redis 在某個時間點上的數據集。 這種文件很是適合用於進行備份: 好比說,你能夠在最近的 24 小時內,每小時備份一次 RDB 文件,而且在每月的每一天,也備份一個 RDB 文件。 這樣的話,即便趕上問題,也能夠隨時將數據集還原到不一樣的版本。
- RDB 很是適用於災難恢復(disaster recovery):它只有一個文件,而且內容都很是緊湊,能夠(在加密後)將它傳送到別的數據中心,或者亞馬遜 S3 中。
- RDB 能夠最大化 Redis 的性能:父進程在保存 RDB 文件時惟一要作的就是
fork
出一個子進程,而後這個子進程就會處理接下來的全部保存工做,父進程無須執行任何磁盤 I/O 操做。- RDB 在恢復大數據集時的速度比 AOF 的恢復速度要快。
RDB 的缺點
- 若是你須要儘可能避免在服務器故障時丟失數據,那麼 RDB 不適合你。 雖然 Redis 容許你設置不一樣的保存點(save point)來控制保存 RDB 文件的頻率, 可是, 由於RDB 文件須要保存整個數據集的狀態, 因此它並非一個輕鬆的操做。 所以你可能會至少 5 分鐘才保存一次 RDB 文件。 在這種狀況下, 一旦發生故障停機, 你就可能會丟失好幾分鐘的數據。
- 每次保存 RDB 的時候,Redis 都要
fork()
出一個子進程,並由子進程來進行實際的持久化工做。 在數據集比較龐大時,fork()
可能會很是耗時,形成服務器在某某毫秒內中止處理客戶端; 若是數據集很是巨大,而且 CPU 時間很是緊張的話,那麼這種中止時間甚至可能會長達整整一秒。 雖然 AOF 重寫也須要進行fork()
,但不管 AOF 重寫的執行間隔有多長,數據的耐久性都不會有任何損失。
AOF 的優勢
- 使用 AOF 持久化會讓 Redis 變得很是耐久(much more durable):你能夠設置不一樣的
fsync
策略,好比無fsync
,每秒鐘一次fsync
,或者每次執行寫入命令時fsync
。 AOF 的默認策略爲每秒鐘fsync
一次,在這種配置下,Redis 仍然能夠保持良好的性能,而且就算髮生故障停機,也最多隻會丟失一秒鐘的數據(fsync
會在後臺線程執行,因此主線程能夠繼續努力地處理命令請求)。- AOF 文件是一個只進行追加操做的日誌文件(append only log), 所以對 AOF 文件的寫入不須要進行
seek
, 即便日誌由於某些緣由而包含了未寫入完整的命令(好比寫入時磁盤已滿,寫入中途停機,等等),redis-check-aof
工具也能夠輕易地修復這種問題。- Redis 能夠在 AOF 文件體積變得過大時,自動地在後臺對 AOF 進行重寫: 重寫後的新 AOF 文件包含了恢復當前數據集所需的最小命令集合。 整個重寫操做是絕對安全的,由於 Redis 在建立新 AOF 文件的過程當中,會繼續將命令追加到現有的 AOF 文件裏面,即便重寫過程當中發生停機,現有的 AOF 文件也不會丟失。 而一旦新 AOF 文件建立完畢,Redis 就會從舊 AOF 文件切換到新 AOF 文件,並開始對新 AOF 文件進行追加操做。
- AOF 文件有序地保存了對數據庫執行的全部寫入操做, 這些寫入操做以 Redis 協議的格式保存, 所以 AOF 文件的內容很是容易被人讀懂, 對文件進行分析(parse)也很輕鬆。 導出(export) AOF 文件也很是簡單: 舉個例子, 若是你不當心執行了 FLUSHALL 命令, 但只要 AOF 文件未被重寫, 那麼只要中止服務器, 移除 AOF 文件末尾的 FLUSHALL 命令, 並重啓 Redis , 就能夠將數據集恢復到 FLUSHALL 執行以前的狀態。
AOF 的缺點
- 對於相同的數據集來講,AOF 文件的體積一般要大於 RDB 文件的體積。
- 根據所使用的
fsync
策略,AOF 的速度可能會慢於 RDB 。 在通常狀況下, 每秒fsync
的性能依然很是高, 而關閉fsync
可讓 AOF 的速度和 RDB 同樣快, 即便在高負荷之下也是如此。 不過在處理巨大的寫入載入時,RDB 能夠提供更有保證的最大延遲時間(latency)。- AOF 在過去曾經發生過這樣的 bug : 由於個別命令的緣由,致使 AOF 文件在從新載入時,沒法將數據集恢復成保存時的原樣。 (舉個例子,阻塞命令 BRPOPLPUSH 就曾經引發過這樣的 bug 。) 測試套件裏爲這種狀況添加了測試: 它們會自動生成隨機的、複雜的數據集, 並經過從新載入這些數據來確保一切正常。 雖然這種 bug 在 AOF 文件中並不常見, 可是對比來講, RDB 幾乎是不可能出現這種 bug 的。
參考資料:
http://redisdoc.com/topic/persistence.html
http://redis.io/commands/expire
http://redis.io/topics/persistence
http://oldblog.antirez.com/post/redis-persistence-demystified.html
http://redis.io/topics/memory-optimization
http://www.infoq.com/cn/articles/tq-redis-memory-usage-optimization-storage
http://redis.io/topics/lru-cache