分布式系統無疑是持久的熱門話題,但其實如果不是一定有必要,強烈建議不要進入分布式領域,在集中式的情況下很多問題都會簡單不少,技術人員千萬不要因為外界火熱的例如微服務,就把自己的產品的也去做改造,一定要仔細判斷是否有必要,不要為了技術而技術,那麼在必須分布式的情況下(訪問量、儲存量或開發人數),乙個分布式領域的合格的架構師要掌握哪些技術呢,這篇文章就聊聊這個話題。簡單重複下我對架構師的標準,乙個架構師最重要的不是畫幾個框,連幾條線(這是基本要求),而是控制技術風險,要控制技術風險顯然不是看幾個結構性的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方式下的伸縮性問題仍然是很大的挑戰,非常不好做。
上面所寫的基本都還只是解決的方向,到細節點基本就很容易判斷是乙個解決過多大規模場景問題的架構師,:)
作為分布式系統,必須要考慮清楚整個系統中任何乙個點掛掉應該怎麼處理(到了一定機器規模,每天掛掉一些機器很正常),同樣主要還是分成了無狀態和有狀態:
1. 無狀態場景
對於無狀態場景,通常好辦,只用節點發現的機制上具備心跳等檢測機制就ok,經驗上來說無非就是純粹靠4層的檢測對業務不太夠,通常得做成7層的,當然,做成7層的就得處理好規模大了後的問題。
2. 有狀態場景
對於有狀態場景,就比較麻煩了,對資料一致性要求不高的還ok,主備型別的方案基本也可以用,當然,主備方案要做的很好也非常不容易,有各種各樣的方案,對於主備方案又覺得不太爽的情況下,例如hbase這樣的,就意味著掛掉一台,另外一台接管的話是需要一定時間的,這個對可用性還是有一定影響的;
全域性一致型別的場景中,如果一台掛了,就通常意味著得有選舉機制來決定其他機器哪台成為主,常見的例如基於paxos的實現。
維護性是很容易被遺漏的部分,但對分布式系統來說其實是很重要的部分,例如整個系統環境應該怎麼搭建,部署,配套的維護工具、監控點、報警點、問題定位、問題處理策略等等。
從上面要掌握的這些技術,就可以知道為什麼要找到乙個合格的分布式領域的架構師那麼的難,何況上面這些提到的還只是通用的分布式領域的技術點,但通常其實需要的都是特定分布式領域的架構師,例如分布式檔案系統、分布式cache等,特定領域的架構師需要在具備上面的這些技術點的基礎上還具備特定領域的知識技能,這就更不容易了。
隨著網際網路的發展,分布式領域的很多技術都在成熟化,想想在8年或9年前,乙個大規模的**的伸縮性是怎麼設計的還是很熱門的**話題,但是到了今天基本的結構大家其實都清楚,並且還有很多不錯的系統開源出來,使得很多需要經驗的東西也被沉澱下去了,在有了各種不錯的開源產品的支撐下以後要做乙個分布式系統的難度一定會越來越大幅降低,雲更是會加速這個過程。
ps: 在寫這篇文章的過程中,發現要判斷乙個技術人的功底有多厚,其實還真不難,就是請ta寫或者講自己覺得懂的所有技術,看看能寫多厚或講多久...要寫厚或講很久其實都不容易,儘管我也不否認要很簡潔的寫明白或講清楚也不容易,但一定是先厚然後薄。
架構師速成8 3 可用性之分布式
分布式算是軟體界發展的乙個里程碑,它開闢乙個新的軟體時代,其他的溢美之詞我就不再亂說了。分布式按照我的觀點,應該分為有狀態和無狀態2種 有狀態 無狀態 當然分布式盡量做成無狀態的分布式,但是儲存最終因為最終儲存的是有狀態的資料,所以不得不變的有狀態。當然web系統也可以是有狀態的,但是最好做成無狀態...
優秀架構師必須掌握的架構思維
如果說架構的本質是管理複雜性,那麼抽象 分層 分治和演化思維是我們工程師 架構師應對和管理複雜性的四種最基本 1 抽象思維 抽象其實是這樣定義的 對某種事物進行簡化表示或描述的過程,抽象讓我們關注要素,隱藏額外細節。在系統架構和設計中,抽象幫助我們從大處著眼 get our mind about b...
分布式架構的架構效能
講的內容有點大,針對分布式架構做一系列的文章,醞釀了好久才打算著手寫這一系列,會持續多期 加入快取系統,可有效提高系統訪問能力,例如 網路,瀏覽器,cpu,硬碟,資料庫全都有快取。對於分布式系統下的快取系統,需要的是乙個快取集群。這其中需要 來做分片及路由。負載均衡系統是水平擴充套件的關鍵技術,它可...