歡迎關注微信公衆號:石杉的架構筆記(id:shishan100)面試
個人新課**《C2C 電商系統微服務架構120天實戰訓練營》在公衆號儒猿技術窩**上線了,感興趣的同窗,能夠點擊下方連接瞭解詳情:算法
億級流量架構專欄:後端
上篇文章(億級流量系統架構之如何設計承載百億流量的高性能架構)聊了一下系統架構中,百億流量級別高併發寫入場景下,如何承載這種高併發寫入,同時如何在高併發寫入的背景下還能保證系統的超高性能計算。緩存
這篇文章我們繼續來聊一下,百億級別的海量數據場景下還要支撐每秒十萬級別的高併發查詢,這個架構該如何演進和設計?性能優化
我們先來看看目前系統已經演進到了什麼樣的架構,你們看看下面的圖:服務器
首先回顧一下,整個架構右側部分演進到的那個程度,其實已經很是的不錯了,由於百億流量,每秒十萬級併發寫入的場景,使用MQ限流削峯、分佈式KV集羣給抗住了。微信
接着使用了計算與存儲分離的架構,各個Slave計算節點會負責提取數據到內存中,基於自研的SQL內存計算引擎完成計算。同時採用了數據動靜分離的架構,靜態數據所有緩存,動態數據自動提取,保證了儘量把網絡請求開銷下降到最低。markdown
另外,經過自研的分佈式系統架構,包括數據分片和計算任務分佈式執行、彈性資源調度、分佈式高容錯機制、主備自動切換機制,都能保證整套系統的任意按需擴容,高性能、高可用的的運行。網絡
下一步,我們得來研究研究架構裏左側的部分了。
其實你們會注意到,在左側還有一個MySQL,那個MySQL就是用來承載實時計算結果和離線計算結果放在裏面彙總的。
終端的商家用戶就能夠隨意的查詢MySQL裏的數據分析結果,支撐本身的決策,他能夠看當天的數據分析報告,也能夠看歷史上任何一段時期內的數據分析報告。
可是那個MySQL在早期可能還好一些,由於其實存放在這個MySQL裏的數據量相對要小一些,畢竟是計算後的一些結果罷了。可是到了中後期,這個MySQL但是也朝不保夕了。
給你們舉一個例子,離線計算鏈路裏,若是天天增量數據是1000萬,那麼天天計算完之後的結果大概只有50萬,天天50萬新增數據放入MySQL,其實仍是能夠接受的。
可是若是天天增量數據是10億,那麼天天計算完之後的結果大體會是千萬級,你能夠算他是計算結果有5000萬條數據吧,天天5000萬增量數據寫入左側的MySQL中,你以爲是啥感受?
能夠給你們說說系統當時的狀況,基本上就是,單臺MySQL服務器的磁盤存儲空間很快就要接近滿掉,並且單表數據量都是幾億、甚至十億的級別。
這種量級的單表數據量,你以爲用戶查詢數據分析報告的時候,體驗能好麼?基本當時一次查詢都是幾秒鐘的級別。很慢。
更有甚者,出現過用戶一次查詢要十秒的級別,甚至幾十秒,上分鐘的級別。很崩潰,用戶體驗不好,遠遠達不到付費產品的級別。
因此解決了右側的存儲和計算的問題以後,左側的查詢的問題也迫在眉睫。新一輪的重構,勢在必行!
首先就是老一套,分庫分表 + 讀寫分離,這個基本是基於MySQL的架構中,必經之路了,畢竟實施起來難度不是特別的高,並且速度較快,效果比較顯著。
整個的思路和以前第一篇文章(《大型系統架構演進之如何支撐百億級數據的存儲與計算》)講的基本一致。
說白了,就是分庫後,每臺主庫能夠承載部分寫入壓力,單庫的寫併發會下降;其次就是單個主庫的磁盤空間能夠下降負載的數據量,不至於很快就滿了;
而分表以後,單個數據表的數據量能夠下降到百萬級別,這個是支撐海量數據以及保證高性能的最佳實踐,基本兩三百萬的單表數據量級仍是合理的。
而後讀寫分離以後,就能夠將單庫的讀寫負載壓力分離到主庫和從庫多臺機器上去,主庫就承載寫負載,從庫就承載讀負載,這樣避免單庫所在機器的讀寫負載太高,致使CPU負載、IO負載、網絡負載太高,最後搞得數據庫機器宕機。
首先這麼重構一下數據庫層面的架構以後,效果就好的多了。由於單表數據量下降了,那麼用戶查詢的性能獲得很大的提高,基本能夠達到1秒之內的效果。
上面那套初步的分庫分表+讀寫分離的架構確實支撐了一段時間,可是慢慢的那套架構又暴露出來了弊端出來了,由於商家用戶都是開了數據分析頁面以後,頁面上有js腳本會每隔幾秒鐘就發送一次請求到後端來加載最新的數據分析結果。
此時就有一個問題了,漸漸的查詢MySQL的壓力愈來愈大,基本上可預見的範圍是朝着每秒10級別去走。
可是咱們分析了一下,其實99%的查詢,都是頁面JS腳本自動發出刷新當日數據的查詢。只有1%的查詢是針對昨天之前的歷史數據,用戶手動指定查詢範圍後來查詢的。
可是如今的這個架構之下,咱們是把當日實時數據計算結果(表明了熱數據)和歷史離線計算結果(表明了冷數據)都放在一塊兒的,因此你們能夠想象一下,熱數據和冷數據放在一塊兒,而後對熱數據的高併發查詢佔到了99%,那這樣的架構還合理嗎?
固然不合理,咱們須要再次重構系統架構。
針對上述提到的問題,很明顯要作的一個架構重構就是**冷熱數據分離。**也就是說,將今日實時計算出來的熱數據放在一個MySQL集羣裏,將離線計算出來的冷數據放在另一個MySQL集羣裏。
而後開發一個數據查詢平臺,封裝底層的多個MySQL集羣,根據查詢條件動態路由到熱數據存儲或者是冷數據存儲。
經過這個步驟的重構,咱們就能夠有效的將熱數據存儲中單表的數據量下降到更少更少,有的單表數據量可能就幾十萬,由於將離線計算的大量數據結果從表裏剝離出去了,放到另一個集羣裏去。此時你們可想而知,效果固然是更好了。
由於熱數據的單表數據量減小了不少,當時的一個最明顯的效果,就是用戶99%的查詢都是針對熱數據存儲發起的,性能從原來的1秒左右下降到了200毫秒之內,用戶體驗提高,你們感受更好了。
架構演進到這裏,看起來好像還不錯,可是其實問題仍是不少。由於到了這個階段,系統遇到了另一個較爲嚴重的問題:冷數據存儲,若是徹底用MySQL來承載是很不靠譜的。冷數據的數據量是日增加不斷增長,並且增速很快,天天都新增幾千萬。
所以你的MySQL服務器將會面臨不斷的須要擴容的問題,並且若是爲了支撐這1%的冷數據查詢請求,不斷的擴容增長高配置的MySQL服務器,你們以爲靠譜麼?
確定是不合適的!
要知道,大量分庫分表後,MySQL大量的庫和表維護起來是至關麻煩的,修改個字段?加個索引?這都是一場麻煩事兒。
此外,由於對冷數據的查詢,通常都是針對大量數據的查詢,好比用戶會選擇過去幾個月,甚至一年的數據進行分析查詢,此時若是純用MySQL仍是挺災難性的。
由於當時明顯發現,針對海量數據場景下,一會兒查詢分析幾個月或者幾年的數據,性能是極差的,仍是很容易搞成幾秒甚至幾十秒纔出結果。
所以針對這個冷數據的存儲和查詢的問題,咱們最終選擇了自研一套基於NoSQL來存儲,而後基於NoSQL+內存的SQL計算引擎。
具體來講,咱們會將冷數據所有采用ES+HBase來進行存儲,ES中主要存放要對冷數據進行篩選的各類條件索引,好比日期以及各類維度的數據,而後HBase中會存放全量的數據字段。
由於ES和HBase的原生SQL支持都不太好,所以咱們直接自研了另一套SQL引擎,專門支持這種特定的場景,就是基本沒有多表關聯,就是對單個數據集進行查詢和分析,而後支持NoSQL存儲+內存計算。
這裏有一個先決條件,就是若是要作到對冷數據所有是單表類的數據集查詢,必需要在冷數據進入NoSQL存儲的時候,所有基於ES和HBase的特性作到多表入庫關聯,進數據存儲就所有作成大寬表的狀態,將數據關聯所有上推到入庫時完成,而不是在查詢時進行。
對冷數據的查詢,咱們自研的SQL引擎首先會根據各類where條件先走ES的分佈式高性能索引查詢,ES能夠針對海量數據高性能的檢索出來須要的那部分數據,這個過程用ES作是最合適的。
接着就是將檢索出來的數據對應的完整的各個數據字段,從HBase裏提取出來,拼接成完成的數據。
而後就是將這份數據集放在內存裏,進行復雜的函數計算、分組聚合以及排序等操做。
上述操做,所有基於自研的針對這個場景的查詢引擎完成,底層基於Elasticsearch、HBase、純內存來實現。
好了,到此爲止,冷數據的海量數據存儲、高性能查詢的問題,就解決了。接着回過頭來看看當日實時數據的查詢,其實實時數據的每日計算結果不會太多,並且寫入併發不會特別特別的高,每秒上萬也就差很少了。
所以這個背景下,就是用MySQL分庫分表來支撐數據的寫入、存儲和查詢,都沒問題。
可是有一個小問題,就是說每一個商家的實時數據其實不是頻繁的變動的,在一段時間內,可能壓根兒沒變化,所以不須要高併發請求,每秒10萬級別的所有落地到數據庫層面吧?要全都落地到數據庫層面,那可能要給每一個主庫掛載不少從庫來支撐高併發讀。
所以這裏咱們引入了一個緩存集羣,實時數據每次更新後寫入的時候,都是寫數據庫集羣同時還寫緩存集羣的,是雙寫的方式。
而後查詢的時候是優先從緩存集羣來走,此時基本上90%以上的高併發查詢都走緩存集羣了,而後只有10%的查詢會落地到數據庫集羣。
好了,到此爲止,這個架構基本左邊也都重構完畢:
經實踐,整個效果很是的好。用戶對熱數據的查詢基本可能是幾十毫秒的響應速度,對冷數據的查詢基本都是200毫秒之內的響應速度。
其實架構演進到這裏已經很不容易了,由於看似這麼一張圖,裏面涉及到無數的細節和技術方案的落地,須要一個團隊耗費至少1年的時間才能作到這個程度。
可是接下來,咱們要面對的,就是高可用的問題,由於付費級的產品,咱們必需要保證超高的可用性,99.99%的可用性,甚至是99.999%的可用性。
可是越是複雜的系統,越容易出現問題,對應的高可用架構就越是複雜無比,所以下篇文章,咱們聊聊:《億級流量系統架構之如何設計全鏈路99.99%高可用架構》。
一大波微服務、分佈式、高併發、高可用的****原創系列
文章正在路上,歡迎掃描下方二維碼,持續關注:
石杉的架構筆記(id:shishan100)
十餘年BAT架構經驗傾囊相授