1. 程式人生 > >快取受益/ 成本/ 更新策略 / 穿透/ 無底洞/

快取受益/ 成本/ 更新策略 / 穿透/ 無底洞/

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新增邏輯過期時間,但發現超過邏輯過期後,會使用單獨的執行緒取構建快取。相比於互斥鎖的方案,此方案沒有等待的過程,但會存在資料不一致,因為沒有等到真正快取重建完,可能拿到老的結果。