參照一個大佬的文章,我也寫一篇應對高併發的文章

參照一個大佬的文章,我也寫一篇高併發的文章,探討一下這門高級的現象,以及一些解決措施。

 

一個關於高併發的問題:

如何設計一個高併發系統?

那位大佬說:如果真的幹過高併發系統的人,面試官是絕對不會對你提出這個問題的,否則就是他太不明智了。至於爲嘛這樣說呢,因爲如果設計一個高併發系統,這句話就是錯誤的了,因爲在脫離了業務的系統架構中都是一羣紙上談兵,真正在複雜業務場景而且存在高併發的時候,那系統架構一定不是那麼簡單的,用個redis、消息隊列就能解決?那不是扯淡嗎?在真實的實際開發中,系統架構配上了業務場景後,會比這種所謂的“高併發”要複雜的多多的。

 

爲什麼會出現高併發呢?爲啥高併發聽起來就很牛掰的一個東西呢?一個併發很厲害,加一個高就更加高級了,都是服務級別了。

 

那麼到底什麼是高併發呢?

先說下是什麼原因會出現高併發系統的,在剛剛開始的時候,一些基礎的系統,都是直連數據庫的,直接對數據庫操作CRUD,在之前的帖子裏面,我也說到過,對於MySQL而言,能夠一秒承受2000的併發量就差不多了,真達到5000,估計就癱了。那麼在從前信息量還沒有大爆炸之前,2000的併發並未常見,但是現在就不一樣的,現在人人都接觸了互聯網,很多的app,網站,實時在線人數就達到了幾萬,甚至上百萬,在大型的網絡活動的時候,幾千萬的人在線並不是不可能的。例如淘寶的雙十一,那是普通用戶沒感覺,在阿里內部,每年雙十一一過去,就開始着手準備來年的雙十一技術支持了,做電商的朋友最燒腦的就是類似秒殺活動了,雙十一0點的時候,每秒十幾萬的併發量那不是跟吃麪條一樣麼???所以,現在用戶量越大,那麼作爲技術儲備,架構支撐,我們就要考慮從系統架構上來應對高併發的請求了。。

 

那麼從那個大佬帖子中共總結了6點,我就用我自己的理解來講解一下,有哪些併發系統設計的優化方案,向這些優化方案都是高級操作,所以大家能夠學習就堅決學習一下。

1.系統拆分:爲啥要拆分?這就是做分佈式的概念了,將整個系統按照各個服務進行劃分,各司其職,然後通過webservice或者rpc通訊機制,服務間內部通訊,一種面向服務(SOA)的架構思維。就好比一堆人開個飯館,A側重做端菜,服務員的業務,B側重做炒菜的業務,C作爲老闆,只是在前臺安排一下新來的客人做哪裏,然後安排A帶領去,然後收一下銀之類的;由於炒菜可能業務量比較重,爲了讓菜炒得及時,炒得好喫,那麼B專職只炒菜;A呢,有可能早上的時候,人少,那麼也充當一下配菜的角色,幫助B進行一下早上的切菜,那這就是分佈式思想了。那麼針對收銀,在超市裏面,我們通常可以看到有多個收銀的入口,這樣的話,是不是就分擔了收銀的壓力了呢?收銀員幹得活都一樣的。但是就是有好幾個人同時在收銀,那麼顧客看到哪裏人排隊少,那麼顧客就會去那裏排隊,均攤每個收銀隊伍的長度了。那麼在系統中,也是模擬類似的思想來增加結賬的效率,我們可以通過一些分佈式框架來搭建一個分佈式系統,然後有可能多個服務節點在分佈式架構中註冊,然後做着同樣的業務處理,設計多個數據庫集羣部署,那麼多個數據庫,一個數據庫最大扛2000,多個2000,並行工作,那併發量的瓶頸就接觸了。

2.緩存,緩存這個概念其實在任何的設備上都有直接的應用,怎麼理解呢?好比一個手機,內存和硬盤,我們在打遊戲的時候,剛剛啓動和平精英,是不是需要彈一個天美,,然後一個燒雞?然後正在加載中?然後再一步步進到喫雞的運行界面中?是的,它正是從Android系統中自帶的sqlite輕量數據庫讀取遊戲的數據信息,這種db操作是很耗時,耗資源的。那我們已經啓動好了遊戲,臨時退出一下游戲,去聊個天,然後再返回的時候,它並不需要像剛啓動那樣一點一點加載,而是直接就加載好的,這就是它遊戲數據直接在內存中準備好了,並沒有回收。這個例子也不一定和緩存,db的概念一模一樣,理解個大概意思。只需要記住,高速緩衝區不是數據庫直接能比的,要知道,redis可是輕輕鬆鬆單機應對幾萬的併發量的。所以在系統中緩存必須要,尤其在於那些主read業務的服務中,可能就是配合多個緩存服務工作的,緩存的作用可不止那麼點,比如緩存共享,分佈式鎖,各種提高業務的處理能力的支持。那麼至於高併發系統中,緩存是一員大將。

