如果20萬使用者同時訪問一個熱點快取,如何優化你的快取架構?【石杉的架構筆記】

石杉的架構筆記發表於2019-01-22

歡迎關注個人公眾號:石杉的架構筆記(ID:shishan100)

週一至週五早8點半!精品技術文章準時送上!

目錄

(1)為什麼要用快取叢集

(2)20萬使用者同時訪問一個熱點快取的問題

(3)基於流式計算技術的快取熱點自動發現

(4)熱點快取自動載入為JVM本地快取

(5)限流熔斷保護

(6)總結

(1)為什麼要用快取叢集

這篇文章,我們們來聊聊熱點快取的架構優化問題。

其實使用快取叢集的時候,最怕的就是熱key、大value這兩種情況,那啥叫熱key大value呢?

簡單來說,熱key,就是你的快取叢集中的某個key瞬間被數萬甚至十萬的併發請求打爆。

大value,就是你的某個key對應的value可能有GB級的大小,導致查詢value的時候導致網路相關的故障問題。

這篇文章,我們就來聊聊熱key問題。先來看看下面的一幅圖。

簡單來說,假設你手頭有個系統,他本身是叢集部署的,然後後面有一套快取叢集,這個叢集不管你用redis cluster,還是memcached,或者是公司自研快取叢集,都可以。

如果20萬使用者同時訪問一個熱點快取,如何優化你的快取架構?【石杉的架構筆記】

那麼,這套系統用快取叢集幹什麼呢?

很簡單了,在快取裡放一些平時不怎麼變動的資料,然後使用者在查詢大量的平時不怎麼變動的資料的時候,不就可以直接從快取裡走了嗎?

快取叢集的併發能力是很強的,而且讀快取的效能是很高的。

舉個例子,假設你每秒有2萬請求,但是其中90%都是讀請求,那麼每秒1.8萬請求都是在讀一些不太變化的資料,而不是寫資料。

那此時你把資料都放在資料庫裡,然後每秒傳送2萬請求到資料庫上讀寫資料,你覺得合適嗎?

當然不太合適了,如果你要用資料庫承載每秒2萬請求的話,那麼不好意思,你很可能就得搞分庫分表 + 讀寫分離。

比如你得分3個主庫,承載每秒2000的寫入請求,然後每個主庫掛3個從庫,一共9個從庫承載每秒1.8萬的讀請求。

這樣的話,你可能就需要一共是12臺高配置的資料庫伺服器,這是很耗費錢的,成本非常高,而且很不合適。

大家看看下面的圖,來體會下這種情況。

如果20萬使用者同時訪問一個熱點快取,如何優化你的快取架構?【石杉的架構筆記】

所以,此時你完全就可以把平時不太變化的資料放在快取叢集裡,快取叢集可以採用2主2從,主節點用來寫入快取,從節點用來讀快取。

以快取叢集的效能,2個從節點完全可以用來承載每秒1.8萬的大量讀了,然後3個資料庫主庫就是承載每秒2000的寫請求和少量其他讀請求就可以了。

大家看看下面的圖,你耗費的機器瞬間變成了4臺快取機器 + 3臺資料庫機器 = 7臺機器,是不是比之前的12臺機器減少了很大的資源開銷?

沒錯,快取其實在系統架構裡是非常重要的組成部分。很多時候,對於那些很少變化但是大量高併發讀的資料,通過快取叢集來抗高併發讀,是非常合適的。

如果20萬使用者同時訪問一個熱點快取,如何優化你的快取架構?【石杉的架構筆記】

這裡所有的機器數量、併發請求量都是一個示例,大家主要是體會一下這個意思就好,其目的主要是給一些不太熟悉快取相關技術的同學一點背景性的闡述,讓這些同學能夠理解在系統裡用快取叢集承載讀請求是什麼意思。

(2)20萬使用者同時訪問一個熱點快取的問題

好了,背景是已經給大家解釋清楚了,那麼現在就可以給大家說說今天重點要討論的問題:熱點快取。

我們來做一個假設,你現在有10個快取節點來抗大量的讀請求。正常情況下,讀請求應該是均勻的落在10個快取節點上的,對吧!

這10個快取節點,每秒承載1萬請求是差不多的。

然後我們再做一個假設,你一個節點承載2萬請求是極限,所以一般你就限制一個節點正常承載1萬請求就ok了,稍微留一點buffer出來。

好,所謂的熱點快取問題是什麼意思呢?

很簡單,就是突然因為莫名的原因,出現大量的使用者訪問同一條快取資料。

舉個例子,某個明星突然宣佈跟某某結婚,這個時候是不是會引發可能短時間內每秒都是數十萬的使用者去檢視這個明星跟某某結婚的那條新聞?

那麼假設那條新聞就是一個快取,然後對應就是一個快取key,就存在一臺快取機器上,此時瞬時假設有20萬請求奔向那一臺機器上的一個key。

此時會如何?我們看看下面的圖,來體會一下這種絕望的感受。

如果20萬使用者同時訪問一個熱點快取,如何優化你的快取架構?【石杉的架構筆記】

