剛看了阿里技術大牛畢玄《分布式領域架構師要掌握的技術》,里面講到,架構師在設計分布式系統需要重點考慮以下四方面:
1、通信
首先要掌握一些基礎知識,例如網絡通信協議(諸如TCP/UDP等等)、網絡IO(Blocking-IO,NonBlocking-IO、Asyn-IO)、網卡(多隊列等);更偏應用的層面,需要了解例如連接復用、序列化/反序列化、RPC、負載均衡等。
學了這些基本知識后,基本上可以寫一個簡單的分布式系統里的通信模塊,但這其實遠遠不夠,既然進入了分布式領域,對規模其實就已經有了不低的要求,通常也就意味着需要的是能支持大量連接、高並發、低資源消耗的通信程序。
大量的連接通常會有兩種方式:
1. 大量client連一個server
在現如今NonBlocking-IO這么成熟的情況下,一個支持大量client的server已經不那么難寫了,但在大規模,並且通常長連接的情況下,有一個點要特別注意,就是當server掛掉的時候,不能出現所有client都在一個時間點發起重連,那樣基本就是災難,在沒有經驗的情況下我看過好幾起類似的case,到client規模上去后,server一重啟基本就直接被沖進來的大量建連沖垮了(當然,server的backlog隊列首先應該稍微設置大一些),通常可以采用的方法是client重連前都做隨機時間的sleep,另外就是重連的間隔采取避讓算法。
2. 一個client連大量的server
有些場景也會出現需要連大量server的現象,在這種情況下,同樣要注意的也是不要並發同時去建所有的連接,而是在能力范圍內分批去建。
除了建連接外,另外還要注意的地方是並發發送請求也同樣,一定要做好限流,否則很容易會因為一些點慢導致內存爆掉。
這些問題在技術風險上得考慮進去,並在設計和代碼實現上體現,否則一旦隨着規模上去了,問題一時半會還真不太好解。
高並發這個點需要掌握CAS、常見的lock-free算法、讀寫鎖、線程相關知識(例如線程交互、線程池)等,通信層面的高並發在NonBlocking-IO的情況下,最重要的是要注意在整體設計和代碼實現上盡量減少對io線程池的時間占用。
2、伸縮性
伸縮性的問題圍繞着以下兩種場景在解決:
1. 無狀態場景
對於無狀態場景,要實現隨量增長而加機器支撐會比較簡單,這種情況下只用解決節點發現的問題,通常只要基於負載均衡就可以搞定,硬件或軟件方式都有;
無狀態場景通常會把很多狀態放在db,當量到一定階段后會需要引入服務化,去緩解對db連接數太多的情況。
2. 有狀態場景
所謂狀態其實就是數據,通常采用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方式下的伸縮性問題仍然是很大的挑戰,非常不好做。
3、穩定性
作為分布式系統,必須要考慮清楚整個系統中任何一個點掛掉應該怎么處理(到了一定機器規模,每天掛掉一些機器很正常),同樣主要還是分成了無狀態和有狀態:
1. 無狀態場景
對於無狀態場景,通常好辦,只用節點發現的機制上具備心跳等檢測機制就OK,經驗上來說無非就是純粹靠4層的檢測對業務不太夠,通常得做成7層的,當然,做成7層的就得處理好規模大了后的問題。
2. 有狀態場景
對於有狀態場景,就比較麻煩了,對數據一致性要求不高的還OK,主備類型的方案基本也可以用,當然,主備方案要做的很好也非常不容易,有各種各樣的方案,對於主備方案又覺得不太爽的情況下,例如HBase這樣的,就意味着掛掉一台,另外一台接管的話是需要一定時間的,這個對可用性還是有一定影響的;
全局一致類型的場景中,如果一台掛了,就通常意味着得有選舉機制來決定其他機器哪台成為主,常見的例如基於paxos的實現。
4、可維護性
維護性是很容易被遺漏的部分,但對分布式系統來說其實是很重要的部分,例如整個系統環境應該怎么搭建,部署,配套的維護工具、監控點、報警點、問題定位、問題處理策略等等。