引言
最近幾年,大家一直在討論各式各樣的架構,如:高併發架構、異地多活架構、容器化架構、微服務架構、高可用架構、彈性化架構。還有這些架構相關的管理型技術方法,如:DevOps、應用監控、自動化運維、SOA服務治理、去IOE等等。面對這麼多的紛亂複雜的技術,很多團隊都是一個個地去做這些技術,非常辛苦,但結果並不好。
分佈式系統架構的目的
首先,我們需要搞清楚的是爲什麼需要分佈式系統,而不是傳統的單體架構。其實,使用分佈式系統主要有以下幾個原因:
- 增加系統容量:隨着業務量越來越大,而要能夠應對越來越大的業務量時,一臺機器的性能已經無法滿足業務的需求了,我們需要多臺機器才能應對大規模的應用場景。所以,我們需要垂直或水平拆分業務系統,讓其變成一個分佈式的架構。
- 加強系統可用性:由於業務變得越來越關鍵,需要提高整個系統架構的可用性,這就意味着架構中不能存在單點故障。這樣整個系統不會因爲一臺機器出現故障導致整體不可用。所以需要通過分佈式架構來冗餘系統以消除單點故障,從而提高系統的可用性。
以上是整個分佈式系統架構的主要目的,當然,它還具體一些其它方面的優勢,比如:
- 模塊化:分佈式系統架構採用的是一個服務一個模塊,所以系統模塊重用性更高;
- 持續發佈和提高效率:因爲軟件服務模塊初拆分,開發的發佈速度可以並行而變得更快;
- 擴展性高:可支持垂着的水平擴展;
- 團隊協作:由於每一個服務模塊都是服務接口的方式暴露的,團隊協作流程也會得到改善;
- ... ...;
分佈式架構的難點
不過,這個世界上並不存在完美的技術方案;採用任何一種技術方案都是“按下葫蘆浮起瓢”,都是有得有失,都是一種取捨。也就是說,分佈式系統在解決上述問題的同時,也給我們帶來了其它方面的問題。因此,我們需要清楚地知道分佈系統所帶來的問題以及如何有效的規避這些問題。
下面的表格是單體應用架構和分佈式架構的優缺點的對比情況:
維度指標 | 單體架構 | 分佈式架構 |
---|---|---|
新功能開發 | 需要時間 | 容易開發和實現 |
部署頻率 | 不經常容易部署 | 經常發佈,部署複雜 |
隔離性 | 故障影響範圍大 | 故障影響範圍小 |
架構設計 | 難度小 | 難度係數增加 |
系統性能 | 響應時間快,吞吐量小 | 響應時間慢,吞吐量大 |
系統運維 | 運維簡單 | 運維複雜 |
學習成本 | 學習曲線大(應用邏輯) | 學習曲線大(架構邏輯) |
技術複雜度 | 技術單一且封閉 | 技術多樣且開放 |
測試和查錯 | 簡單(日誌文件) | 複雜(逐個節點排查) |
系統擴展性 | 擴展性很差,容易出現性能瓶頸 | 擴展性很好 |
系統管理 | 重點在於開發成本 | 重點在於服務治理和調度 |
從上面對比表格我們可以看到,分佈式系統雖然有一些優勢,但也存在一些問題。
- 架構設計變得複雜
- 部署單個服務會比較快,但是如果一次部署多個服務時,部署會變得複雜。
- 系統吞吐量會變大,但是響應時間會變長。
- 運維複雜度會因爲服務變多而變得複雜。
- 架構複雜導致學習曲線變大。
- 測試和查錯的複雜度增大。
- 技術多樣化,這會帶來維護和運維的和複雜度。
- 管理分佈式系統中的服務和調度變得困難和複雜。
也就是說,分佈式系統架構的難點在於系統設計以及管理和運維。所以,分佈式架構解決了“單點”和“性能容量”的問題,卻新增了一堆的問題。而對於這些新增的問題,還會衍生出更多的子問題,這就需要我們不斷地用各式各樣的技術手段來解決這些問題。
分佈式架構技術棧
我們知道構建系統的目的是增加系統容量和提高系統的可用性,轉換成技術方面,也就是完成以下兩件事:
- 大流量處理:通過集羣技術把大規模併發請求的負載分散到不同的機器上。
- 關鍵業務保護:提高後臺服務的可用性,把故障隔離起來阻止“多米諾骨牌效應(雪崩效應)”,如果流量過大,需要對業務降級,以保護關鍵業務流轉。
說白了就是幹兩件事,一是提高整體架構的吞吐量,服務更多的併發和流量,二是爲了提高系統的穩定性SLA,讓系統的可用性更高。
提高性能的常用技術
- 緩存系統:加入緩存,可以有效的提高系統的訪問能力。從前端的瀏覽器,到網絡,再到後端的服務,底層數據庫,文件系統,硬盤和CPU,全部都有緩存,這是提高快速訪問能力的最有效的手段。對於分佈式系統下的緩存系統,需要一個緩存集羣。這其中需要一個代理(Proxy)來做緩存的分片和路由。
- 負載均衡:它是做水平擴展的關鍵技術,其可以用多臺機器來共同分擔一部分的流量請求。常見的負載均衡器可以分爲:硬負載(F5)和軟負載(Nginx)。
- 異步調用:異步系統主要通過消息隊列對請求做排除處理,這樣可以把前端的請求峯值給”削平“了,而後端通過自已能夠處理的速度來處理請求。這樣可以增加系統的吞吐量,但是實時性就差很多了。同時,還會引入消息丟失的問題,所以要對消息隊列做持久化處理,這會造成”有狀態“的結點,從而增加了服務調度的難度。
- 數據分區: 數據分區就是把數據按一定的方式分成多個區(比如通過地理位置),不同的數據區分來分擔不同區的流量,這需要一個數據路由中間件,會導致跨庫的Jion和跨庫的事務非常複雜。
- 數據鏡像:數據鏡像就是把一個數據庫鏡像成多份一樣的數據,這樣就不需要數據路由的中間件了。你可以在任意的結點上進行讀寫操作,內部會自行的同步數據。然而,數據鏡像中最大的問題就是數據一致性的問題。
提高穩定性的常用技術
- 服務拆分:服務拆分的目的主要有兩個:一是爲了隔離故障,二是爲了重用服務模塊。但服務拆分後,會引入服務調用間的依賴問題。
- 服務冗餘:是爲了去除單點故障,並可以支持服務的彈性伸縮及故障遷移。然而,對於一些有狀態的服務來說這就導致了數據不一致的問題
- 限流降級:當系統實在扛不住壓力時,只能通過限流或者功能降級的方式來停掉一部分服務或拒絕一部分用戶,以確保系統不會掛掉,所以限流降級是一種保護措施。
- 高可用架構:通常來說是從冗餘架構的角度來保障可用性。常用的做法有:多租戶隔離,災備多活,數據分區(數據複製保持一致性的集羣)。總之,其根本的目的就是不出單點故障。
- 高可用運維:指的是DevOps中的CI(持續集成)與CD(持續部署)兩方面。一個良好的運維應該是一條很流暢的軟件發佈管線,其中做了足夠多的自動化測試,還可以做相應的灰度發佈,以及對線上系統的自動化控制。這樣做的目的可以保證‘計劃內“和”非計劃內“的宕機事件的時長最短。
小結
總體來說,分佈式系統需要乾的就是兩件事:一是提高整體架構的吞吐量,服務更多的併發和流量;二是爲了是提高系統的穩定性,讓系統的可用性更高。
爲了達到上述兩個主要的目的,列舉了並梳理出了其中的技術難點及可能會帶來的問題。