快取的架構設計要點
一、快取的典型應用場景
下面的2中情況下,優化儲存系統是無法有效提升效能的。
1. 需要經過複雜運算得出的資料
例如需要展示有多少使用者線上,如果使用資料庫,每次都要執行 count 操作,展示量很大的話就對資料庫造成了極大壓力。
2. 讀多寫少的資料
例如一個明星釋出一條微博,可能有幾千萬人瀏覽,如果每次瀏覽都 select 一次的話,幾千萬的請求對資料庫的壓力非常大。
快取就是為了減輕儲存系統的壓力,將可重複使用的資料放到記憶體中,一次生成、多次使用。
二、設計要點
快取雖然為儲存系統減負了,但給架構設計帶來了複雜性,下面3點需要重點關注:
-
快取穿透
-
快取雪崩
-
快取熱點
1. 快取穿透
指業務系統在快取中沒有查到資料,需要再次去儲存系統查詢。
通常有2中情況:
-
儲存資料不存在
被訪問的資料確實不存在,儲存系統中沒有,那麼快取中肯定也沒有。
對於這類資料,每次都要查詢快取、查詢儲存系統,如果有人惡意大量訪問一些不存在的資料,就會對系統產生嚴重影響。可以直接設定一個預設值放到快取中,防止訪問儲存系統。
-
快取資料生成需要耗費時間或者資源
儲存系統中存在資料,但生成快取耗時耗資源,快取失效後,訪問壓力就集中在儲存系統了。
例如商品分頁,資料量巨大,不能都快取起來,只能分頁快取,頁數靠後的訪問少,快取就很容易過期消失,之後的訪問需要計算、訪問儲存層,重新生成快取。
正常情況這類訪問不會頻繁,但如果爬蟲遍歷的時候,系統性能就可能出問題了。
這種情況沒有太好的解決方案,可以考慮:
-
識別爬蟲禁止訪問,但這會影響SEO和推廣;
-
做好監控,發現問題後及時處理,爬蟲不是攻擊,對系統的影響是逐步的,監控發現問題後有時間處理。
2. 快取雪崩
當快取過期被清除後,業務系統需要重新生成快取,訪問儲存系統、計算。
高併發的系統中,在新快取還未生成的這一小段時間內,可能會有上百個請求進來,他們發現快取中沒有,就都去生成快取,從而對儲存系統造成巨大壓力,引發連鎖反應,造成系統崩潰。
解決方案:
-
更新鎖
對快取更新操作進行加鎖保護,保證只有一個執行緒能夠進行快取更新。
對於分散式系統,可能有上百臺伺服器,即使每臺伺服器上只有一個更新執行緒,但總體數量大,同樣會引發雪崩,需要使用分散式鎖。
-
後臺更新
快取有效期設為永久,後臺執行緒定時更新。
需要考慮一個情況:當快取記憶體不足時,會清理掉一些快取資料,從被清理到下次更新快取這段時間內,業務訪問時讀到的就是空。
可以考慮當業務發現快取失效後,傳送一個訊息,通知後臺執行緒進行更新。
後臺更新機制還適合做快取預熱。指系統上線後,定時觸發了快取載入,不用等待使用者訪問才載入。
3. 快取熱點
快取中的個別資料可能是大熱點,短時間內會被高頻訪問,雖然快取伺服器的效能好,但如果訪問量過大也會帶來效能壓力。例如明星的某條微博被海量使用者瀏覽。
解決方案:複製多個快取副本,分散請求,減輕單體伺服器壓力。
需要注意:不同副本不要設定統一的過期時間,防止同時失效引起雪崩。可以設定一個過期時間範圍,不同副本的過期時間指定範圍內的隨機值。
內容整理自《從0開始學架構》
點選:point_down: 閱讀原文 ,檢視 文章列表