1. 程式人生 > >網際網路架構“高併發”到底怎麼玩?

網際網路架構“高併發”到底怎麼玩?

什麼是高併發?

高併發(High Concurrency)是網際網路分散式系統架構設計中必須考慮的因素之一,它通常是指,通過設計保證系統能夠同時並行處理很多請求。

高併發相關的常見指標有哪些?

  • 響應時間(Response Time)
  • 吞吐量(Throughput)
  • 每秒查詢率QPS(Query Per Second)
  • 併發使用者數

什麼是響應時間?

系統對請求做出響應的時間。

例如:系統處理一個HTTP請求需要200ms,這個200ms就是系統的響應時間。

什麼是吞吐量?

單位時間內處理的請求數量。

什麼是QPS?

每秒響應請求數。在網際網路領域,這個指標和吞吐量區分的沒有這麼明顯。

什麼是併發使用者數?

同時承載正常使用系統功能的使用者數量。

例如:一個即時通訊系統,同時線上量一定程度上代表了系統的併發使用者數。

如何提升系統的併發能力?

網際網路分散式架構設計,提高系統併發能力的方式,方法論上主要有兩種:

  • 垂直擴充套件(Scale Up)
  • 水平擴充套件(Scale Out)

什麼是垂直擴充套件?

垂直擴充套件是指,提升單機處理能力,垂直擴充套件的方式又有兩種:

  • 增強單機硬體效能,例如:增加CPU核數如32核,升級更好的網絡卡如萬兆,升級更好的硬碟如SSD,擴充硬碟容量如2T,擴充系統記憶體如128G;
  • 提升單機架構效能,例如:使用Cache來減少IO次數,使用非同步來增加單服務吞吐量,使用無鎖資料結構來減少響應時間;

畫外音:在網際網路業務發展非常迅猛的早期,如果預算不是問題,強烈建議使用“增強單機硬體效能”的方式提升系統併發能力,因為這個階段,公司的戰略往往是發展業務搶時間,而“增強單機硬體效能”往往是最快的方法。

垂直擴充套件有什麼瓶頸?

不管是提升單機硬體效能,還是提升單機架構效能,都有一個致命的不足:單機效能總是有極限的。

如何突破單機的極限?

網際網路分散式架構設計,高併發終極解決方案還是水平擴充套件。

什麼是水平擴充套件?

只要增加伺服器數量,就能線性擴充系統性能。

常見的網際網路分層架構如何?

各層該如何落地水平擴充套件?

常見網際網路分散式架構如上,分為:

  • 客戶端層:典型呼叫方是瀏覽器browser或者手機應用APP;
  • 反向代理層:系統入口,反向代理;
  • 站點應用層:實現核心應用邏輯,返回html或者json;
  • 服務層:如果實現了服務化,就有這一層;
  • 資料-快取層:快取加速訪問儲存;
  • 資料-資料庫層:資料庫固化資料儲存;

要想真個系統支援水平擴充套件,就必須每一層都支援水平擴充套件。

反向代理層如何進行水平擴充套件?

反向代理層的水平擴充套件,是通過“DNS輪詢”實現的:dns-server對於一個域名配置了多個解析ip,每次DNS解析請求來訪問dns-server,會輪詢返回這些ip。

當nginx成為瓶頸的時候,只要增加伺服器數量,新增nginx服務的部署,增加一個外網ip,就能擴充套件反向代理層的效能,做到理論上的無限高併發。

站點層如何進行水平擴充套件?

站點層的水平擴充套件,是通過“nginx”實現的,通過修改nginx.conf,可以設定多個web後端。

畫外音:nginx是個例子,有可能是LVS或者F5等反向代理。

當web後端成為瓶頸的時候,只要增加伺服器數量,新增web服務的部署,在nginx配置中配置上新的web後端,就能擴充套件站點層的效能,做到理論上的無限高併發。

服務層如何進行水平擴充套件?

服務層的水平擴充套件,是通過“服務連線池”實現的。

站點層通過RPC-client呼叫下游的服務層RPC-server時,RPC-client中的連線池會建立與下游服務多個連線,當服務成為瓶頸的時候,只要增加伺服器數量,新增服務部署,在RPC-client處建立新的下游服務連線,就能擴充套件服務層效能,做到理論上的無限高併發。

畫外音:如果需要優雅的進行服務層自動擴容,這裡可能需要配置中心裡服務自動發現功能的支援。

