Redis 持久化原理及過期 key 清除策略


Redis RDB 持久化原理

1)RDB 持久化配置

# 時間策略,表示900s內如果有1條是寫入命令,就觸發產生一次快照,可以理解為就進行一次備份
save 900 1
save 300 10 # 表示300s內有10條寫入,就產生快照
save 60 10000 # 表示60s內有10000條寫入,就產生快照

# 文件名稱
dbfilename dump.rdb

# 如果持久化出錯,主進程是否停止寫入
stop-writes-on-bgsave-error yes

# 是否壓縮
rdbcompression yes

# 導入時是否檢查
rdbchecksum yes

# 文件保存路徑
dir /usr/local/redis-4.0.6

2)save 的含義

實際生產環境每個時段的讀寫請求肯定不是均衡的,為此 redis 提供一種根據 key 單位時間操作次數來觸發一次備份到磁盤,我們可以自由定制什么情況下觸發備份,此功能起到平衡性能與數據安全的作用

3)在 Redis 中 RDB 持久化的觸發分為兩種:自己手動觸發與 Redis 定時觸發

針對 RDB 方式的持久化,手動觸發可以使用:

  • save:會阻塞當前 Redis 服務器,直到持久化完成,線上應該禁止使用。
  • bgsave:該觸發方式會 fork 一個子進程,由子進程負責持久化過程,因此阻塞只會發生在 fork 子進程的時候

而自動觸發的場景主要是有以下幾點:

  • 根據我們的 save m n 配置規則自動觸發
  • 從節點全量復制時,主節點發送 rdb 文件給從節點完成復制操作,主節點會觸發 bgsave
  • 執行 debug reload 時
  • 執行 shutdown 時,如果沒有開啟aof,也會觸發

4)禁用RDB

只需要在 save 的最后一行寫上:save ""

 

 

 

Redis AOF 持久化原理

1)AOF 持久化配置

# 是否開啟aof
appendonly yes

# 文件名稱
appendfilename "appendonly.aof"

# 同步方式
appendfsync everysec

# aof重寫期間是否同步
no-appendfsync-on-rewrite no

# 重寫觸發配置
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

# 加載aof時如果有錯如何處理
aof-load-truncated yes # yes表示如果aof尾部文件出問題,寫log記錄並繼續執行。no表示提示寫入等待修復后寫入

# 文件重寫策略
aof-rewrite-incremental-fsync yes

2)appendfsync 同步模式有三種模式,一般情況下都采用 everysec 配置,在數據和安全里面做平衡性選擇,最多損失1s的數據

  • always:把每個寫命令都立即同步到 aof,很慢,但是很安全
  • everysec:每秒同步一次,是折中方案
  • no:redis 不處理交給 OS 來處理,非常快,但是也最不安全

3)AOF 的整個流程大體來看可以分為兩步

第一步是命令的實時寫入(如果是 appendfsync everysec 配置,會有 1s 損耗)。

第二步是對 aof 文件的重寫。

步驟:

命令寫入=》追加到 aof_buf =》通過時間事件調用 flushAppendOnlyFile 函數同步到 aof 磁盤

原因:

實時寫入磁盤會帶來非常高的磁盤 IO,影響整體性能

4)AOF 持久化的效率和安全性分析

  • always:每個時間事件循環都將 AOF_BUF 緩沖區的所有內容寫入到 AOF 文件,並且同步 AOF 文件,這是最安全的方式,但磁盤操作和阻塞延遲,是 IO 開支較大。
  • everysec:每秒同步一次,性能和安全都比較中庸的⽅方式,也是 redis 推薦的方式。如果遇到物理服務器故障,有可能導致最近一秒內 aof 記錄丟失(可能為部分丟失)。
  • no:redis 並不直接調用文件同步,而是交給操作系統來處理,操作系統可以根據 buffer 填充情況/通道空閑時間等擇機觸發同步;這是一種普通的文件操作方式。性能較好,在物理服務器故障時,數據丟失量會因 OS 配置有關。處於 no 模式下的 flushAppendOnlyFile 調用無須執行同步操作

 

