1. 程式人生 > >快取穿透、快取併發、熱點快取之最佳招式

快取穿透、快取併發、熱點快取之最佳招式

快取穿透與併發方案

• 如何解決穿透
• 如何解決併發
  當併發較高的時候,其實一般不建議使用快取過期這個策略的,更希望快取一直存在,通過後臺系統來更新快取系統中的資料達到資料的一致性目的,可能有人會質疑,如果快取系統掛了怎麼辦,這樣資料庫更新了但是快取沒有更新,沒有達到一致性的狀態。

解決問題的思路是:
  如果快取是因為網路問題沒有更新成功資料,那麼建議重試幾次,如果依然沒有更新成功則認為快取系統出錯不可用,這時候客戶端會將資料的KEY插入到訊息系統中,訊息系統可以過濾相同的KEY,只需保證訊息系統不存在相同的KEY,當快取系統恢復可用的時候,依次從mq中取出KEY值然後從資料庫中讀取最新的資料更新快取。
  注意:

更新快取之前,快取中依然有舊資料,所以不會造成快取穿透。
  下圖展示了整個思路的過程:
這裡寫圖片描述
  看完上面的方案以後,也許又會有疑問,如果是第一次使用快取或者快取中暫時沒有需要的資料,那又該如何處理呢?

解決問題的思路:
  在這種場景下,客戶端從快取中根據KEY讀取資料,如果讀到了資料則流程結束,如果沒有讀到資料(可能會有多個併發都沒有讀到資料),這時候使用快取系統中的setNX方法設定一個值(這種方法類似加個鎖),沒有設定成功的請求則sleep一段時間,設定成功的請求讀取資料庫獲取值,如果獲取到則更新快取,流程結束,之前sleep的請求這時候喚醒後直接再從快取中讀取資料,此時流程結束。
  在看完這個流程後,這裡面會有一個漏洞,如果資料庫中沒有需要的資料該怎麼處理,如果不處理則請求會造成死迴圈,不斷的在快取和資料庫中查詢,這時候可以這樣,如果沒有讀到資料則往快取中插入一個NULL字串的思路,這樣其他請求直接就可以根據“NULL”進行處理,直到後臺系統在資料庫成功插入資料後同步更新清理NULL資料和更新快取。
  流程圖如下所示:

熱點快取解決方案

1、快取使用背景:
  拿使用者中心的一個案例來說明:每個使用者都會首先獲取自己的使用者資訊,然後再進行其他相關的操作,有可能會有如下一些場景情況:

• 會有大量相同使用者重複訪問該專案。
• 會有同一使用者頻繁訪問同一模組。

2、思路解析

• 因為使用者本身是不固定的而且使用者數量也有幾百萬尤其上千萬,不可能把所有的使用者資訊全部快取起來,通過第一個場景情況可以看到一些規律,那就是有大量的相同使用者重複訪問,但是究竟是哪些使用者重複訪問我們也並不知道。
• 如果有一個使用者頻繁重新整理讀取專案,那麼對資料庫本身也會造成較大壓力,當然我們也會有相關的保護機制來確實惡意攻擊,可以從前端控制,也可以有采黑名單等機制,這裡不在贅述。如果用快取的話,我們又該如何控制同一使用者繁重讀取使用者資訊呢。

  我們可以通過快取系統做一個排序佇列,比如1000個使用者,系統會根據使用者的訪問時間更新使用者資訊的時間,越是最近訪問的使用者排名越排前,系統會定期過濾掉排名最後的200個使用者,然後再從資料庫中隨機取出200個使用者加入佇列,這樣請求每次到達的時候,會先從佇列中獲取使用者資訊,如果命中則根據userId,再從另一個快取資料結構中讀取使用者資訊,如果沒有命中則說明該使用者請求頻率不高。