這個時候很明顯了,我們剛才假設的是一個快取Slave節點最多每秒就是2萬的請求,當然實際快取單機承載5萬~10萬讀請求也是可能的,我們這裡就是一個假設。

結果此時,每秒突然奔過來20萬請求到這臺機器上,會怎麼樣?

很簡單,上面圖裡那臺被20萬請求指向的快取機器會過度操勞而當機的。

那麼如果快取叢集開始出現機器的當機,此時會如何?

接著,讀請求發現讀不到資料,會從資料庫裡提取原始資料,然後放入剩餘的其他快取機器裡去。但是接踵而來的每秒20萬請求,會再次壓垮其他的快取機器。

以此類推,最終導致快取叢集全盤崩潰,引發系統整體當機。

我們們看看下面的圖,再感受一下這個恐怖的現場。

如果20萬使用者同時訪問一個熱點快取,如何優化你的快取架構?【石杉的架構筆記】

(3)基於流式計算技術的快取熱點自動發現

其實這裡關鍵的一點,就是對於這種熱點快取,你的系統需要能夠在熱點快取突然發生的時候,直接發現他,然後瞬間立馬實現毫秒級的自動負載均衡。

那麼我們就先來說說,你如何自動發現熱點快取問題?

首先你要知道,一般出現快取熱點的時候,你的每秒併發肯定是很高的,可能每秒都幾十萬甚至上百萬的請求量過來,這都是有可能的。

所以,此時完全可以基於大資料領域的流式計算技術來進行實時資料訪問次數的統計,比如storm、spark streaming、flink,這些技術都是可以的。

然後一旦在實時資料訪問次數統計的過程中,比如發現一秒之內,某條資料突然訪問次數超過了1000,就直接立馬把這條資料判定為是熱點資料,可以將這個發現出來的熱點資料寫入比如zookeeper中。

當然,你的系統如何判定熱點資料,可以根據自己的業務還有經驗值來就可以了。

大家看看下面這張圖,看看整個流程是如何進行的。

如果20萬使用者同時訪問一個熱點快取,如何優化你的快取架構?【石杉的架構筆記】

當然肯定有人會問,那你的流式計算系統在進行資料訪問次數統計的時候,會不會也存在說單臺機器被請求每秒幾十萬次的問題呢?

答案是否,因為流式計算技術,尤其是storm這種系統,他可以做到同一條資料的請求過來,先分散在很多機器裡進行本地計算,最後再彙總區域性計算結果到一臺機器進行全域性彙總。

所以幾十萬請求可以先分散在比如100臺機器上,每臺機器統計了這條資料的幾千次請求。

然後100條區域性計算好的結果彙總到一臺機器做全域性計算即可,所以基於流式計算技術來進行統計是不會有熱點問題的。

如果20萬使用者同時訪問一個熱點快取,如何優化你的快取架構?【石杉的架構筆記】

(4)熱點快取自動載入為JVM本地快取

我們自己的系統可以對zookeeper指定的熱點快取對應的znode進行監聽,如果有變化他立馬就可以感知到了。

此時系統層就可以立馬把相關的快取資料從資料庫載入出來,然後直接放在自己系統內部的本地快取裡即可。

這個本地快取,你用ehcache、hashmap,其實都可以,一切都看自己的業務需求,主要說的就是將快取叢集裡的集中式快取,直接變成每個系統自己本地實現快取即可,每個系統自己本地是無法快取過多資料的。

因為一般這種普通系統單例項部署機器可能就一個4核8G的機器,留給本地快取的空間是很少的,所以用來放這種熱點資料的本地快取是最合適的,剛剛好。

假設你的系統層叢集部署了100臺機器,那麼好了,此時你100臺機器瞬間在本地都會有一份熱點快取的副本。

然後接下來對熱點快取的讀操作,直接系統本地快取讀出來就給返回了,不用再走快取叢集了。

這樣的話,也不可能允許每秒20萬的讀請求到達快取機器的一臺機器上讀一個熱點快取了,而是變成100臺機器每臺機器承載數千請求,那麼那數千請求就直接從機器本地快取返回資料了,這是沒有問題的。

我們再來畫一幅圖,一起來看看這個過程:

如果20萬使用者同時訪問一個熱點快取,如何優化你的快取架構?【石杉的架構筆記】

(5)限流熔斷保護

除此之外,在每個系統內部,其實還應該專門加一個對熱點資料訪問的限流熔斷保護措施。

每個系統例項內部,都可以加一個熔斷保護機制,假設快取叢集最多每秒承載4萬讀請求,那麼你一共有100個系統例項。

你自己就該限制好,每個系統例項每秒最多請求快取叢集讀操作不超過400次,一超過就可以熔斷掉,不讓請求快取叢集,直接返回一個空白資訊,然後使用者稍後會自行再次重新重新整理頁面之類的。

通過系統層自己直接加限流熔斷保護措施,可以很好的保護後面的快取叢集、資料庫叢集之類的不要被打死,我們來看看下面的圖。

如果20萬使用者同時訪問一個熱點快取,如何優化你的快取架構?【石杉的架構筆記】