資料層如何進行水平擴充套件?

在資料量很大的情況下,資料層(快取,資料庫)涉及資料的水平擴充套件,將原本儲存在一臺伺服器上的資料(快取,資料庫)水平拆分到不同伺服器上去,以達到擴充系統性能的目的。

網際網路資料層常見的水平拆分方式有這麼幾種,以資料庫為例:

1. 按照範圍水平拆分

每一個數據服務,儲存一定範圍的資料,上圖為例:

  • user0庫,儲存uid範圍1-1kw
  • user1庫,儲存uid範圍1kw-2kw

這個方案的好處是:

  • 規則簡單,service只需判斷一下uid範圍就能路由到對應的儲存服務;
  • 資料均衡性較好;
  • 比較容易擴充套件,可以隨時加一個uid[2kw,3kw]的資料服務;

不足是:

  • 請求的負載不一定均衡,一般來說,新註冊的使用者會比老使用者更活躍,大range的服務請求壓力會更大;

2. 按照雜湊水平拆分

每一個數據庫,儲存某個key值hash後的部分資料,上圖為例:

  • user0庫,儲存偶數uid資料
  • user1庫,儲存奇數uid資料

這個方案的好處是:

  • 規則簡單,service只需對uid進行hash能路由到對應的儲存服務;
  • 資料均衡性較好;
  • 請求均勻性較好;

不足是:

  • 不容易擴充套件,擴充套件一個數據服務,hash方法改變時候,可能需要進行資料遷移;

通過水平拆分來擴充系統性能,與主從同步讀寫分離來擴充資料庫效能,有什麼本質的不同?

畫外音:這兩個方案千萬別搞混。

通過水平拆分擴充套件資料庫效能:

  • 每個伺服器上儲存的資料量是總量的1/n,所以單機的效能也會有提升;
  • n個伺服器上的資料沒有交集,那個伺服器上資料的並集是資料的全集;
  • 資料水平拆分到了n個伺服器上,理論上讀效能擴充了n倍,寫效能也擴充了n倍(其實遠不止n倍,因為單機的資料量變為了原來的1/n);

通過主從同步讀寫分離擴充套件資料庫效能:

  • 每個伺服器上儲存的資料量是和總量相同;
  • n個伺服器上的資料都一樣,都是全集;
  • 理論上讀效能擴充了n倍,寫仍然是單點,寫效能不變;

快取層的水平拆分和資料庫層的水平拆分類似,也是以範圍拆分和雜湊拆分的方式居多,就不再展開。

總結

高併發(High Concurrency)是網際網路分散式系統架構設計中必須考慮的因素之一,它通常是指,通過設計保證系統能夠同時並行處理很多請求。

提高系統併發能力的方法主要有兩種:

  • 垂直擴充套件(Scale Up)
  • 水平擴充套件(Scale Out)

前者垂直擴充套件可以通過提升單機硬體效能,或者提升單機架構效能,來提高併發性,但單機效能總是有極限的,網際網路分散式架構設計高併發終極解決方案還是後者:水平擴充套件。

網際網路分層架構中,各層次水平擴充套件的實踐又有所不同:

  • 反向代理層可以通過“DNS輪詢”的方式來進行水平擴充套件;
  • 站點層可以通過nginx來進行水平擴充套件;
  • 服務層可以通過服務連線池來進行水平擴充套件;
  • 資料庫可以按照資料範圍,或者資料雜湊的方式來進行水平擴充套件;

各層實施水平擴充套件後,能夠通過增加伺服器數量的方式來提升系統的效能,做到理論上的效能無限。

思路比結論重要。
如果你對技術提升很感興趣,可以加入Java高階技術來交流學習:856443934,裡面都是同行,有資源分享和技術進階思維導圖,其中:(分散式架構、高可擴充套件、高效能、高並 發、Jvm效能調優、Spring,MyBatis,Nginx原始碼分析,Redis,ActiveMQ、、Mycat、Netty、Kafka、Mysql 、Zookeeper、Tomcat、Docker、Dubbo、Nginx)。歡迎一到五年的工程師加入,合理利用自己每一分每一秒的時間來學習提升自己,不要再用"沒有時間“來掩飾自己思想上的懶惰!趁年輕,使勁拼,給未來的自己一個交代!文末分享架構資料,私信【架