程序員硬核吃瓜宋慧喬宋仲基離婚、范冰冰李晨分手
作者 | 中華石杉
責編 | 伍杏玲
本文經授權轉載自石杉的架構筆記
【CSDN 編者按】昨天一連出現4個熱點新聞:雙宋離婚、唐藝昕張若昀結婚、寶強母親去世、李晨范冰冰分手。廣大網友在吃瓜之餘,紛紛心疼其新浪程序員:
扛過頭三次熱點的微博,在最後也終於熬不住了:
估計是程序員有點累吧,需要喘口氣。
我們在吃瓜之餘,作為程序員,你是否會思考:究竟後台需要如何設計才能扛得住一天四熱點連發呢?
本文作者為從業十多年的資深程序員,將在本文詳細地給大家答疑解惑。
我們先普及下背景:如何用緩存集群承載讀請求?
為什麼要用緩存集群
其實使用緩存集群的時候,最怕的就是熱Key、大Value這兩種情況,那啥叫熱Key大Value呢?
簡單來說,熱Key就是你的緩存集群中的某個Key瞬間被數萬甚至十萬的並發請求打爆。大Value,就是某個Key對應的Value可能有GB級的大小,導致查詢Value的時候導致網路相關的故障問題。
我們先來看看下面一幅圖,假設你手頭有個系統,他本身是集群部署的,然後後面有一套緩存集群,這個集群不管你用Redis Cluster,還是Memcached,或者是公司自研緩存集群,都可以。
那麼,這套系統用緩存集群幹什麼呢?
很簡單,在緩存里放一些平時不怎麼變動的數據,然後用戶在查詢大量的平時不怎麼變動的數據的時候,不就可以直接從緩存里走了嗎?
緩存集群的並發能力是很強的,而且讀緩存的性能是很高的。舉個例子,假設你每秒有2萬請求,但是其中90%都是讀請求,那麼每秒1.8萬請求都是在讀一些不太變化的數據,而不是寫數據。
那此時你把這些數據都放在資料庫里,然後每秒發送2萬請求到資料庫上讀寫數據,你覺得合適嗎?
當然不合適了,如果要用資料庫承載每秒2萬請求的話,那麼不好意思,你很可能就得搞分庫分表 + 讀寫分離。
比如可能得分3個主庫,承載每秒2000的寫入請求,然後每個主庫掛3個從庫,一共9個從庫承載每秒1.8萬的讀請求。
這樣的話,可能就需要一共是12台高配置的資料庫伺服器,這是很耗費錢的,成本非常高,很不合適。
大家看看下面的圖,來體會下這種情況。
因此,我們完全可以把平時不太變化的數據放在緩存集群里,緩存集群可以採用2主2從,主節點用來寫入緩存,從節點用來讀緩存。
以緩存集群的性能,2個從節點完全可以用來承載每秒1.8萬的大量讀請求,然後3個資料庫主庫就是承載每秒2000的寫請求和少量其他讀請求就OK了。
這樣一來,耗費的機器瞬間變成了4台緩存機器 + 3台資料庫機器 = 7台機器,是不是比之前的12台機器減少了很大的資源開銷?
沒錯,緩存其實在系統架構里是非常重要的組成部分。很多時候,對於那些很少變化但是大量高並發讀的數據,通過緩存集群來抗高並發讀,是非常合適的。
我們看看下面的圖,體會一下這個過程。
需要說明的是,這裡所有的機器數量、並發請求量都是一個示例,大家主要是體會一下這個意思就好。
其目的主要是給一些不太熟悉緩存相關技術的同學一點背景性的闡述,讓這些同學能夠理解在系統里用緩存集群承載讀請求是什麼意思。
20萬用戶同時訪問一個熱點緩存
好了,背景已經給大家解釋清楚,現在就可以給大家說說今天重點要討論的問題:熱點緩存。
我們來做一個假設,現在有10個緩存節點來抗大量的讀請求。正常情況下,讀請求應該是均勻的落在10個緩存節點上。
這10個緩存節點,每秒承載1萬請求是差不多的。
然後我們再做一個假設,一個節點承載2萬請求是極限,所以一般你就限制一個節點正常承載1萬請求就OK,稍微留一點Buffer出來。
好,所謂的熱點緩存問題是什麼意思呢?很簡單,就是突然因為莫名的原因,出現大量的用戶訪問同一條緩存數據。
比如像昨天那樣,雙宋離婚、寶強母親去世、李晨范冰冰分手,這是不是會引發短時間內每秒都數十萬用戶去查看這幾條熱點新聞?
假設上述3條新聞就是3個緩存,對應3個緩存Key,這些Key都存在於一台緩存機器上。
然後某條新聞一公布,比如范冰冰一發布微博,接著瞬間就可能幾十萬請求奔向那一台機器。
此時會如何?我們看看下面的圖,來體會一下這種絕望的感受。
很明顯了,我們剛才假設的是一個緩存Slave節點最多每秒就是2萬的請求,當然實際緩存單機承載5萬~10萬讀請求也是可能的,這裡就是一個假設。
結果每秒突然奔過來20萬請求到這台機器上會怎麼樣?很簡單,上面圖裡那台被20萬請求指向的緩存機器會過度操勞而宕機的。
那麼如果緩存集群開始出現機器的宕機,此時會如何?
此時讀請求發現讀不到數據,會從資料庫里提取原始數據,然後放入剩餘的其他緩存機器里去。但是接踵而來的每秒20萬請求,會再次壓垮其他的緩存機器。
以此類推,最終導致緩存集群全盤崩潰,引發系統整體宕機。
咱們看看下面的圖,再感受一下這個恐怖的現場。
基於流式計算技術的緩存熱點自動發現
其實這裡關鍵的一點,就是對於這種熱點緩存,系統需要能夠在熱點緩存突然發生的時候,直接發現然後瞬間立馬實現毫秒級的自動負載均衡。
那麼我們就先來說說,你如何自動發現熱點緩存問題?
首先你要知道,一般出現緩存熱點的時候,每秒並發肯定是很高的,可能每秒都幾十萬甚至上百萬的請求量過來,這都是有可能的。
所以,此時完全可以基於大數據領域的流式計算技術來進行實時數據訪問次數的統計,比如Storm、Spark Streaming、Flink。
一旦在實時數據訪問次數統計的過程中,比如發現一秒之內,某條數據突然訪問次數超過了1000,就直接立馬把這條數據判定為是熱點數據,可以將這個發現出來的熱點數據寫入比如ZooKeeper中。
當然,系統如何判定熱點數據,可以根據自己的業務還有經驗值來就可以了。
大家看看下面這張圖,看看整個流程是如何進行的。
這裡肯定有人會問,那你的流式計算系統在進行數據訪問次數統計的時候,會不會也存在說單台機器被請求每秒幾十萬次的問題呢?
答案是:否。
因為流式計算技術,尤其是Storm這種系統,他可以做到同一條數據的請求過來,先分散在很多機器里進行本地計算,最後再匯總局部計算結果到一台機器進行全局匯總。
所以幾十萬請求可以先分散在比如100台機器上,每台機器統計了這條數據的幾千次請求。
然後100條局部計算好的結果匯總到一台機器做全局計算即可,所以基於流式計算技術來進行統計是不會有熱點問題的。
熱點緩存自動載入為JVM本地緩存
我們自己的系統可以對ZooKeeper指定的熱點緩存對應的Znode進行監聽,如果有變化他立馬就可以感知到了。
此時系統層就可以立馬把相關的緩存數據從資料庫載入出來,然後直接放在自己系統內部的本地緩存里即可。
這個本地緩存,你用Ehcache、Hashmap,其實都可以,一切看自己的業務需求。我們這裡主要說的就是將緩存集群里的集中式緩存,直接變成每個系統自己本地實現緩存即可,每個系統本地是無法緩存過多數據的。
因為一般這種普通系統單實例部署機器可能就一個4核8G的機器,留給本地緩存的空間是很少的,所以用來放這種熱點數據的本地緩存是最合適的,剛剛好。
假設你的系統層集群部署了100台機器,那麼好了,此時100台機器瞬間在本地都會有一份熱點緩存的副本。
然後接下來對熱點緩存的讀操作,直接系統本地緩存讀出來就給返回了,不用再走緩存集群了。
這樣的話,也不可能允許每秒20萬的讀請求到達緩存機器的一台機器上讀一個熱點緩存了,而是變成100台機器每台機器承載數千請求,那麼那數千請求就直接從機器本地緩存返回數據了,這是沒有問題的。
我們再來畫一幅圖,一起來看看這個過程:
限流熔斷保護
除此之外,在每個系統內部,其實還應該專門加一個對熱點數據訪問的限流熔斷保護措施。
每個系統實例內部都可以加一個熔斷保護機制,假設緩存集群最多每秒承載4萬讀請求,那麼一共有100個系統實例。
這樣的話就該限制好,每個系統實例每秒最多請求緩存集群讀操作不超過400次,一超過就可以熔斷掉,不讓請求緩存集群,直接返回一個空白信息,然後用戶稍後會自行再次重新刷新頁面之類的。
通過系統層自己直接加限流熔斷保護措施,可以很好的保護後面的緩存集群、資料庫集群之類的不要被打死。
再來一幅圖,一起來看看:
總結
具體要不要在系統里實現這種複雜的緩存熱點優化架構呢?這個還要看你們自己的系統有沒有這種場景了。
如果你的系統有熱點緩存問題,那麼就要實現類似本文的複雜熱點緩存支撐架構。但是如果沒有的話,那麼也別過度設計,其實你的系統可能根本不需要這麼複雜的架構。
如果是後者,那麼大伙兒就權當看看本文,了解一下對應的架構思想好了。
作者簡介:中華石杉,十餘年BAT架構經驗,傾囊相授
公眾號:石杉的架構筆記(id:shishan100)
【END】
熱 文推 薦
?蘋果首席設計官將離職;華為將從世界範圍招攬天才少年;新版 Edge 更新 | 極客頭條
?六維圖見過么?Python 畫出來了!
?想換行做 5G 的開發者到底該咋辦?
?老司機教你如何寫出沒人敢維護的代碼!
?Python有哪些技術上的優點?比其他語言好在哪兒?
?上不了北大「圖靈」、清華「姚班」,AI專業還能去哪上?
?公鏈史記 | 從鴻蒙初辟到萬物生長的十年激蕩……
?邊緣計算容器化是否有必要?
?馬雲曾經偶像,終於把阿里留下的1400億敗光了!
點擊閱讀原文,輸入關鍵詞,搜索CSDN文章。
你點的每個「在看」,我都認真當成了喜歡


※五大行業會古都 華為賦能全行業開發者
※華為反擊!要求美國運營商巨頭支付 10 億美元專利費
TAG:CSDN |