一、緩存的更新策略
緩存中的數據有生命周期,需要定期更新和刪除以保證內存空間的合理使用以及緩存數據與數據庫數據的一致性。
緩存數據需要根據合理的數據更新策略更新緩存中的數據,有如下三種策略:
(1)LRU/LFU/FIFO算法剔除:Redis使用maxmemory-policy
,即Redis中的數據占用的內存超過設定的最大內存時的操作策略
(2)超時剔除:對緩存的數據設置過期時間,超過過期時間自動刪除緩存數據,然后再次進行緩存,保證與數據庫中的數據一致
(3)主動更新:開發者控制key的更新周期,當key在后端數據庫中發生更新時,向Redis主動發送消息,Redis接收到消息對key進行更新或刪除
# 根據LRU算法刪除過期的key
volatile-lru -> remove the key with an expire set using an LRU algorithm
# 根據LRU算法刪除一些key
allkeys-lru -> remove any key according to the LRU algorithm
# 隨機刪除一些設置了過期時間的key
volatile-random -> remove a random key with an expire set
# 從所有的key中隨機刪除一些key
allkeys-random -> remove a random key, any key
# 刪除一些快過期的key
volatile-ttl -> remove the key with the nearest expire time (minor TTL)
# 不刪除任何key,在向Redis寫入key時返回一個錯誤,這將會占用更多的內存
noeviction -> don't expire at all, just return an error on write operations
需要注意的是:with any of the above policies, Redis will return an error on write operations, when there are no suitable keys for eviction。
即在上面的六種策略中,如果沒有key可以被刪除時,向Redis中寫入數據會返回一個error異常。
緩存更新策略對比如下圖所示:
二、緩存粒度控制
上圖中,使用Redis來做緩存,底層使用MySQL來做數據存儲源,這種架構下大部分請求由Redis處理,少部分請求到達MySQL。從MySQL中獲取一個用戶的所有信息,然后緩存到Redis的數據結構中。
此時需要面對一個問題:緩存這個用戶的所有數據信息,還是緩存用戶需要的用戶信息字段。
可以從三個角度來考慮:
(1)通用性:從通用性角度考慮,緩存全量屬性更好。
因為當用戶數據表字段發生改變時,不需要修改程序就可以直接同步修改之后的用戶信息到Redis緩存中供用戶使用,但是這樣會占用更多的內存空間。
(2)占用空間:從占用空間的角度考慮,緩存部分屬性更好。
因為當用戶數據表字段發生改變時而用戶需要這個字段信息時,就需要修改程序源代碼來把修改之后的用戶信息同步緩存到Redis中,這種情況下占用的內存空間比全量屬性占用的內存空間要少。
(3)代碼維護:從代碼維護角度考慮,表面上緩存全量屬性更好。
因為不管數據源中的數據表結構如何改變,都會把所有的數據同步到Redis緩存中,而不需要修改程序源代碼,但是在大多數情況下,並不會使用到全量數據,只需要緩存需要的數據就可以了。因此從內存空間消耗及性能方面考慮,緩存部分屬性更好。
綜合以上3點原因得出:在選擇緩存屬性時,需要綜合考慮緩存全量屬性還是部分屬性。
后續待寫。。。
參考博文:
(1) https://www.cnblogs.com/renpingsheng/p/10202914.html
(2) https://youzhixueyuan.com/design-performance-and-application-of-redis-cache.html (redis系列文章)
(3) https://segmentfault.com/a/1190000022029639 (Redis 緩存雪崩、擊穿、穿透)