Redis 兩種持久化方案對比

Redis 提供了不同的持久性選項:

  • RDB 持久性以指定的時間間隔執行數據集的時間點快照。
  • AOF 持久性記錄服務器接收的每個寫入操作,將在服務器啟動時再次播放,重建原始數據集。使用與 Redis 協議本身相同的格式以僅追加方式記錄命令。當 Redis 太大時,Redis 能夠重寫日志背景。

RDB 的優缺點

優點:

  • RDB 最大限度地提高了 Redis 的性能,父進程不需要參與磁盤 I/O
  • 與 AOF 相比,RDB 允許使用大數據集更快地重啟

缺點:

  • 如果您需要在 Redis 停止工作時(例如斷電后)將數據丟失的可能性降至最低,則 RDB 並不好
  • RDB 經常需要 fork() 才能使用子進程持久存儲在磁盤上。如果數據集很大,fork() 可能會非常耗時

AOF 的優缺點

優點:

  • 數據更加安全
  • 當 Redis AOF 文件太大時,Redis 能夠在后台自動重寫 AOF
  • AOF 以易於理解和解析的格式一個接一個地包含所有操作的日志

缺點:

  • AOF 文件通常比同一數據集的等效 RDB 文件大
  • 根據確切的fsync策略,AOF 可能比 RDB 慢

RDB 和 AOF,我應該用哪一個?

一般來說,如果想達到足以媲美 PostgreSQL 的數據安全性, 你應該同時使用兩種持久化功能。如果你非常關心你的數據,但仍然可以承受數分鍾以內的數據丟失,那么你可以只使用 RDB 持久化。有很多用戶都只使用 AOF 持久化, 但我們並不推薦這種方式:因為定時生成 RDB 快照(snapshot)非常便於進行數據庫備份, 並且 RDB 恢復數據集的速度也要比 AOF 恢復的速度要快。

在線上我們到底該怎么做?

  • RDB 持久化與 AOF 持久化同步使用
  • 如果 Redis 中的數據並不是特別敏感或者可以通過其它方式重寫生成數據,可以關閉持久化,如果丟失數據可以通過其它途徑補回
  • 自己制定策略定期檢查 Redis 的情況,然后可以手動觸發備份、重寫數據
  • 采用集群和主從同步

 

Redis 過期 key 清除策略

Redis 如何淘汰過期的 keys?

惰性刪除 :

概念:當一些客戶端嘗試訪問它時,key 會被發現並主動的過期。放任鍵過期不管,但是每次從鍵空間中獲取鍵時,都檢查取得的鍵是否過期,如果過期的話,就刪除該鍵

特點:CPU 友好,但如果一個 key 不再使用,那么它會一直存在於內存中,造成浪費

定時刪除:

概念:設置鍵的過期時間的同時,創建一個定時器(timer),讓定時器在鍵的過期時間來臨時,立即執行對鍵的刪除操作

定期刪除:

隔一段時間,程序就對數據庫進行一次檢查,刪除里面的過期鍵,至於要刪除多少過期鍵,以及要檢查多少個數據庫,則由算法決定。 即設置一個定時任務,比如10分鍾刪除一次過期的 key;間隔小則占用 CPU,間隔大則浪費內存

例如 Redis 每秒處理:

  1. 測試隨機的 20 個 keys 進⾏行行相關過期檢測。
  2. 刪除所有已經過期的 keys。
  3. 如果有多於 25% 的 keys 過期,重復步奏1

Redis 服務器實際使用的是惰性刪除和定期刪除兩種策略:通過配合使用這兩種刪除策略,服務器可以很好地在合理使用 CPU 時間和避免浪費內存空間之間取得平衡。

惰性刪除策略是怎么實現?

通過 expireIfNeeded 函數,當我們操作 key 的時候進行判斷 key 是否過期。

定期刪除策略是怎么實現的?

通過 activeExpireCycle 函數,serverCron 函數執行時,activeExpireCycle 函數就會被調用,規定的時間里面分多次遍歷服務器的 expires 字典隨機檢查一部分 key 的過期時間,並刪除其中的過期 key。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM