摘要:分佈式系統無疑是持久的熱門話題,但其實若是不是必定有必要,強烈建議不要進入分佈式領域,在集中式的狀況下不少問題都會簡單很多,技術人員千萬不要由於外界火熱的例如微服務,就把本身的產品的也去作改造,必定要仔細判斷是否有必要,不要爲了技術而技術,那麼在必須分佈式的狀況下(訪問量、存儲量或開發人數),一個分佈式領域的合格的架構師要掌握哪些技術呢,這篇文章就聊聊這個話題。算法
分佈式系統無疑是持久的熱門話題,但其實若是不是必定有必要,強烈建議不要進入分佈式領域,在集中式的狀況下不少問題都會簡單很多,技術人員千萬不要由於外界火熱的例如微服務,就把本身的產品的也去作改造,必定要仔細判斷是否有必要,不要爲了技術而技術,那麼在必須分佈式的狀況下(訪問量、存儲量或開發人數),一個分佈式領域的合格的架構師要掌握哪些技術呢,這篇文章就聊聊這個話題。網絡
簡單重複下我對架構師的標準,一個架構師最重要的不是畫幾個框,連幾條線(這是基本要求),而是控制技術風險,要控制技術風險顯然不是看幾個結構性的ppt就能學會的。架構
既然是分佈式系統,系統間通訊的技術就不可避免的要掌握。併發
首先要掌握一些基礎知識,例如網絡通訊協議(諸如TCP/UDP等等)、網絡IO(Blocking-IO,NonBlocking-IO、Asyn-IO)、網卡(多隊列等);更偏應用的層面,須要瞭解例如鏈接複用、序列化/反序列化、RPC、負載均衡等。負載均衡
學了這些基本知識後,基本上能夠寫一個簡單的分佈式系統裏的通訊模塊,但這其實遠遠不夠,既然進入了分佈式領域,對規模其實就已經有了不低的要求,一般也就意味着須要的是能支持大量鏈接、高併發、低資源消耗的通訊程序。分佈式
大量的鏈接一般會有兩種方式:微服務
在現現在NonBlocking-IO這麼成熟的狀況下,一個支持大量client的server已經不那麼難寫了,但在大規模,而且一般長鏈接的狀況下,有一個點要特別注意,就是當server掛掉的時候,不能出現全部client都在一個時間點發起重連,那樣基本就是災難,在沒有經驗的狀況下我看過好幾起相似的case,到client規模上去後,server一重啓基本就直接被衝進來的大量建連沖垮了(固然,server的backlog隊列首先應該稍微設置大一些),一般能夠採用的方法是client重連前都作隨機時間的sleep,另外就是重連的間隔採起避讓算法。高併發
有些場景也會出現須要連大量server的現象,在這種狀況下,一樣要注意的也是不要併發同時去建全部的鏈接,而是在能力範圍內分批去建。工具
除了建鏈接外,另外還要注意的地方是併發發送請求也一樣,必定要作好限流,不然很容易會由於一些點慢致使內存爆掉。網站
這些問題在技術風險上得考慮進去,並在設計和代碼實現上體現,不然一旦隨着規模上去了,問題一時半會還真不太好解。
高併發這個點須要掌握CAS、常見的lock-free算法、讀寫鎖、線程相關知識(例如線程交互、線程池)等,通訊層面的高併發在NonBlocking-IO的狀況下,最重要的是要注意在總體設計和代碼實現上儘可能減小對io線程池的時間佔用。
低資源消耗這點的話NonBlocking-IO自己基本已經作到。
分佈式系統基本就意味着規模不小了,對於這類系統在設計的時候必須考慮伸縮性問題,架構圖上畫的任何一個點,若是請求量或者是數據量不斷增大,怎麼作到能夠經過加機器的方式來解決,固然,這個過程也不用考慮無限大的場景,若是經歷過從比較小到很是大規模的架構師,顯然優點是不小的,一樣也會是愈來愈稀缺的。
伸縮性的問題圍繞着如下兩種場景在解決:
對於無狀態場景,要實現隨量增加而加機器支撐會比較簡單,這種狀況下只用解決節點發現的問題,一般只要基於負載均衡就能夠搞定,硬件或軟件方式都有;
無狀態場景一般會把不少狀態放在db,當量到必定階段後會須要引入服務化,去緩解對db鏈接數太多的狀況。
所謂狀態其實就是數據,一般採用Sharding來實現伸縮性,Sharding有多種的實現方式,常見的有這麼一些:
2.1 規則Sharding
基於必定規則把狀態數據進行Sharding,例如分庫分表不少時候採用的就是這樣的,這種方式支持了伸縮性,但一般也帶來了很複雜的管理、狀態數據搬遷,甚至業務功能很難實現的問題,例如全局join,跨表事務等。
2.2 一致性Hash
一致性Hash方案會使得加機器代價更低一些,另外就是壓力能夠更爲均衡,例如分佈式cache常常採用,和規則Sharding帶來的問題基本同樣。
2.3 Auto Sharding
Auto Sharding的好處是基本上不用管數據搬遷,並且隨着量上漲加機器就OK,但一般Auto Sharding的狀況下對如何使用會有比較高的要求,而這個一般也就會形成一些限制,這種方案例如HBase。
2.4 Copy
Copy這種常見於讀遠多於寫的狀況,實現起來又會有最終一致的方案和全局一致的方案,最終一致的多數可經過消息機制等,全局一致的例如zookeeper/etcd之類的,既要全局一致又要作到很高的寫支撐能力就很難實現了。
即便發展到今天,Sharding方式下的伸縮性問題仍然是很大的挑戰,很是很差作。
上面所寫的基本都還只是解決的方向,到細節點基本就很容易判斷是一個解決過多大規模場景問題的架構師,:)
做爲分佈式系統,必需要考慮清楚整個系統中任何一個點掛掉應該怎麼處理(到了必定機器規模,天天掛掉一些機器很正常),一樣主要仍是分紅了無狀態和有狀態:
對於無狀態場景,一般好辦,只用節點發現的機制上具有心跳等檢測機制就OK,經驗上來講無非就是純粹靠4層的檢測對業務不太夠,一般得作成7層的,固然,作成7層的就得處理好規模大了後的問題。
對於有狀態場景,就比較麻煩了,對數據一致性要求不高的還OK,主備類型的方案基本也能夠用,固然,主備方案要作的很好也很是不容易,有各類各樣的方案,對於主備方案又以爲不太爽的狀況下,例如HBase這樣的,就意味着掛掉一臺,另一臺接管的話是須要必定時間的,這個對可用性仍是有必定影響的;
全局一致類型的場景中,若是一臺掛了,就一般意味着得有選舉機制來決定其餘機器哪臺成爲主,常見的例如基於paxos的實現。
維護性是很容易被遺漏的部分,但對分佈式系統來講實際上是很重要的部分,例如整個系統環境應該怎麼搭建,部署,配套的維護工具、監控點、報警點、問題定位、問題處理策略等等。
從上面要掌握的這些技術,就能夠知道爲何要找到一個合格的分佈式領域的架構師那麼的難,況且上面這些提到的還只是通用的分佈式領域的技術點,但一般其實須要的都是特定分佈式領域的架構師,例如分佈式文件系統、分佈式cache等,特定領域的架構師須要在具有上面的這些技術點的基礎上還具有特定領域的知識技能,這就更不容易了。
隨着互聯網的發展,分佈式領域的不少技術都在成熟化,想一想在8年或9年前,一個大規模的網站的伸縮性是怎麼設計的仍是很熱門的探討話題,可是到了今天基本的結構你們其實都清楚,而且還有不少不錯的系統開源出來,使得不少須要經驗的東西也被沉澱下去了,在有了各類不錯的開源產品的支撐下之後要作一個分佈式系統的難度必定會愈來愈大幅下降,雲更是會加速這個過程。
ps: 在寫這篇文章的過程當中,發現要判斷一個技術人的功底有多厚,其實還真不難,就是請TA寫或者講本身以爲懂的全部技術,看看能寫多厚或講多久…要寫厚或講好久其實都不容易,儘管我也不否定要很簡潔的寫明白或講清楚也不容易,但必定是先厚而後薄。
做者:阿里畢玄