亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

1. 前言

Redis 相對于傳統的關系型數據庫(例如 MySQL )而言,還具有設置過期時間的特性,在項目實戰中,我們經常關心的三元組是 {key,value,expire_time}。這里的過期時間(expire_time)是的具體執行方式,涉及到 Redis 的緩存過期策略。

2. 緩存過期策略

面試官提問: Redis 里的 Key 超過失效時間,是如何處理的呢?

題目解析:

首先,我們要明白緩存過期的目的是為了在 Key 超過 expire_time 后,從內存中刪除,減少內存空間的占用。其次,要分析不同策略的定義、優點和缺點。Redis 的過期策略主要有三種實現方式:

(1)定時刪除:

  • 定義:對于每一個有過期時間的 Key,創建一個定時器,到過期時間立即刪除;
  • 優點:保存內存可以盡快釋放,減少過期 Key 對內存空間的占用;
  • 缺點:占用大量的 CPU 資源去處理定時器,影響緩存的吞吐量,這和 Redis 設計追求性能的設定不符,所以一般不會采用這種策略。

(2)惰性刪除:

  • 定義:過期的 Key 不做處理,只有當訪問這個 Key 時才會判斷是否過期,過期則清除;
  • 優點:刪除操作只有在訪存的時候才可能執行,對 CPU 的占用做到了最小。
  • 缺點:如果內存中大量的 Key 均過期,且一段時間內沒有被訪問,會占用大量內存。

(3)定期刪除:

  • 定義:每隔一段時間全量掃描設置了過期時間的 Key,如果失效則從內存中刪除,否則不做處理;
  • 優點:通過限制定時的頻率,來減少對 CPU 的占用和對內存的占用;
  • 缺點:作為一種折中的方案,在內存友好方面,不如定時刪除策略;在 CPU 友好方面,不如惰性刪除。使用時的表現非常依賴配置的定期頻率。

3. 內存淘汰機制

面試官提問: Redis 的內存淘汰機制有哪些,能枚舉說明嗎?

題目解析:

我們需要注意,緩存過期策略和內存淘汰機制是容易混淆的兩個概念,兩者的目的不同。

  • 緩存過期策略:針對過期 Key ,從內存中移除的方式。
  • 內存淘汰機制:針對 Redis 內存不足時,業務還在繼續往 Redis 追加內容,如何處理已有的內容。

在 Redis 的 redis.conf 文件中,我們能找到八種可配置的內存淘汰機制:

  • volatile-lru:當內存不足以容納新寫入數據時,在設置了過期時間的鍵空間中,移除最近最少使用的 key;
  • allkeys-lru:當內存不足以容納新寫入數據時,在鍵空間中,移除最近最少使用的 key;
  • volatile-lfu:當內存不足以容納新寫入數據時,在過期密集的鍵中,使用 LFU 算法進行刪除 key;
  • allkeys-lfu:當內存不足以容納新寫入數據時,對所有的 key 執行 LFU 算法篩選過期;
  • volatile-random:當內存不足以容納新寫入數據時,在設置了過期的鍵中,隨機刪除一個 key;
  • allkeys-random:當內存不足以容納新寫入數據時,隨機刪除一個或者多個 key;
  • volatile-ttl:當內存不足以容納新寫入數據時,在設置了過期時間的鍵空間中,有更早過期時間的 key 優先移除;
  • noeviction:當內存不足以容納新寫入數據時,新寫入操作直接報錯,無法寫入。

上述算法按照特性可以分為幾類:LRU/LFU 算法、隨機刪除算法、優先淘汰歷史數據算法、報錯處理算法。

在項目中推薦兩種 LRU 算法,即如果 Redis 用作持久化數據庫,不配置緩存過期時間,采用 allkeys-lru ;如果 Redis 作為緩存數據庫,配置了 Key 過期時間,采用 volatile-lru 算法。

4. LRU 算法

面試官提問: 緩存過期的 LRU 算法原理是什么?

題目解析:

既然在 Redis 中談到了 LRU ,就不可避免解釋其原理。LRU(Least Recently Used,最近最少使用算法)是最常見的緩存淘汰算法,核心思想是 "如果數據最近被訪問過,那么將來被訪問的可能性也更高"。

圖片描述
?

(LRU 算法原理)

LRU 算法的核心步驟在于:

  1. 新數據直接插入到鏈表頭部;
  2. 每當緩存命中(即緩存數據被訪問),則將被命中的數據移到鏈表頭部;
  3. 當鏈表滿的時候,將鏈表尾部的數據丟棄。

從性質上總結,越靠近鏈表頭部的數據越是不容易被淘汰,越靠近鏈表尾部的數據越是容易淘汰。

5. 小結

本章介紹了 Redis 緩存過期策略和內存淘汰策略,需要大家區分兩種策略解決的問題,同時需要針對 LRU 算法原理進行說明,必要性能夠做到手寫 LRU 算法的偽代碼。