分布式系統(tǒng)技術(shù)
通信
既然是分布式系統(tǒng)考抄,系統(tǒng)間通信的技術(shù)就不可避免的要掌握细疚。
首先要掌握一些基礎(chǔ)知識(shí),例如網(wǎng)絡(luò)通信協(xié)議(諸如TCP/UDP等等)座泳、網(wǎng)絡(luò)IO(Blocking-IO惠昔,NonBlocking-IO、Asyn-IO)挑势、網(wǎng)卡(多隊(duì)列等)镇防;更偏應(yīng)用的層面,需要了解例如連接復(fù)用潮饱、序列化/反序列化来氧、RPC、負(fù)載均衡等香拉。
學(xué)了這些基本知識(shí)后啦扬,基本上可以寫一個(gè)簡(jiǎn)單的分布式系統(tǒng)里的通信模塊,但這其實(shí)遠(yuǎn)遠(yuǎn)不夠凫碌,既然進(jìn)入了分布式領(lǐng)域扑毡,對(duì)規(guī)模其實(shí)就已經(jīng)有了不低的要求,通常也就意味著需要的是能支持大量連接盛险、高并發(fā)瞄摊、低資源消耗的通信程序。
大量的連接通常會(huì)有兩種方式:
大量client連一個(gè)server
在現(xiàn)如今NonBlocking-IO這么成熟的情況下苦掘,一個(gè)支持大量client的server已經(jīng)不那么難寫了换帜,但在大規(guī)模,并且通常長(zhǎng)連接的情況下鹤啡,有一個(gè)點(diǎn)要特別注意惯驼,就是當(dāng)server掛掉的時(shí)候,不能出現(xiàn)所有client都在一個(gè)時(shí)間點(diǎn)發(fā)起重連递瑰,那樣基本就是災(zāi)難祟牲,在沒有經(jīng)驗(yàn)的情況下我看過(guò)好幾起類似的case,到client規(guī)模上去后泣矛,server一重啟基本就直接被沖進(jìn)來(lái)的大量建連沖垮了(當(dāng)然疲眷,server的backlog隊(duì)列首先應(yīng)該稍微設(shè)置大一些),通衬啵可以采用的方法是client重連前都做隨機(jī)時(shí)間的sleep,另外就是重連的間隔采取避讓算法。
一個(gè)client連大量的server
有些場(chǎng)景也會(huì)出現(xiàn)需要連大量server的現(xiàn)象哗总,在這種情況下几颜,同樣要注意的也是不要并發(fā)同時(shí)去建所有的連接,而是在能力范圍內(nèi)分批去建讯屈。
除了建連接外蛋哭,另外還要注意的地方是并發(fā)發(fā)送請(qǐng)求也同樣,一定要做好限流涮母,否則很容易會(huì)因?yàn)橐恍c(diǎn)慢導(dǎo)致內(nèi)存爆掉谆趾。
這些問(wèn)題在技術(shù)風(fēng)險(xiǎn)上得考慮進(jìn)去,并在設(shè)計(jì)和代碼實(shí)現(xiàn)上體現(xiàn)叛本,否則一旦隨著規(guī)模上去了沪蓬,問(wèn)題一時(shí)半會(huì)還真不太好解。
高并發(fā)這個(gè)點(diǎn)需要掌握CAS来候、常見的lock-free算法跷叉、讀寫鎖、線程相關(guān)知識(shí)(例如線程交互营搅、線程池)等云挟,通信層面的高并發(fā)在NonBlocking-IO的情況下,最重要的是要注意在整體設(shè)計(jì)和代碼實(shí)現(xiàn)上盡量減少對(duì)io線程池的時(shí)間占用转质。
低資源消耗這點(diǎn)的話NonBlocking-IO本身基本已經(jīng)做到园欣。
伸縮性
分布式系統(tǒng)基本就意味著規(guī)模不小了,對(duì)于這類系統(tǒng)在設(shè)計(jì)的時(shí)候必須考慮伸縮性問(wèn)題休蟹,架構(gòu)圖上畫的任何一個(gè)點(diǎn)沸枯,如果請(qǐng)求量或者是數(shù)據(jù)量不斷增大,怎么做到可以通過(guò)加機(jī)器的方式來(lái)解決鸡挠,當(dāng)然辉饱,這個(gè)過(guò)程也不用考慮無(wú)限大的場(chǎng)景,如果經(jīng)歷過(guò)從比較小到非常大規(guī)模的架構(gòu)師拣展,顯然優(yōu)勢(shì)是不小的彭沼,同樣也會(huì)是越來(lái)越稀缺的。
橫向可擴(kuò)展性(Scale Out)是指通過(guò)增加服務(wù)器數(shù)量來(lái)提升集群整體性能备埃⌒栈螅縱向可擴(kuò)展性(Scale Up)是指提升每臺(tái)服務(wù)器性能進(jìn)而提升集群整體性能“唇牛縱向可擴(kuò)展性的上限非常明顯于毙,分布式系統(tǒng)強(qiáng)調(diào)橫向可擴(kuò)展性。
分布式系統(tǒng)應(yīng)用服務(wù)最好做成無(wú)狀態(tài)的
應(yīng)用服務(wù)的狀態(tài)是指運(yùn)行時(shí)程序因?yàn)樘幚矸?wù)請(qǐng)求而存在內(nèi)存的數(shù)據(jù)辅搬。分布式應(yīng)用服務(wù)最好是設(shè)計(jì)成無(wú)狀態(tài)唯沮。因?yàn)槿绻麘?yīng)用程序是有狀態(tài)的脖旱,那么一旦服務(wù)器宕機(jī)就會(huì)使得應(yīng)用服務(wù)程序受影響而掛掉,那存在內(nèi)存的數(shù)據(jù)也就丟失了介蛉,這顯然不是高可靠的服務(wù)萌庆。把應(yīng)用服務(wù)設(shè)計(jì)成無(wú)狀態(tài)的,讓程序把需要保存的數(shù)據(jù)都保存在專門的存儲(chǔ)上(eg. 數(shù)據(jù)庫(kù))币旧,這樣應(yīng)用服務(wù)程序可以任意重啟而不丟失數(shù)據(jù)践险,方便分布式系統(tǒng)在服務(wù)器宕機(jī)后恢復(fù)應(yīng)用服務(wù)。
伸縮性的問(wèn)題圍繞著以下兩種場(chǎng)景在解決:
無(wú)狀態(tài)場(chǎng)景
對(duì)于無(wú)狀態(tài)場(chǎng)景吹菱,要實(shí)現(xiàn)隨量增長(zhǎng)而加機(jī)器支撐會(huì)比較簡(jiǎn)單巍虫,這種情況下只用解決節(jié)點(diǎn)發(fā)現(xiàn)的問(wèn)題,通常只要基于負(fù)載均衡就可以搞定鳍刷,硬件或軟件方式都有占遥;
無(wú)狀態(tài)場(chǎng)景通常會(huì)把很多狀態(tài)放在db,當(dāng)量到一定階段后會(huì)需要引入服務(wù)化倾剿,去緩解對(duì)db連接數(shù)太多的情況筷频。
有狀態(tài)場(chǎng)景
所謂狀態(tài)其實(shí)就是數(shù)據(jù),通常采用Sharding來(lái)實(shí)現(xiàn)伸縮性前痘,Sharding有多種的實(shí)現(xiàn)方式凛捏,常見的有這么一些:
2.1 規(guī)則Sharding
基于一定規(guī)則把狀態(tài)數(shù)據(jù)進(jìn)行Sharding,例如分庫(kù)分表很多時(shí)候采用的就是這樣的芹缔,這種方式支持了伸縮性坯癣,但通常也帶來(lái)了很復(fù)雜的管理、狀態(tài)數(shù)據(jù)搬遷最欠,甚至業(yè)務(wù)功能很難實(shí)現(xiàn)的問(wèn)題示罗,例如全局join,跨表事務(wù)等芝硬。
2.2 一致性Hash
一致性Hash方案會(huì)使得加機(jī)器代價(jià)更低一些蚜点,另外就是壓力可以更為均衡,例如分布式cache經(jīng)常采用拌阴,和規(guī)則Sharding帶來(lái)的問(wèn)題基本一樣绍绘。
2.3 Auto Sharding
Auto Sharding的好處是基本上不用管數(shù)據(jù)搬遷,而且隨著量上漲加機(jī)器就OK迟赃,但通常Auto
Sharding的情況下對(duì)如何使用會(huì)有比較高的要求陪拘,而這個(gè)通常也就會(huì)造成一些限制,這種方案例如HBase纤壁。
2.4 Copy
Copy這種常見于讀遠(yuǎn)多于寫的情況左刽,實(shí)現(xiàn)起來(lái)又會(huì)有最終一致的方案和全局一致的方案,最終一致的多數(shù)可通過(guò)消息機(jī)制等酌媒,全局一致的例如zookeeper/etcd之類的欠痴,既要全局一致又要做到很高的寫支撐能力就很難實(shí)現(xiàn)了迄靠。
即使發(fā)展到今天,Sharding方式下的伸縮性問(wèn)題仍然是很大的挑戰(zhàn)斋否,非常不好做梨水。
上面所寫的基本都還只是解決的方向拭荤,到細(xì)節(jié)點(diǎn)基本就很容易判斷是一個(gè)解決過(guò)多大規(guī)模場(chǎng)景問(wèn)題的架構(gòu)師茵臭,
穩(wěn)定性
作為分布式系統(tǒng),必須要考慮清楚整個(gè)系統(tǒng)中任何一個(gè)點(diǎn)掛掉應(yīng)該怎么處理(到了一定機(jī)器規(guī)模舅世,每天掛掉一些機(jī)器很正常)旦委,同樣主要還是分成了無(wú)狀態(tài)和有狀態(tài):
無(wú)狀態(tài)場(chǎng)景
對(duì)于無(wú)狀態(tài)場(chǎng)景,通常好辦雏亚,只用節(jié)點(diǎn)發(fā)現(xiàn)的機(jī)制上具備心跳等檢測(cè)機(jī)制就OK缨硝,經(jīng)驗(yàn)上來(lái)說(shuō)無(wú)非就是純粹靠4層的檢測(cè)對(duì)業(yè)務(wù)不太夠,通常得做成7層的罢低,當(dāng)然查辩,做成7層的就得處理好規(guī)模大了后的問(wèn)題。
有狀態(tài)場(chǎng)景
對(duì)于有狀態(tài)場(chǎng)景网持,就比較麻煩了宜岛,對(duì)數(shù)據(jù)一致性要求不高的還OK,主備類型的方案基本也可以用功舀,當(dāng)然萍倡,主備方案要做的很好也非常不容易,有各種各樣的方案辟汰,對(duì)于主備方案又覺得不太爽的情況下列敲,例如HBase這樣的,就意味著掛掉一臺(tái)帖汞,另外一臺(tái)接管的話是需要一定時(shí)間的戴而,這個(gè)對(duì)可用性還是有一定影響的;
全局一致類型的場(chǎng)景中翩蘸,如果一臺(tái)掛了所意,就通常意味著得有選舉機(jī)制來(lái)決定其他機(jī)器哪臺(tái)成為主,常見的例如基于paxos的實(shí)現(xiàn)鹿鳖。
可維護(hù)性
維護(hù)性是很容易被遺漏的部分扁眯,但對(duì)分布式系統(tǒng)來(lái)說(shuō)其實(shí)是很重要的部分,例如整個(gè)系統(tǒng)環(huán)境應(yīng)該怎么搭建翅帜,部署姻檀,配套的維護(hù)工具、監(jiān)控點(diǎn)涝滴、報(bào)警點(diǎn)绣版、問(wèn)題定位胶台、問(wèn)題處理策略等等。
好了杂抽,以上就是為大家整理的架構(gòu)師必須掌握的分布式技術(shù)啦诈唬,有需要學(xué)習(xí)架構(gòu)師的朋友,也可以在Java課程直播間免費(fèi)學(xué)習(xí)缩麸,為了感謝大家的支持铸磅,小編歡迎大家進(jìn)群:901439810一起學(xué)習(xí)交流,并為大家提供java架構(gòu)師的全套學(xué)習(xí)資料