快取受益/ 成本/ 更新策略 / 穿透/ 無底洞/
1.快取的受益與成本
受益:
1)加速讀寫
2)降低後端負載
後端伺服器通過前端快取降低負載,業務端使用Redis降低後端MySQL負載
成本
1)資料不一致:緩衝層和資料層有時間視窗不一致,和更新策略有關。
2)程式碼維護成本:多了一層快取邏輯
3)運維成本:如Redis Cluster
2.快取使用場景
1)降低後端負載
對高消耗的SQL:join結果集/分組統計結果快取(如截至某段時間的快取)
2)加速請求響應
利用Redis/Memcache優化IO響應時間
3)大量寫合併為批量寫:
某個操作如計算訪問量,如果直接和DB連線,會造成大量更新操作,DB寫的速度慢,造成效能差。則計數器先Redisl累加再批量寫DB。
3.快取更新策略
快取的資料擁有生命週期,需要定期更新或刪除,從而保證空間在可控範圍內,並且保證資料的更新。
更新策略:
1)LRU / LFU / FIFO演算法剔除:例如maxmemory-policy
適用場景:最大記憶體
2)超時提出:例如expire
3)主動更新:開發控制每個key的生命週期。例如,在儲存層使用者的資訊發生變化,如果通過一定的業務程式碼或是開發工具,能訂閱儲存層的更新,來更新快取層中的資料,來實現資料的一致性。
更新建議:
1)低一致性:最大記憶體和淘汰策略
2)高一致性:超時剔除和主動更新結合,最大記憶體和淘汰測率兜底。(建議)
4.快取力度控制
快取三個角度
1)通用性:全量屬性更好
2)佔用空間:部分屬性更好
3)程式碼維護:表面上全量屬性更好
一般都快取一部分屬性,雖然快取全量屬性系統有利於後續的擴充套件,但是序列化和記憶體上開銷較大,而且有些功能成功後不怎麼會再進行大的擴充套件。
5.快取穿透問題
1)業務程式碼自身問題
2)惡意攻擊、爬蟲等
視訊網站:視訊的URL進過加密,防止惡意人員猜測視訊id規格,強制訪問,然後造成穿透問題
如何發現快取穿透
1)業務的響應時間
利用監控系統監控,請求都打到儲存層,則會對響應時間造成影響(快取會比直接查儲存層快),因此可以通過監控來發現。
2)業務本身的問題
3)相關指標:總呼叫數,快取層命中數,儲存層命中數
解決快取擊穿:
方法一:快取空物件
缺點:1)需要更多的鍵:惡意攻擊或爬蟲有許多的鍵,雖然只儲存鍵和null,但是數量很大時,從快取的使用上來說會有一定的影響。
2)快取層和儲存層資料"短期"不一致:例如呼叫儲存層介面時網路不通,導致拿不到對應的結果(過期時間設為5分鐘),其實儲存層是有這個資料的,但是由於網路原因導致了資料在快取過期時間內是不一致的。【可以在介面恢復正常時重新整理快取中的資料】
方法二:布隆過濾器
布隆過濾器在cache層之前進行過濾,如果布隆過濾器中被過濾,則認為這個請求是無效的,反之,認為它是有效的。【固定的資料布隆過濾器效果好,但是如果變化的資料,如果構建布隆過濾器】
6.無底洞問題優化
無底洞問題主要考慮通訊開銷,方法有序列mget,序列IO,並行IO,hash_tag
8.熱點key重建優化
有大量的執行緒都會做快取重建,查詢資料來源,這樣導致資料來源有很大的壓力,而且響應時間會變得很慢。
三個目標
1)減少重快取的次數
2)資料儘可能一致
3)減少潛在危險
兩個解決
1)互斥鎖
互斥鎖的方法解決了大量重建的問題,但是它會有大量執行緒在等待的問題。
2)永不過期
a.快取層面:沒有設定過期時間(無expire)
b.功能層面:為每個value新增邏輯過期時間,但發現超過邏輯過期後,會使用單獨的執行緒取構建快取。相比於互斥鎖的方案,此方案沒有等待的過程,但會存在資料不一致,因為沒有等到真正快取重建完,可能拿到老的結果。