System design summary

KeBoom發表於2024-03-20

system design

https://github.com/donnemartin/system-design-primer

Performance vs scalability

scalability 這裡面的伸縮性是指指標的。當系統有較高的負載時,每個使用者仍然能夠有較好的響應時,我們說他系統伸縮性強。

Performance 就是指一個請求的響應越快,自然說效能越高

如何才能讓系統有更好的可伸縮性?

需要在系統設計初就提前考慮好系統設計,提前知道可能的問題點,效能點等等。

那麼具體的系統設計如下:

Latency vs throughput

延時:單個請求的延時

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

Availability vs consistency

CAP理論:對於分散式系統,發生網路分割槽是一定要考慮的,因此在發生網路分割槽的情況下,對於C和A只能二選一。

當發生網路分割槽時,如果你允許使用者操作,那麼就會造成網路分割槽之間的資料不一致。

當發生網路分割槽時,如果你不允許使用者操作,那麼不同分割槽之間的資料不會因此而不一致,但這就不能保證可用性。

Consistency patterns

Weak consistency 通話影片,丟一些也沒關係,最大限度保證通暢

Eventual consistency 可以忍受延時,保證最終一致性

Strong consistency 強一致性,比如Mysql 事務,事務執行後,第一次查詢就要是最新的資料

Availability patterns

Fail-over : Active-passive 主從結構,當主節點掛掉後,從節點自動升級為主節點向外提供服務,比如redis哨兵,mysql主從。 Active-active 主主結構,叢集中各個節點都向外提供服務,當某個節點掛機後,負載均衡器不將流量負載到當機節點即可。比如一些分散式資料庫,kafka叢集等。

Availability in numbers

可靠性的一些指標,比如要達到幾個9

99.9% availability - three 9s

Duration Acceptable downtime
Downtime per year 8h 45min 57s
Downtime per month 43m 49.7s
Downtime per week 10m 4.8s
Downtime per day 1m 26.4s

99.99% availability - four 9s

Duration Acceptable downtime
Downtime per year 52min 35.7s
Downtime per month 4m 23s
Downtime per week 1m 5s
Downtime per day 8.6s

一些常見的系統元件

DNS,用DNS做負載均衡的

CDN,某些雲伺服器廠商的CDN原理。我有一個域名keboom.site。然後我可以訪問此域名拿到一些檔案。在雲廠商處配置keboom.site,他會返回給你一個類似 alicloud.keboom.site的域名,前端程式碼在請求資源時,使用 alicloud.keboom.site來獲取資源。雲廠商會將keboom.site 的資源快取到他們的伺服器上。前端程式將訪問雲廠商快取的資源,這大概就是CDN原理。

負載均衡,平時我們說的有nginx,這其實是在application 層。對於負載均衡在網路協議中,layer 4 也是可以做的,我記得是有些硬體裝置支援這種層次的協議。

資料庫

關係式資料庫,特點是他支援事務,關係型表結構。

一些討論點: 主從:分主從的話,比如讀寫分離,那麼就要有手段做讀寫分離 主主:資料衝突,事務性的破壞,需要控制訪問哪個主

對於資料庫主主,主從,共同的缺點:資料延時問題(主同步不及時,此時主掛機,則資料丟失),資料同步問題(同步資料,消耗效能) 聯邦:國外是這麼叫的,對於國內來說,他可能說叫根據業務進行資料切分。缺點:如果多資料庫join就很麻煩。多資料庫事務。

切片:資料做分割槽,切片。mysql是有partition功能的,可對資料做分割槽(但這只是mysql內部做的最佳化,如果資料量足夠大,僅僅分割槽還是不夠,可能還是要將資料分到多個資料庫多個伺服器,然後做hash)。當然有也人為的對錶做切分,比如對錶加字尾然後做hash,這樣人為做切分。缺點很明顯就是資料切分後,我們的查詢邏輯變得複雜。

反規範:可以消除一些join,但帶來一些冗餘。

SQL最佳化:建表時:比如欄位的選擇,儘可能讓表結構更小。SQL查詢時,注意建立索引,並且能夠使用到索引。慢查詢排查等。


NoSQL

雖然一些NoSQL資料庫聲稱自己支援事務,但是網路上並不太認同。

一般來說他們 可用性 > 一致性

key value:典型的redis等,作為分散式快取使用。

doc:如MongoDB,文件型,資料結構更加靈活些,json型別的文件不必要每個欄位都必須一致。如果你的資料結構層級較深,結構沒有那麼規整,那麼可以考慮使用文件型

列式儲存:大資料相關,HBase clickhouse等,特點是資料壓縮效率高,支援大量的寫入,大資料情形下表現好。比如日誌儲存,或者一些資料歸檔等,作為資料倉儲等使用。

圖形:社交關係

Cache

從頭到尾,客戶端快取,CDN快取,web sever快取,application 快取,分散式快取,資料庫快取

cache pattern: 經典的redis 和 資料庫的更新

查詢時: cache aside:查詢cache,如果cache沒有,則從資料庫中查詢出來放到快取中,然後返回。

缺點: 1.時間變長(查詢快取、更新資料庫、更新快取)2. 當資料庫資料更新時,快取中資料需要做過期或修改或刪除等操作。3. 當快取伺服器重啟,則所有快取需要重新載入

更新時:

  1. 先更新資料庫再跟新redis
  2. 先更新redis在更新資料庫

以上兩種方式都是有一定時間的資料不一致。

非同步

訊息佇列—背壓:生產者生產訊息放到訊息佇列伺服器的記憶體中,消費者進行消費時,直接從記憶體中讀取。這樣是效率最高的。如果佇列中資料過多導致伺服器記憶體不足,則訊息勢必儲存到磁碟中。這時消費者再來進行消費,則需要先從磁碟中隨機讀,將資料載入到記憶體中,才能進行消費,這樣速度就會慢。那麼透過背壓的方式,當記憶體滿時,則同時生產者減慢或者暫停生產。

相關文章