1. 程式人生 > >高併發理解及一些概念

高併發理解及一些概念

一、什麼是高併發

高併發(High Concurrency)是網際網路分散式系統架構設計中必須考慮的因素之一,它通常是指,通過設計保證系統能夠同時並行處理很多請求。高併發相關常用的一些指標有響應時間(Response Time),吞吐量(Throughput),每秒查詢率QPS(Query Per Second),併發使用者數等。

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

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

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

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

二、什麼是秒殺

秒殺場景一般會在電商網站舉行一些活動或者節假日在12306網站上搶票時遇到。對於電商網站中一些稀缺或者特價商品,電商網站一般會在約定時間點對其進行限量銷售,因為這些商品的特殊性,會吸引大量使用者前來搶購,並且會在約定的時間點同時在秒殺頁面進行搶購。

此種場景就是非常有特點的高併發場景,如果不對流量進行合理管控,肆意放任大流量衝擊系統,那麼將導致一系列的問題出現,比如一些可用的連線資源被耗盡、分散式快取的容量被撐爆、資料庫吞吐量降低,最終必然會導致系統產生雪崩效應。

一般來說,大型網際網路站通常採用的做法是通過擴容、動靜分離、快取、服務降級及限流五種常規手段來保護系統的穩定執行。

三、擴容

由於單臺伺服器的處理能力有限,因此當一臺伺服器的處理能力接近或已超出其容量上限時,採用叢集技術對伺服器進行擴容,可以很好地提升系統整體的並行處理能力,在叢集環境中,節點的數量越多,系統的並行能力和容錯性就越強。           

在無狀態服務下,擴容可能是迄今為止效果最明顯的增加併發量的技巧之一。

從擴容方式角度講,分為垂直擴容(scale up)和水平擴容(scale out)。垂直擴容就是增加單機處理能力,懟硬體,但硬體能力畢竟還是有限;水平擴容說白了就是增加機器數量,懟機器,但隨著機器數量的增加,單應用併發能力並不一定與其呈現線性關係, 此時就可能需要進行應用服務化拆分了。

從資料角度講,擴容可以分為無狀態擴容和有狀態擴容。無狀態擴容一般就是指我們的應用伺服器擴容;有狀態擴容一般是指資料儲存擴容,要麼將一份資料拆分成不同的多份,即sharding,要麼就整體複製n份,即副本。sharding遇到的問題就是分片的可靠性,一般做轉移、rehash、分片副本;副本遇到的問題是一致性性,一般做一致性演算法,如paxos,raft等。

四、動靜分離

動靜分離,靜態資源請求與動態請求分離,專案中需要訪問的圖片、聲音、js/css等靜態資源需要有獨立的存放位置,便於將來實現靜態請求分離時直接剝離出來,比如nginx可以直接配置圖片檔案直接訪問目錄,而不需要經過tomcat。這樣tomcat就可以專注處理動態請求,操作資料庫資料處理之類的。靜態請求代理伺服器效能比tomcat高很多。

動靜分離是指,靜態頁面與動態頁面分開不同系統訪問的架構設計方法。

高併發解決方案

一般來說:

  • 靜態頁面訪問路徑短,訪問速度快,幾毫秒
  • 動態頁面訪問路徑長,訪問速度相對較慢(資料庫的訪問,網路傳輸,業務邏輯計算),幾十毫秒甚至幾百毫秒,對架構擴充套件性的要求更高
  • 靜態頁面與動態頁面以不同域名區分

系統需要將動態資料 和靜態資料分而治之,使用者對靜態資料的訪問,應該避免請求直接落到企業的資料中心,而是應該在CDN中獲取,以加速系統的響應速度。

高併發解決方案

五、快取

快取之所以能夠提高處理速度,是因為不同裝置的訪問速度存在差異。快取的話題可以扯幾本書不帶重樣的。從CPU可以一直扯到客戶端快取,即從最底層一直到扯到最特近使用者的一層,每一層都可能或可以有快取的存在。我們這裡不扯這麼多,只說簡單服務端快取。現在從幾個不同角度來看一下快取:

①從效果角度。命中率越高越好嗎?10萬個店鋪資料,快取了1000個,命中率穩定100%,那是不是說,有99000個店鋪都是長尾店鋪?快取效果評估不能單看命中率。

②從回收策略。如果把快取當做資料庫一樣的儲存裝置去用,那就沒有回收的說法了(除非重啟或者宕機,否則資料依然有效);如果只儲存熱資料,那就有回收和替換的問題。回收有兩種方式,一種是空間配額,另一種是時間配額。替換也有幾種方式,LRU,FIFO,LFU。

③從快取使用模式角度:使用者直接操作快取和db;使用者直接操作快取,快取幫助我們讀寫DbB;

④從快取分級角度。java堆內快取、java堆外快取、磁碟快取、分散式快取,多級快取。

⑤從快取使用角度。null穿透問題、驚群問題、快取熱點問題、快取一致性問題、讀寫擴散問題。。。。。。

⑥更新方式。讀更新、寫更新、非同步更新。

如果快取叢集涉及到異地多叢集部署,再結合大資料量高併發業務場景,還會遇到很多更加複雜的問題,這裡就不一一列舉了。

六、服務降級

業務高峰期,為了保證核心服務,需要停掉一些不太重要的業務,eg 商品評論、論壇或者粉絲積分等

另外一些場景就是某些服務不可用時,又不能直接讓整個流程失敗就本地Mcok(模擬)實現,做流程放通

eg 使用者登入餘額鑑權服務不能正常工作,需要做業務放通,記錄消費話單允許使用者繼續訪問,而不是返回失敗

為了保證以上兩種場景的正常服務,服務需要有降級。

服務降級主要包括容錯降級和遮蔽降級

遮蔽降級:

1)throw null 不發起遠端呼叫,直接返回空

2)throw exception 不發起遠端呼叫,直接丟擲指定異常

3)execute bean 不發起遠端呼叫,直接執行本地模擬介面實現

服務降級是可逆操作,當系統壓力恢復到一定值不需要降級服務時,要重新發起遠端呼叫,服務狀態改為正常

容錯降級:

非核心服務不可呼叫時,可以對故障服務做業務放通,保證主流程不受影響

1)RPC異常:通常指超時、訊息解碼異常、流控異常、系統擁塞保護異常等

2)Service異常 eg登入校驗異常、資料庫操作失敗異常等

七、限流

通過對併發訪問和請求進行限速或者一個時間視窗內的請求進行限速來保護系統的可用性,一旦達到限制速率就可以拒絕服務(友好定向到錯誤頁或告知資源沒有了),排隊或者等待(比如秒殺,評論,下單),降級(返回預設資料)。

通過壓測的手段找到每個系統的處理峰值,然後通過設定峰值閾值,來防止當系統過載時,通過拒絕處理過載的請求來保障系統 可用性,同時也應該根據系統的吞吐量,響應時間,可用率來動態調整限流閾值。

分類:

  • 限制總併發數---資料庫連線池,執行緒池
  • 限制瞬時併發數---nginx的limit_conn模組,用來限制瞬時併發連線數
  • 限制時間視窗內的平均速率---guava的RateLimiter,nginx的limit_req模組,限制每秒平均速率
  • 其他---限制遠端介面呼叫速率,限制MQ消費速率,另外,還可以根據網路連線數,網路流量,CPU或記憶體負載等來限流。

演算法:

  • 滑動視窗協議---改善吞吐量的技術
  • 漏桶---強制限制資料的傳輸速率,限制的流出速率
  • 令牌桶---(控制(流入)速率型別的限流演算法)系統以恆定的速度往桶中放入令牌,如果請求需要被處理,則需要先從桶中獲取一個令牌,當桶中沒有令牌可取,則拒絕服務。當平時處理速率小於桶中令牌的速率,那麼在突發流量時桶內有堆積可以有效預防。

令牌桶

高併發解決方案

漏桶

高併發解決方案

八、總結

任何一個分散式系統的容量都會存在上限,哪怕天貓這種級別的網站也不例外。一旦使用者流量過載,系統的吞吐量便會開始下