3.MQ(消息隊列)消息隊列,在我的另一篇文章中有詳細的介紹過消息隊列的幾大優點,以及任何架構帶來優點的同時都會帶來一些弊端,這裏就不詳細介紹了。昨天朋友說到一個問題,他把餘額寶的錢提取到銀行卡的時候,發現餘額寶中的錢扣了,但是銀行卡中還沒到賬,然後他有點慌,哈哈。其實我們大家都有類似的經歷,我們從各種支付平臺,網絡賬戶進行餘額提現的時候都會發現一個提示:提現24小時內到賬。快一點的2小時到賬。這也是銀行系統的一種自保機制,提現是需要等待的。這麼講,倘若,好多個平臺,同時提現到一家銀行,在一秒鐘,這家銀行突然同時收到了5000的提現請求,需要在各自對應的賬戶中打款,然後加事務,給各大平臺響應,我這邊加好錢了,你那邊趕緊扣,或者說我這邊加錢的時候碰到點問題,失敗了,你那邊回滾一下。想想,這流程還是挺複雜的,5000/秒,系統也喫不消啊,那麼就需要中間件的接入了,比如消息隊列,你們進來的提現請求,一個個排好隊,我加錢一個個加,不要着急,我一累倒了,誰都加不了。我叫下一個的時候,我再把你的請求領進來加錢。這樣就是將加錢服務的業務量平攤,將頂峯進行削峯了。但是我立馬回了我朋友一句,要是消息丟失啦這咋辦。哈哈,平臺扣了錢,銀行卡錢沒加上。。那就GG了,所以也就有了備份節點待命的保護機制,如果像這種主從服務,主服務掛了,那麼其他配合的服務等同於掛了,那系統也掛了。回到正題,高併發系統怎麼通過MQ來進行併發壓力降低。也是一個道理,排隊,我db操作慢慢來,需要異步,但是這樣是最好保護我係統的方式,能做的,只有我加硬件,算法優化,將這“慢慢來”的速度提升,按照2000最大的mysql,一秒5000,也就是2-3秒的延遲感,而且我們都是異步機制,幾乎對於用戶來說就是無感的。那麼你幾萬,我多開幾個收銀入口,那或許來說原來1秒,我現在就是0.2秒了。

4.分庫分表,如果還問有什麼優化的空間,那就在數據庫的角度進行優化了,且不說那種粒度小的優化方式。可以從冷熱數據,按業務將數據庫的表分成幾個庫,幾個數據庫服務。如果是那種記錄表,可以按年月劃分不同時間段表,這樣,每一張表的IO壓力就降低了,我就不信了,這還防不住併發?

5.讀寫分離:這其實也是也是數據庫角度的優化方案,我公司現在用到的一張表就是幾乎的讀操作,原始數據表,根本不讓更新,刪除操作,然後讀取的話,通常都是後臺erp管理系統用於數據統計用到,這是在erp後臺系統中,然後寫入操作,就是在examservice中進行檢測業務時進行隊列寫入的。那麼這裏我們也可以用一個主從架構,主庫負責寫入,我負責生產,從庫負責讀取,那麼這樣再添加一個從庫也是很方便的,多一個消費服務就是了。

6.ElaticsSearch(基於Lucene的開源搜索項目),這是大數據範疇的一個工具了,其中的倒排索引,索引量爆炸都爲主核心,想我們熟悉的百度搜索引擎,谷歌搜索引擎,都是應用到這個倒排索引的方案,然後再基於一些網頁爬蟲進行的操作了。因爲es是基於分佈式的,那麼可以隨意的擴容,分佈式的誕生一部分原因就是爲了支撐高併發的,那麼至於其中的倒排索引原理,我就現先不在這裏細講了,下次再寫篇文章細講一下。所以在搜索引擎框架的選用,全文搜索的操作可以選擇es來承載。

 

基本上來說,以上6點都是很常見的併發系統設計方案,對於選擇的時候,也要根據實際的業務場景來進行併發系統設計。需要考慮哪些表結構的哪個字段添加索引,索引添加不當,反而會性能降低;哪些需要分表,分表後,到時候有哪些業務需要鏈表查詢,哪些的操作頻率高,我們都需要考慮取捨的。哪些數據是需要放到緩存的,因爲有些需要實時更新的,我們需要實時的從db中讀取,哪些數據的併發訪問的,這些地方都要考慮緩存擊穿,緩存穿透,緩存雪崩。所以說,設計一個高併發的系統,設計好了,無疑是好的,是可以抗很大併發壓力的,但是要知道有些時候,殺雞用牛刀,你多浪費的力氣做什麼。系統集成的架構越多,維護的成本就會越大,而且,併發系統在市面上都是通用的,並不是針對某個公司現狀針對設計的,所以得結合公司項目自身的情況來進行適當的選擇。

祝各位代碼無bug!!

 

 

這裏拷貝一張別人的圖:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章