1
無論是我們在學校剛開始學編程,還是在剛參加工作開始處理實際問題,寫出來的程序都是很簡單的。因為面對的問題很簡單。
以處理數據為例,可能只是把一個幾十 K 的文件解析下,然後生成一個詞頻分析的報告。很簡單的程序,十幾行甚至幾行就搞定了。
直到有一天,給你扔過來 1000 個文件,有些還特別大,好幾百 M 了。你用之前的程序一跑,發現跑的時間有點長。於是想要去優化下。
1000 個文件,互相還沒業務聯繫,用多線程呀,一個線程處理一個文件,結果再匯總就搞定了。總算把學校里學的作業系統知識和程式語言里的多線程庫都運用起來了。你很高興,老師知道了也會很欣慰。
如果多線程效果不夠好,比如像 Python 的多線程,沒法利用多核的威力,那就用多進程。
如果嫌線程和進程切換開銷太大,大到影響整體性能 -- 通常就是所謂的 I/O bound 的場景,還可以用協程這類技術。
無論是線程、進程,還是協程,本質上,目的都是為了計算的並行化,解決的是算的慢的問題。
而如果計算量足夠大,就算榨乾了機器的計算能力,也算不過來,咋辦?
一台機器不夠,那就多搞幾台機器嘛。所以就從多線程/進程/協程的「計算並行化」,進化到了「計算的分布式化」(當然,分布式一定程度上也是並行化)。
2
這還沒完,另一方面,如果處理的數據有 10T,而你手上的機器只有 500G 的硬碟,怎麼辦?
一種辦法是縱向擴展,搞一台幾十 T 硬碟的機器;另一種是橫向擴展,多搞幾台機器,分散著放。前者很容易到瓶頸,畢竟數據無限,而一台機器的容量有限,所以在大數據量的情況下,只能選後者。
把數據分散到多台機器,本質上解決的是存不下的問題。
同時,剛才提到計算分布式化後,總不能所以程序都去同一台機器讀數據吧,這樣效率必然會受到單台機器性能的拖累,比如磁碟 IO、網絡帶寬等,也就逼著數據存儲也要分散到各個機器去了。
基於這兩個原因,數據存儲也分布式起來了。
3
前面說計算的分布式化的時候,有這麼一句話:
一個線程處理一個文件,結果再匯總就搞定了
先做任務的拆分,然後再做結果的合併。本質上就是分治的思想。很顯然,分治是個非常通用和應用無關的方法,沒有必要每個應用都去實現一遍,做個通用的庫就行了,或者裝逼點,我們叫它框架。
解決這個問題之後,再做好抽象,豐富下功能,定義好 API,基本的樣子就出來了。
於是,我們有了一個分布式的計算框架。
4
而說存儲的分布式化的時候,忽略了一些問題,比如:
這些問題的答案也不難:
當然,問題不只這些,只是舉例而已。解決這些問題之後,再加以完善,封裝好 API 和服務,一個能存海量數據的框架就有了,或者裝逼點,我們叫它引擎。
於是,我們有了一個分布式的存儲引擎。
5
分布式存儲引擎和分布式計算框架,就是一個分布式系統最基礎的組成部分。
廣義的分布式系統,當然不只包含這兩個東西。但它們是最基礎和核心的東西。有了它們,我們就能對海量數據做最基本和通用的處理,而不再被單台機器束縛住。
是的,分布式系統很強大、很有用。但什麼時候該用,什麼時候又不要高射炮打蚊子呢?
其實也很簡單。和分布式系統嘗試解決的問題對應起來,就一目了然了:
那很有可能,你需要考慮分布式系統了。
至於多慢叫慢,多大叫大,就區別於應用場景了。
老闆每天早上要看的報表,凌晨跑幾個小時都能接受;全平台的准實時監控數據,就等不了幾個小時了。
同樣是做指標統計,幾百 G 的用戶註冊數據可能不算大,但幾百 G 的用戶行為數據可能就很大了。後者比前者更有可能需要分布式系統,因為增長速度會快一兩個數量級。
6
一個乍看起來很無厘頭,細想又挺值得思考的問題:微服務是不是分布式系統?
類似的問題還有:分庫分表+訪問中間件的資料庫是不是分布式系統?
廣義來講,都可以算是。
狹義來講,也是從這個系列關注的角度來看,分布式系統是指大數據領域下,以處理海量數據為目的的系統。
當然,分布式系統遠不止這麼簡單的兩個分類,也遠不止表面上看起來這樣隨便弄弄就能用好,還有非常多需要考慮和解決的問題,其中很多恰恰是分布式本身帶來的問題(聽起來很無奈吧),這也是這個系列後面會花大量篇幅去講的內容。
這樣,我們就對開頭提到的 What -- 這個東西是什麼,也有了基本的認識。
(看吧,先講 Why,再講 What,也沒有影響我們學習這個東西。我這麼組織,也是想借這點來強調開頭提到的多思考 Why 的重要性。)
總結:
這個系列文章關注的分布式系統,是指以處理海量數據為目的的多機系統。
我們之所以需要分布式系統,是為了擺脫單機資源的束縛。再具體點,是為了解決這兩個問題:
實際應用中,分布式系統最基礎核心的是兩種:
知道了為什麼要有分布式系統,以及什麼時候應該用分布式系統。緊接著一個問題就是,分布式系統都是怎麼來的,又是誰做出來的呢?
end:如果你覺得本文對你有幫助的話,記得關注點贊轉發,你的支持就是我更新動力。(商務合作私信即可)