1. 程式人生 > >Java架構-別忽視分散式系統這六大“暗流”

Java架構-別忽視分散式系統這六大“暗流”

任何事物都有兩面性。你只有瞭解了分散式系統背後的“暗流湧動”現象是什麼,才能避免掉到“坑”裡去。

暗流的含義是流動的地下水,是潛伏在“深層”的,我們往往過度地沉迷於表面的美好,而忽略了它。在分散式系統當中,最容易被我們忽略的是下面這六大“暗流”:

  • 網路並不是可靠的

  • 不同節點之間的通訊是存在延遲的

  • 頻寬是有上限的

  • 分散式並不直接意味著是“敏捷開發”了

  • 資料由一份冗餘成多份後如何保持一致

  • 整個系統的不同部分可能是異構的

為了讓你有更深刻的理解,我們來分別深入認識一下。

網路並不是可靠的

你應該明白,分散式系統中不同節點間的通訊是基於網路的。網路使得它們連線起來共同協作。

然而,光纜被挖斷的事件相信你也看到過不是一兩次了。除此之外,網絡卡異常、交換機故障、遭受惡意攻擊等導致的網路擁塞、網路中斷、報文丟失的種種跡象皆意味著網路隨時可能無法正常運作,是不可靠的。

此時,需要在你的系統設計中,儘可能地考慮到:當前節點所依賴的其他節點由於各種原因無法與之正常通訊時,該如何保證其依然能夠提供部分或者完整的服務。這個概念在軟體領域被定義為“魯棒性”。

不同節點之間的通訊是存在延遲的

網路連線的是處於不同物理位置上的節點,學過物理和數學你的應該明白,兩點之間是存在“距離”的,而我們的分散式系統需要在這個距離之上進行資料的傳遞,本質上就是物質的傳遞。同時應該你也知道,物質的運動速度不會超過光速。所以,不同節點之間的通訊是需要經過一段時間的,也就意味著會存在延遲。具體的延遲是由所用的傳輸介質、節點當前的負載大小所決定的。另外,不容被忽視是為了通訊所做的額外工作也是耗時的,而且還不小,下圖的橙色部分就是為了兩個遠端節點的通訊額外做的事情。

所以我們不能以呼叫本地方法一樣的認知去理解遠端呼叫(RPC)。在目前的技術環境下,CPU 的運算能力長期保持高速增長,因此兩個節點間通訊的大部分場景中,延遲的耗時總是大於目標節點進行邏輯運算的耗時。

由此可得,並不是將一個集中式系統拆分得越散,系統就越快。當中存在的延遲,不容忽視。如果是基於提速為目的的拆分,至少是滿足下面這樣的條件的。

因為如果無法並行處理,反而會更慢,就像下面這樣。

關於這點,我們還需要慎重考慮是否有必要進行“同步”的 RPC 呼叫,以及儘量的降低呼叫次數等。這就是為什麼我們說,迴圈呼叫不如一次批量呼叫,反覆呼叫不如呼叫一次做程序內快取,同步呼叫比如非同步呼叫的道理。

頻寬是有上限的

這個點,我相信你是知道的,因為當你通過 QQ、釘釘之類的工具傳輸或者下載一個大檔案時候,就發現它是存在上限的,這個上限是根據你的網路頻寬大小決定的。但是,為什麼你還是有可能會掉入這個陷阱裡呢?這往往由於你對所傳輸的資料的大小和頻率沒有充分的認識,導致了你覺得達到上限是一個很久遠的事情,不用考慮它。

舉個例子,你的網路都是基於 100M 頻寬標準搭建的。那麼此時如果每一秒會產生 10240 次資料傳輸,平均每個資料包大小是 10KB,我們來看下是否會遇到瓶頸。

  • 100M 頻寬的理論傳輸速率是 12.5MB/ 秒。那麼現在每一秒需要傳輸:10240 次 / 秒 * 10KB = 100MB/ 秒。很明顯,頻寬遠遠不夠了。

關於頻寬上限,你需要明白這幾點。

1.實際環境中的傳輸速率大小,是由服務商所提供的頻寬大小,以及網絡卡、網絡卡、交換機、路由器所支援的傳輸速率中的最小值決定的。

2.內網與外網傳輸速率是不同的,一般都是內網大於外網。因為服務商所提供的頻寬成本更高。

3.同一個區域網內的節點是公用外網出入口的,所以儘可能的縮小在外網傳輸的資料,以降低佔用“獨木橋”外網的空間。

分散式並不直接意味著是“敏捷”了

可能你曾經有過這樣的想法,當在規模較大的集中式系統中工作的時候,每次和許多人在一個程式碼庫裡提交程式碼,老是遇到衝突、排隊等待上游模組先開發等等。這時你會想,如果改造成分散式系統,這些問題都沒了,工作效率高多了。

