您好,登錄后才能下訂單哦!
本文主要介紹了 Redis 持久化的兩種機制:RDB 和 AOF,以及鍵過期的策略:惰性刪除和定期刪除,還有 RDB、AOF 和復制功能對過期鍵的處理。
RDB 是 Redis 持久化的第一種方式。有兩個 Redis 命令可以用于生成 RDB 文件,一個是 SAVE,另一個是 BGSAVE。
SAVE 會阻塞 Redis 服務器進程,執行時 Redis 服務器會阻塞所有客戶端發送的命令。
redis> SAVE
OK
BGSAVE 會派生出一個子進程執行,執行時仍可繼續處理客戶端的命令,但會拒絕客戶端 SAVE 和 BGSAVE 的命令,延遲 BGREWRITEAOF 命令。
redis> BGSAVE
Background saving started
SAVE 命令會阻塞服務器,所以只能手動執行。BGSAVE 可以在不阻塞的情況下執行,所以可以配置 save 選項讓服務器每隔一段時間自動執行一次。
比如我們可以向服務器提供以下配置:
save 900 1
save 300 10
save 60 10000
那么只要滿足以下三個條件中的任意一個即可被執行:
為了實現這一功能,服務器會維持一個記錄距離上次保存之后修改的次數的 dirty 計數器和一個記錄上次保存時間的 lastsave 屬性。
周期操作函數 serverCron 默認每個 100 毫秒就會執行一次,它的其中一項工作就是檢查 save 選項設置的條件是否滿足,如果滿足的話就會執行 BGSAVE 命令。
RDB 文件有多個部分,包括握手字段 ‘REDIS’ 字符串,版本號,數據庫,’EOF’ 和校驗字段。
核心部分是數據庫字段,數據庫字段包括了握手字段 ‘SELECTDB’,數據庫編號和鍵值對,數據庫編號指示了這是第幾個數據庫,而鍵值對則保存了各項數據。
鍵值對中除了類型和數據,還可能會有過期時間。對于不同類型的鍵值對,RDB 文件會用不同的方式來保存它們。
RDB 文件本身是一個經過壓縮的二進制文件,每次 SAVE 或者 BGSAVE 都會創建一個新的 RDB 文件,不支持追加操作。
AOF 是 Redis 持久化的第二種方式,在 AOF 和 RDB 同時開啟時,服務器會優先考慮從 AOF 恢復數據,因為 AOF 每次記錄間隔的時間更短。
和 RDB 直接記錄鍵值對不同,AOF 記錄的是命令。服務器在執行完一個寫命令以后,會把這條命令追加到服務器 aof_buf 緩沖區的末尾,并在一個適當的時候寫入文件。重建時服務器會創建一個偽客戶端,依次執行文件中的命令即可完成數據的載入。
AOF 的持久化發生在每次事件循環結束之前,會阻塞服務器。在持久化時會調用操作系統的 write 函數,但通常該函數會把數據保存在一個內存緩沖區里面而不是立刻刷入磁盤。這就帶來一個安全問題。為了避免這個問題操作系統又提供了 fsync 和 fdatasync 兩個強制刷盤的同步函數。我們把 write 稱為寫入,把 fsync 和 fdatasync 稱為同步。
服務器會在每次事件循環結束之前根據 appendfsync 選項寫入和同步 aof_buf 中的數據:
隨著服務器運行時間的流逝,AOF 文件中的內容會越來越多,文件的體積也會越來越大,不僅會對宿主計算機造成影響,也拖慢了數據恢復所需要的時間。
AOF 重寫是指重新生成一個 AOF 文件替換原來的 AOF 文件。但這里的重寫不會對原有的文件進行讀取、分析或者寫入,而是把數據庫中的鍵值對折算成命令,重新寫入新的文件。
重寫是一個耗時的操作,因此 Redis 把它放到后臺去操作,對應的指令是 BGREWRITEAOF。在重寫過程中服務器還可能接收新的指令,因此 Redis 會維護一個 AOF 重寫緩沖區,記錄重寫期間的寫命令,在重寫完成后追加到 AOF 文件末尾。
RDB 的優點:
RDB 的缺點:
AOF 的優點:
AOF 的缺點:
RDB 和 AOF 各有所長,RDB 體積小,恢復速度快,而且可以生成快照;AOF 頻率更高,可以保存更新的數據。一般來說,推薦同時使用。
Redis 采取的是惰性刪除和定期刪除配合使用的方式。
惰性刪除是指 Redis 會在訪問某個鍵的時候檢查該鍵是否過期,如果過期,就會將輸入鍵從數據庫中刪除。但惰性刪除不能及時清理內存,因此 Redis 還有定期刪除的機制。
定期刪除是另一種過期鍵刪除方式。Redis 會維護一個過期字典(如下圖所示),所有聲明了過期時間的鍵都會被添加進這個字典中。周期操作函數 serverCron 執行時,會在規定時間內隨機檢查一部分鍵的過期時間,并刪除其中的過期鍵。
RDB 文件在生成時會檢查每個鍵的過期時間,過期鍵不會被添加進 RDB 文件里。
載入 RDB 文件時,如果該服務器是主服務器,則不會載入文件中過期的鍵;如果該服務器是從服務器,則不論過期與否都會被載入。不過,因為主從服務器在同步的時候,從服務器的數據庫會被清空,所以一般來講,過期鍵對載入 RDB 文件的從服務器不會造成影響。
AOF 文件寫入時,如果數據庫中的某個鍵已過期,但它還沒被刪除,那么 AOF 文件不會因為這個鍵產生任何影響。當它被惰性刪除或者定期刪除之后,程序會向 AOF 文件追加一條 DEL 命令顯示記錄該鍵已被刪除。
AOF 重寫時,和生成 RDB 文件一樣,會過濾掉已經過期的鍵。
主服務器在刪除一個過期鍵后,會顯式地向所有從服務器發送一個 DEL 命令,告知從服務器刪除這個過期鍵。
Redis 3.2 前,為了保持主從一致性,從服務器在執行客戶端發送的讀命令時,即使碰到過期鍵也不會將過期鍵刪除,而是繼續像處理未過期鍵一樣處理過期鍵。從服務器只有在接到主服務器發來的 DEL 命令之后,才會刪除過期鍵。Redis 3.2 后,從節點在讀取數據時,增加了對數據是否過期的判斷:如果該數據已過期,則不返回給客戶端。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。