一、雙寫一致性
雙寫一致性,也就是說 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、設定熱點資料永遠不過期。