初識分佈式:MIT 6.284系列(一)
前言
本系列是源於 「碼農翻身」
所屬知識星球發起的讀書活動,由大佬 @我的UDP不丟包
推薦而來,這次的讀書活動有一些另類,我們拋棄了傳統的書籍,開始攻略最高學府的研究生頂級課程 <6.824>,該課程是很多年前的蠕蟲病毒發明者 Robert Morris
大佬授課,歸屬於 麻省理工大學
,授課方式主要是:視頻 + Lab 實驗(Go 語言) + 論文,全程英語,難度較大。
分佈式系統的判斷依據
- multiple cooperating computers (多臺計算機協作)
- storage for big web sites, MapReduce, peer-to-peer sharing (大規模數據集運算,如:MapReduce,或點對點共享)
- lots of critical infrastructure is distributed (系統的絕大部分基礎設施是分佈式的)
MapReduce
:大規模數據集計算系統,比如計算從 1 加到 1000 億,可以單臺計算機計算,也可以利用該技術分散到多臺計算機計算然後合併結果,極大的提高效率
爲什麼需要分佈式系統
- to increase capacity via parallelism (通過並行增加系統性能)
- to tolerate faults via replication (通過複製備份增加系統容錯)
- to place computing physically close to external entities (可以將計算放在離外部實體更近的地方)
- to achieve security via isolation (可以通過隔離增加系統的安全)
容錯:
針對於容錯,主要是兩點,一是可用性,二是可恢復性
對於分佈式系統來說,一般不會全部服務器同時癱瘓,因此無論是服務可用還是數據安全,都比單體服務更有保障。
分佈式的難點
- 需要額外注意併發編程,對開發人員的能力要求直線上升
- 系統內的相互作用非常複雜
- 意想不到的錯誤:局部錯誤
- 預期性能和實際性能往往不符
局部錯誤
:假設一臺機器每天出故障的概率是千分之一,在單體應用中,可能很長時間可以工作,但是在分佈式系統中,設備數量急劇上升,每天都可能有設備出現故障,這就是所謂的局部錯誤,很難排查,也幾乎無法避免
此處展示一張單體應用和分佈式應用的對比圖,圖片出自:《極客時間 · 左耳聽風》
分佈式系統的解決方案
宏觀目標
我們需要設計一系列能夠屏蔽分佈式系統複雜性的抽象
爲什麼要設立此目標?
因爲分佈式系統本身已足夠複雜,因此必須簡化使用方式
簡化使用方式和抽象有什麼關係?
我目前認可的最完美抽象是:文件
“UNIX 文件本質上就是一大袋字節。” —— 《UNIX 編程藝術》
在 Unix 中,任何可讀/寫也就是有 I/O 的設備,無論是文件,socket,驅動,在打開設備之後都有一個對應的文件描述符。Unix 將對這些設備的讀寫簡化在 read/write 中,換言之,你只需要把打開的文件描述符傳給這兩個函數,操作系統內核知道如何根據這個文件描述符得到具體設備信息,內部隱藏了對各種設備進行讀寫的細節,所有這些對用戶都是透明的,你只需要打開它,得到 fd,再進行相應的操作就夠了。
研究角度
- 實現方式。
- RPC 遠程調用,線程和併發控制
- 性能:
- 通常我們想要提供一個性能可以擴展的系統。
- 可以通過簡單增加系統的電腦數量來增強並行能力,從而部分擴展系統的性能:
- 當沒有複雜交互的時候這麼做很有效
- 可以不用請昂貴的程序員來重新設計系統。
- 簡單增加系統內電腦數量並不能一直增加系統性能:
- 當電腦數量變得很多的時候,負載不均,系統內每臺電腦性能不均,無法並行執行的代碼,初始化的交互都會降低系統的性能。
- 來自共享資源的訪問也會造成性能瓶頸,比如網絡通訊或者數據庫等
- 同時性能也並不能總是靠增加系統內電腦數量達成:
- 比如來自單一用戶請求的快速響應時間
- 比如所有用戶都想要更新同一個數據。
- 通常這些情況需要更好的程序設計而不是更多的電腦。
- 容錯:
- 大量的服務器 + 大型的系統通常代表着總有錯誤會發生
- 我們需要嚮應用程序隱藏這些錯誤
- 我們通常想要讓系統擁有可用性和可恢復性
- 可用性:即使錯誤發生了,系統還是可以繼續運行
- 可恢復性:當錯誤被修復之後,系統可以恢復運行
- 通常可以用備用的服務器來增加容錯
- 一致性:
- 通常想要達成正確工作的系統十分困難:
- 服務器和它的備份服務器之間很難保持一致,代價太高
- 客戶端可能會在中途出錯。
- 服務器可能會在處理之後回覆之前崩潰
- 不佳的網絡可能會使得正常的服務器無法提供服務
- 一致性和性能通常是矛盾的:
- 高一致性需要各種基礎設置之間大量的通信
- 許多設計爲了提升性能被迫只提供弱一致性
- 通常想要達成正確工作的系統十分困難:
一致性
:一致性問題貌似是最難以解決的問題,因爲它本質包含了性能,容錯,數據一致性等等諸多要素
我們前文說過,爲了考慮容錯容災機制,需要數據進行備份,那麼在分佈式系統中,A 服務修改了 A 數據庫的值,B 數據庫的值要不要跟着改,是立即跟着改,還是延遲跟着改,在同步修改中出問題了怎麼辦,在異步修改中出問題了怎麼辦
最終業界也很難解決相應的問題,因此現在主流的方式是: 最終一致性
即允許短時間內數據不一致,通過最終一致性保證性能和數據安全的兼顧
持續腦圖
文件分享地址: https://www.processon.com/view/link/5f1db0230791291b99680fa0
下一章內容
接下來的一章,我們將進行 <6.824> 中的 Lab 1,即實現一個簡單的 MapReduce
系統,該系統將採用 Go 語言構建
Go 語言是近些年非常熱門的語言之一,其價值個人感覺大於被炒的火熱的 Python
本章要求
- 瞭解分佈式系統的由來及面臨的挑戰
- 瞭解<6.824>課程中涉及的分佈式系統解決方案
- 搭建 Go 語言環境,寫出 HelloWorld 即可(語法層面及 MR 實現將在下章學習)
最後
相關資源:
如果覺得對你有用的話,不要忘記點個贊啊~ 也可以掃描二維碼關注我,一起朝着技術人的頂峯前進!