(6)本文總結

具體要不要在系統裡實現這種複雜的快取熱點優化架構呢?這個還要看你們自己的系統有沒有這種場景了。

如果你的系統有熱點快取問題,那麼就要實現類似本文的複雜熱點快取支撐架構。

但是如果沒有的話,那麼也別過度設計,其實你的系統可能根本不需要這麼複雜的架構。

如果是後者,那麼大夥兒就權當看看本文,來了解一下對應的架構思想好了^_^

End

如有收穫,請幫忙轉發,您的鼓勵是作者最大的動力,謝謝!

一大波微服務、分散式、高併發、高可用的原創系列文章正在路上

歡迎掃描下方二維碼,持續關注:

如果20萬使用者同時訪問一個熱點快取,如何優化你的快取架構?【石杉的架構筆記】

石杉的架構筆記(id:shishan100)

十餘年BAT架構經驗傾囊相授

推薦閱讀:

1、拜託!面試請不要再問我Spring Cloud底層原理

2、【雙11狂歡的背後】微服務註冊中心如何承載大型系統的千萬級訪問?

3、【效能優化之道】每秒上萬併發下的Spring Cloud引數優化實戰

4、微服務架構如何保障雙11狂歡下的99.99%高可用

5、兄弟,用大白話告訴你小白都能聽懂的Hadoop架構原理

6、大規模叢集下Hadoop NameNode如何承載每秒上千次的高併發訪問

7、【效能優化的祕密】Hadoop如何將TB級大檔案的上傳效能優化上百倍

8、拜託,面試請不要再問我TCC分散式事務的實現原理!

9、【坑爹呀!】最終一致性分散式事務如何保障實際生產中99.99%高可用?

10、拜託,面試請不要再問我Redis分散式鎖的實現原理!

11、【眼前一亮!】看Hadoop底層演算法如何優雅的將大規模叢集效能提升10倍以上?

12、億級流量系統架構之如何支撐百億級資料的儲存與計算

13、億級流量系統架構之如何設計高容錯分散式計算系統

14、億級流量系統架構之如何設計承載百億流量的高效能架構

15、億級流量系統架構之如何設計每秒十萬查詢的高併發架構

16、億級流量系統架構之如何設計全鏈路99.99%高可用架構

17、七張圖徹底講清楚ZooKeeper分散式鎖的實現原理

18、大白話聊聊Java併發面試問題之volatile到底是什麼?

19、大白話聊聊Java併發面試問題之Java 8如何優化CAS效能?

20、大白話聊聊Java併發面試問題之談談你對AQS的理解?

21、大白話聊聊Java併發面試問題之公平鎖與非公平鎖是啥?

22、大白話聊聊Java併發面試問題之微服務註冊中心的讀寫鎖優化

23、網際網路公司的面試官是如何360°無死角考察候選人的?(上篇)

24、網際網路公司面試官是如何360°無死角考察候選人的?(下篇)

25、Java進階面試系列之一:哥們,你們的系統架構中為什麼要引入訊息中介軟體?

26、【Java進階面試系列之二】:哥們,那你說說系統架構引入訊息中介軟體有什麼缺點?

27、【行走的Offer收割機】記一位朋友斬獲BAT技術專家Offer的面試經歷

28、【Java進階面試系列之三】哥們,訊息中介軟體在你們專案裡是如何落地的?

29、【Java進階面試系列之四】扎心!線上服務當機時,如何保證資料100%不丟失?

30、一次JVM FullGC的背後,竟隱藏著驚心動魄的線上生產事故!

31、【高併發優化實踐】10倍請求壓力來襲,你的系統會被擊垮嗎?

32、【Java進階面試系列之五】訊息中介軟體叢集崩潰,如何保證百萬生產資料不丟失?

33、億級流量系統架構之如何在上萬併發場景下設計可擴充套件架構(上)?

34、億級流量系統架構之如何在上萬併發場景下設計可擴充套件架構(中)?

35、億級流量系統架構之如何在上萬併發場景下設計可擴充套件架構(下)?

36、億級流量架構第二彈:你的系統真的無懈可擊嗎?

37、億級流量系統架構之如何保證百億流量下的資料一致性(上)

38、億級流量系統架構之如何保證百億流量下的資料一致性(中)?

39、億級流量系統架構之如何保證百億流量下的資料一致性(下)?

40、網際網路面試必殺:如何保證訊息中介軟體全鏈路資料100%不丟失(1)

41、網際網路面試必殺:如何保證訊息中介軟體全鏈路資料100%不丟失(2

42、面試大殺器:訊息中介軟體如何實現消費吞吐量的百倍優化?

43、高併發場景下,如何保證生產者投遞到訊息中介軟體的訊息不丟失?

44、兄弟,用大白話給你講小白都能看懂的分散式系統容錯架構

45、從團隊自研的百萬併發中介軟體系統的核心設計看Java併發效能優化

作者:石杉的架構筆記 連結:juejin.im/post/5c263a… 來源:掘金 著作權歸作者所有,轉載請聯絡作者獲得授權!

相關文章