文章參考:《Redis 設計與實現》黃建巨集

設定過期時間

通過 EXPIRE 或者 PEXPIRE 命令,客戶端可以以秒或毫秒精度為資料庫中的某個鍵設定生存時間 TTL (Time To Live)

SETEX 命令可以設定一個字串的同時為鍵設定過期時間

儲存過期時間

redisDb 結構的 expires 字典儲存了資料庫中所有鍵的過期時間,我們稱這個字典為過期字典:

  • 過期字典的鍵是一個指標,這個指標指向鍵空間中的某個鍵物件
  • 過期字典的值十億額 long long 型別的整數,儲存了鍵的過期時間, 一個毫秒精度的 UNIX 時間戳
typedef struct redisDb{
// ...
// 過期字典
dict *expires;
// ...
} redisDb;

過期鍵的判定

通過過期字典,可以用以下步驟檢查一個給定鍵是否過期:

  1. 檢查給定鍵是否存在於過期字典中,如果存在,那麼取得鍵的過期時間
  2. 檢查當前 UNIX 時間戳是否大於該鍵的過期時間,如果是的話, 那麼鍵已經過期

過期鍵的刪除策略

  1. 定時刪除:在設定鍵的過期時間同時,建立一個定時器 timer,讓定時器在鍵的過期時間來臨時,立即執行對鍵的刪除操作, 對記憶體最友好,佔用大量 CPU,所以現階段不現實
  2. 惰性刪除:放任鍵過期不管,但是每次從鍵空間中獲取鍵時,都檢查取得的鍵是否過期,如果過期就刪除該鍵,如果沒有過期,就返回該鍵,對 CPU 友好,對記憶體不友好

在使用惰性刪除策略時,如果資料庫中有非常多的過期鍵,而這些過期鍵又恰好沒有被訪問到的話,那他們也許永遠也不會被刪除,除非手動執行 FLUSHDB, 我們甚至可以將這種情況看作是一種記憶體洩漏,這對於執行狀態非常依賴記憶體的 Redis 伺服器來說,肯定不是一個好訊息。

  1. 定期刪除:每隔一段時間,程式就對資料庫進行一次檢查, 刪除裡面的過期鍵

其中, Redis 使用了惰性刪除和定期刪除兩種策略