答案是否定的,在前兩篇文章中也有提到一些。拆分後需要做的額外工作如果沒做好,可能會導致不是更快,而是更慢。最典型的現象如:

  • 釋出更麻煩了。原先雖然開發麻煩,但是釋出簡單啊,哪怕用最原始的方式:編譯一次,登上伺服器,複製黏貼,秒秒鐘搞定。而現在需要釋出 10 個、20 個、幾十個,再這樣操作很明顯要把人逼瘋。

  • 排查問題更難了。原本出了問題,不是在程式就是在資料庫。現在還得判斷在哪個程式,哪個資料庫,是不是要抓狂?

關於這點,你需要秉持著工欲善其事必先利其器的思想。將建設協作相關的輔助性工作與分散式系統同時進行。比如:監控告警系統、配置中心、服務發現,以及批量部署、持續整合,甚至 DevOps 等。

資料由一份冗餘成多份後如何保持一致

這點其實是由於前面提到的網路因素產生的連帶效應。

當遇到資料庫壓力增大,響應開始變慢的時候,你可能會很容易想到,讓 DBA 來做個主從啊。但是,由於網路不可靠、存在延遲、頻寬有上限這一系列因素。所以,這個看似只是 Copy 一下工作,需要我們花大量的精力去解決如何保證在使用不同副本上的資料的時候,都是符合應有的預期的。

關於這點,業界已經研究了幾十年,同時得出了許多具有指導意義的理論和思想。你需要充分的理解這些,並且能夠識別出合適的運用場景,就可以解決這個問題。這個概念在軟體領域被定義為「資料一致性」。

整個系統的不同部分可能是異構的

先來看下「異構」的定義:

  • 形容一個包含或者組成“異構網路”的產品,所謂的“異構網路”通常指不同廠家的產品所組成的網路。

比如,可以是裝有不同作業系統的伺服器、不同的資料庫產品、用不同的語言開發的產品等等。我們所處的整個全球網際網路就是“異構”的。

在系統初期,同類技術下的差異往往不太被關注。但是隨著分散式系統規模的逐漸擴大,在進入到成熟期的過程中,往往不可避免的會使系統成為異構的,有主動的,也有被動的。

  • 被動的。往往需要引入一些新的技術棧或者解決方案來解決當前的問題,因為很多時候不會有資源,也沒有必要去“重複造每一個輪子”。

  • 主動的。由於規模效應的影響越來越大,某些技術更適合在特定場景下發揮,因此能夠降低同等壓力下對資源的消耗,就可以明顯的降低成本。

關於這點,你要思考如何通過專制的方式進行標準化,來遮蔽這些差異帶來的複雜度影響,使得有更多的精力投入到有價值的地方去。專制的特點是“約束”效果,標準化通過專制來進行可以降低許多為了方便而妥協問題。比如每個節點都通過統一的遠端呼叫(RPC)中介軟體來做“連線”,就將如何連線異構節點的問題交由這個中介軟體來全權負責,而不是不同的團隊各自實現一套。

總結

這次我們深入講解了分散式系統當中常見的一些“暗流”,而上面列舉的這些只能說是最常見的一些典型。在後續的文章中你會跟著我一起發現更多類似的“坑”,讓我們一起來尋找避開它們的方式吧。

希望你能時刻保持警惕之心,帶著沒有“完美方案”的心態在分散式系統中前行。

從下一篇文章起,將正式開始講解做好分散式系統需要掌握的一個個核心要點,我會力爭儘可能的深入淺出,讓你能夠深刻理解每個要點的作用,如何用好它,以及最佳實踐等等。

思考題

你在平時的專案開發中有遇到過哪些“坑”嗎?可以在下方評論框給我們留言。

我本人邀約各大BATJ架構大牛共創Java架構師社群群,(群號:673043639)致力於免費提供Java架構行業交流平臺,通過這個平臺讓大家相互學習成長,提高技術,讓自己的水平進階一個檔次,成功通往Java架構技術大牛或架構師發展。

為什麼某些人會一直比你優秀,是因為他本身就很優秀還一直在持續努力變得更優秀,而你是不是還在滿足於現狀內心在竊喜!

合理利用自己每一分每一秒的時間來學習提升自己,不要再用"沒有時間“來掩飾自己思想上的懶惰!趁年輕,使勁拼,給未來的自己一個交代!

希望此文能幫到大家的同時,也聽聽大家的觀點。歡迎留言討論,加關注,分享你的高見!持續更新

  • To-陌霖Java架構

分享網際網路最新文章 關注網際網路最新發展