一、雙寫一致性
雙寫一致性,也就是說 Redis 和 mysql 數據同步
雙寫一致性數據同步的方案有:
1、先更新數據庫,再更新緩存
這個方案一般不用:
因為當有兩個請求AB先后更新數據庫后,A應該先更新緩存,但是因為網絡原因,B卻先更新了緩存,導致了臟數據,所以不考慮用。
2、先刪緩存,再更新數據庫
這個方案也不是很好:
緩存刪了,數據庫還沒存完,又來了一個請求,又去數據庫拿,然后緩存又有了(在存數據的時候,請求來了,緩存不是最新的)
3、先更新數據庫,再刪緩存
推薦用這個方案:
更新了數據庫就馬上把緩存刪了
但是還是有一點小問題,就是在更新數據的過程中拿到的數據還不是最新的。
二、緩存更新策略
LRU/LFU/FIFO
算法剔除,也就是maxmemory-policy
,超過最大內存,新的放不進去了,淘汰策略
LRU:沒有被使用時間最長的(可以保證熱點數據)
LFU:一定時間段內使用次數最少的(會單獨起一個 counter 來計數,會影響性能)
FIFO:先進先出
如何保證 Redis 中數據是最熱的,配置 LRU 的剔除算法
配置文件中:maxmemory-policy:volatile-lru
LFU 配置 Redis4.0 之后為 maxmemory_policy 淘汰策略添加了兩個 LFU 模式
-配置
maxmemory-policy:volatile-lfu
lfu-log-factor 10
lfu-decay-time 1
# 1 分鍾使用 10 次,不在這個范圍內的就把它剔除
三、緩存穿透、緩存擊穿、緩存雪崩
緩存穿透
描述:
緩存穿透是指緩存和數據庫中都沒有的數據,而用戶不斷發起請求,如發起為id為“-1”的數據或id為特別大不存在的數據。這時的用戶很可能是攻擊者,攻擊會導致數據庫壓力過大。
解決方案:
1、接口層增加校驗,如用戶鑒權校驗,id做基礎校驗,id<=0的直接攔截;
2、從緩存取不到的數據,在數據庫中也沒有取到,這時也可以將key-value對寫為key-null,緩存有效時間可以設置短點,如30秒(設置太長會導致正常情況也沒法使用)。這樣可以防止攻擊用戶反復用同一個id暴力攻擊
3、通過布隆過濾器實現,mysql中所有數據都放到布隆過濾器,請求來了,先去布隆過濾器查,如果沒有,表示非法,直接返回
緩存擊穿
描述:
緩存擊穿是指緩存中沒有但數據庫中有的數據(一般是緩存時間到期),這時由於並發用戶特別多,同時讀緩存沒讀到數據,又同時去數據庫去取數據,引起數據庫壓力瞬間增大,造成過大壓力
解決方案:
設置熱點數據永遠不過期。
緩存雪崩
描述:
緩存雪崩是指緩存中數據大批量到過期時間,而查詢數據量巨大,引起數據庫壓力過大甚至down機。和緩存擊穿不同的是,緩存擊穿指並發查同一條數據,緩存雪崩是不同數據都過期了,很多數據都查不到從而查數據庫。
解決方案:
1、緩存數據的過期時間設置隨機,防止同一時間大量數據過期現象發生。
2、如果緩存數據庫是分布式部署,將熱點數據均勻分布在不同搞得緩存數據庫中。
3、設置熱點數據永遠不過期。