【系統設計】如何設計一個牛X的系統?這三點很重要

 

       今天這篇文章是我看完極客時間《高併發系統設計40問》前幾章後做的一個讀書筆記,將裏面的重點都總結出來了,大家如果認真看完,應該會對系統設計有一個比較清晰的框架了。 

       什麼樣的系統纔是一個牛逼的系統呢?如果一個系統滿足這三點,我們就可以說它是個牛逼的系統了:高性能、高可用、可拓展。那我們如何按照這三點來設計系統呢?下面將一一爲大家介紹。

 

1. 高性能

性能優化原則

1. 問題導向:針對目前存在或未來會出現的問題進行優化。

2. 二八原則:20%精力解決80%性能問題。

3. 需要數據支持:優化的效果是需要數據證明,提升了多少響應速度、吞吐量等。

4. 優化過程是持續的:換句話說,只要系統不斷迭代,優化就要不斷進行。

 

性能度量指標

一般度量性能的指標是接口響應時間。單次響應時間是沒有意義的,我們一般需要度量一段時間的響應情況,所以會用到如下特徵值:

1. 平均值:時間段內所有請求時間除以時間(敏感度差)。

2. 最大值:取最長響應時間(太敏感)。

3. 分位值:把響應時間從小到大分成一百個等級。

脫離併發來談性能是沒意義的,通常用“吞吐量”和“響應時間”來度量併發和流量:

1. 響應時間:一般響應時間。

2. 吞吐量:當響應時間1s,吞吐量是每秒1次;響應10ms,吞吐量每秒100次。

所以我們設立性能優化目標一般會如下表示:在每秒1萬次的請求量下,響應時間99分位值在10ms以下。

 

高併發下的性能優化思路:

提高系統的處理核心數:

假設系統的處理核心數由一個增加爲兩個,並且進程也由一個增加到兩個,讓這兩個進程跑在不同的核心上,理論上系統吞吐量增加一倍。

多核心的吞吐量的計算公式與單核心不同:吞吐量 = 併發進程數 / 響應時間。

是不是併發進程數越多,吞吐量越大?NO,併發進程增加,並行的任務對系統資源的爭搶越嚴重,超過某個臨界點,性能反而下降,這就是性能測試中的拐點模型。

減小單次任務響應時間:

1. CPU密集型:優化程序計算的算法。

2. IO密集型:磁盤IO與網絡IO,通過硬件與軟件層面來解決。

 

2. 高可用

可用性的度量指標:

1. MTBF:Mean Time Between Failure 平均故障間隔時間

2. MTTR:Mean Time To Repair 故障的平均恢復時間

Availability = MTBF / ( MTBF + MTTR )

 

高可用系統設計思路:

主要分爲系統設計和系統運維兩方面:

1. 系統設計方面

(1)故障轉移(failover)

發生failover的節點有兩種情況:

  • 在完全對等的節點之間:所有節點都承擔讀寫流量,並且節點中不保存狀態,每個節點都可以作爲另一個節點的鏡像,所以某個節點失敗,簡單隨機訪問另一個節點就可以了。

  • 在不對等節點之間,即主備節點:比如我們有一個主節點,多個備用節點(熱備:同樣在線提供服務;冷備:只用於備份),我們需要在代碼中控制如何檢測主備機器是否故障以及如何做主備切換。

故障檢測機制與主備切換:

  • 故障檢測機制:心跳,可以在客戶端定期向主節點發送心跳包,也可以從備份節點上定期發送。當一段時間未收到心跳包,就可以認爲主節點發生故障,可以觸發選主操作。

  • 選主:選主結果需要在多個備份節點上達成一致,一般會使用某一種分佈式一致性算法,比如Paxos,Raft。

(2)超時控制

高併發系統通常會由許多系統模塊組成,他們之間調用最怕的是延遲而非失敗,因爲失敗是瞬間的,可以通過重試解決,而延遲會導致調用方阻塞在這次調用上,使它佔用的資源得不到釋放。當存在大量這種阻塞請求時,調用方就會因爲用盡資源而掛掉。所以我們要做超時控制。

超時的時間設置爲多少呢?時間短了造成大量超時錯誤,時間長了起不了作用影響性能。一般通過收集系統之間的調用日誌,統計比如說99%的響應時間是怎樣的,再依據這個響應時間來指定超時時間。

(3)降級

保證核心任務穩定而犧牲非核心任務的運行。

比如我們發微博通常會進行反垃圾檢測,檢測通過了再進行入庫。而反垃圾檢測比較重的操作,在日常流量下雖然耗時但還能正常響應。但當併發較高的情況下,則可能成爲瓶頸,而且它不是發佈微博的主體流程,所謂當併發高時,我們可以關閉反垃圾服務檢測,保證主流流程更加穩定。

(4)限流

通過對併發的請求進行限速來保護系統。

比如web應用,我限制單機只能處理每秒 1000次請求,超過的部分直接返回錯誤給客戶端。

2. 系統運維方面

(1)灰度發佈

一般系統啥時候容易出事?除了超出預期的流量外,就是上線變更階段了。比如你目前上線了一個新需求,數據庫慢查增加了一倍,導致系統請求被拖慢從而產生故障。這時,我們就可以用到灰度發佈了。我們可以先將服務部署在一臺機器上觀察一段時間,如果沒啥問題,再發布到所有機器上。 

(2)故障演練

爲了瞭解發生故障時的系統表現,我們可以人爲的製造故障來進行觀察,當然這樣還是有風險的,所以很多有錢的公司都會搭一套和線上部署環境一樣的線下系統來進行故障演練,從而避免對線上系統造成影響。

 

3. 可拓展

可擴展性可講的太多了,後面我會找個時間單獨講講,今天先大致講下思路,其實很簡單:拆分。即將一個龐大複雜的系統拆分成一個一個的單獨模塊,而拆分的維度是根據實際情況來的,比如功能、數據、設備等等。

 

寫個文章真的是耗時間啊,本來晚上還想看看視頻休息下的,沒想到寫完就到了可以直接睡覺的點了,大家晚安。        

 

 

歡迎大家關注公衆號:程序員進階之路,裏面記錄了一個非科班程序員的成長之路

                                                   

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