學習分散式系統需要怎樣的知識?

如題,希望有好的教材推薦?


歡迎轉載,請標明作者和出處。


作者:@馬超Terminal


我的 Phd 研究方向是分散式系統,我老闆也是搞分散式系統出身,我們實驗室在這方面的積累還算不錯,所以藉此問題談談自己的看法。首先需要說明的是,分散式系統是一個複雜且寬泛的研究領域,學習一兩門在線課程,看一兩本書可能都是不能完全覆蓋其所有內容的。介於這篇文章是引導初學者入門,所以我個人覺得為初學者介紹一下當前分散式系統領域的全貌,也許比直接推薦論文和課程更有幫助。當初學者對這個領域建立起一個大的 Picture 之後,可以根據自己的興趣,有選擇性的深入不同領域進行進一步的學習。

這篇文章主要試圖回答以下兩個個問題:

1. 近些年分散式系統領域都在做些什麼。
2. 為什麼現在投入分散式系統的學習和研究是值得的。

我會儘可能多的去介紹更 「實用」 的分散式系統知識。

什麼是實用?例如:

Paxos 是分散式系統里一個重要而且實用的技術。
Consistent Hash 也是分散式系統里一個重要而且實用的技術。
MapReduce, Spark 等等都是很實用的系統。

什麼不實用? 例如:

Paxos 演算法的數學證明。(注意此處「不實用」 和 「不重要」的區別)

當然,分散式系統實在是一個太寬泛的話題,本人才疏學淺,回答也僅僅可能側重於我所關心的領域和方向,很多地方都不能面面俱到。所以在此只能拋磚引玉, 蜻蜓點水,歡迎大家提出寶貴意見,我也會及時對文章進行修改和補充。


分散式系統近些年都在做些什麼?

分散式系統是一個古老而寬泛的話題,而近幾年因為 「大數據」 概念的興起,又煥發出了新的青春與活力。除此之外,分散式系統也是一門理論模型與工程技法並重的學科內容。相比於機器學習這樣的研究方向,學習分散式系統的同學往往會感覺:「入門容易,深入難」。的確,學習分散式系統幾乎不需要太多數學知識(相比於機器學習),這也是為什麼會造成 「入門容易」 的錯覺。然而一旦深入下去,往往需要我們去體會 system 研究的 「簡潔」 與 「美」,正如樓上 李沐 的回答中說的那樣,系統工作是 「藝術」 而不是 「科學」 ,這一點我覺得是系統研究工作最難,同時也是最精華的地方。總之把握一點原則:好的系統研究工作,尤其是分散式系統研究,一定是儘可能地用最簡單、最直觀的方法去解決實際的問題(看看 MapReduce 就知道了),因為簡單就意味著實用。

總的來說,分散式系統要做的任務就是把多台機器有機的組合、連接起來,讓其協同完成一件任務,可以是計算任務,也可以是存儲任務。如果一定要給近些年的分散式系統研究做一個分類的話,我個人認為大概可以包括三大部分:

1. 分散式存儲系統
2. 分散式計算系統
3. 分散式管理系統

近十年來在這三個方向上,毫無疑問, Google 都是開創者,甚至很多業內人士都說,這十年是外界追隨谷歌技術的十年。我們之前說到,分散式系統的研究是一門由實際問題驅動的研究,而 google 則是最先需要面對這些實際問題的公司。下面我們分別看看這三個方面工業界以及學術界這幾年都在做些什麼。

分散式存儲系統:

分散式存儲系統是一個非常古老的話題,同時也是分散式系統里最難,最複雜,涉及面最廣的問題。 往細了分,分散式存儲系統大概可以分為四個子方向:

1. 結構化存儲
2. 非結構化存儲
3. 半結構化存儲
4. In-memory 存儲

除了這四個子方向之外,分散式存儲系統還有一系列的理論、演算法、技術作為支撐:例如 Paxos, CAP, ConsistentHash, Timing (時鐘), 2PC, 3PC 等等,這些內容我們會在後面提到。現在,我們先來看看上述四個子方向大致都在幹些什麼。

結構化存儲(structured storage systems)的歷史非常古老,典型的場景就是事務處理系統或者關係型資料庫(RDBMS)。傳統的結構化存儲都是從單機做起的,比如大家耳熟能詳的 MySQL。有句話說:MySQL的成長史就是互聯網的成長史。這一點也不為過。除了 MySQL 之外,PostgreSQL 也是近幾年來勢頭非常強勁的一個 RDBMS. 我們發現,傳統的結構化存儲系統強調的是:(1)結構化的數據(例如關係表)。(2)強一致性 (例如,銀行系統,電商系統等場景)(3)隨機訪問(索引,增刪查改,SQL 語言)。然而,正是由於這些性質和限制,結構化存儲系統的可擴展性通常都不是很好,這在一定程度上限制了結構化存儲在大數據環境下的表現。隨著摩爾定律面臨的瓶頸,傳統的單機關係型資料庫系統面臨著巨大的挑戰。不過真的沒辦法了嗎?在此我們先埋下一個伏筆:)

非結構化存儲 (no-structed storage systems). 和結構化存儲不同的是,非結構化存儲強調的是高可擴展性,典型的系統就是分散式文件系統。分散式文件系統也是一個古老的研究話題,比如 70 年代的 Xerox Alto, 80 年代的 NFS, AFS, 90 年代 xFS 等等。然而,這些早期的分散式文件系統只是起到了網路磁碟的作用, 其最大的問題就是不支持 容錯 (fault tolerance)和 錯誤恢復 (fault recovery)。而 Google 在 2003 年 SOSP 上推出的 GFS (google file system) 則是做出了里程碑的一步,其開源實現對應為 HDFS. GFS 的主要思想包括:

(1)用 master 來管理 metadata。
(2)文件使用 64MB 的 chunks 來存儲,並且在不同的 server 上保存多個副本。
(3)自動容錯,自動錯誤恢復。

Google 設計 gfs 最初的目的是為了存儲海量的日誌文件以及網頁等文本信息,並且對其進行批量處理(例如配合 mapreduce 為文檔建立倒排索引,計算網頁 PageRank 等)。和結構化存儲系統相比,雖然分散式文件系統的可擴展性,吞吐率都非常好,但是幾乎無法支持隨機訪問(random access)操作,通常只能進行文件進行追加(append)操作。而這樣的限制使得非結構化存儲系統很難面對那些低延時,實時性較強的應用。

半結構化存儲 (semi-structure storage systems)的提出便是為了解決結非構化存儲系統隨機訪問性能差的問題。我們通常會聽到一些流行的名詞,比如 NoSQL, Key-Value Store, 甚至包括對象存儲,例如 protobuf,thrift 等等。這些都屬於半結構化存儲研究的領域,其中以 NoSQL 近幾年的發展勢頭尤為強勁。NoSQL 系統既有分散式文件系統所具有的可擴展性,又有結構化存儲系統的隨機訪問能力 (例如隨機update, read 操作),系統在設計時通常選擇簡單鍵值(K-V)進行存儲,拋棄了傳統 RDBMS 里複雜 SQL 查詢以及 ACID 事務。這樣做可以換取系統最大的限度的可擴展性和靈活性。在 NoSQL 里比較有名系統包括:Google 的 Bigtable, Amazon 的 Dynamo, 以及開源界大名鼎鼎的 HBase,Cassandra 等. 通常這些 NoSQL 系統底層都是基於比較成熟的存儲引擎,比如 Bigtable 就是基於 LevelDB ( jeff dean 寫的,非常好的 C++ 源碼教程) ,底層數據結構採用 LSM-Tree. 除了 LSM-Tree 之外 B-Tree (B+Tree)也是很成熟的存儲引擎數據結構。

In-memory 存儲。隨著業務的並發越來越高,存儲系統對低延遲的要求也越來越高。 同時由於摩爾定律以及內存的價格不斷下降,基於內存的存儲系統也開始普及。 In-memory 存儲顧名思義就是將數據存儲在內存中, 從而獲得讀寫的高性能。比較有名的系統包括 memcahed ,以及 Redis。 這些基於 K-V 鍵值系統的主要目的是為基於磁碟的存儲系統做 cache。還有一些偏向於內存計算的系統,比如可以追溯到普林斯頓 Kai Lee 教授早期的研究工作 distributed shared memory ( DSM ),斯坦福的 RamCloud, 以及最近比較火的基於 lineage 技術的 tachyon (Alluxio) 項目(Spark生態系統子項目)等等。

NewSQL. 我們在介紹結構化存儲時說到,單機 RDBMS 系統在可擴展性上面臨著巨大的挑戰,然而 NoSQL 不能很好的支持關係模型。那是不是有一種系統能兼備 RDBMS 的特性(例如:完整的 SQL 支持,ACID 事務支持),又能像 NoSQL 系統那樣具有強大的可擴展能力呢? 2012 年 Google 在 OSDI 上發表的 Spanner,以及 2013 年在 SIGMOD 發表的 F1, 讓業界第一次看到了關係模型和 NoSQL 在超大規模數據中心上融合的可能性。不過由於這些系統都太過於黑科技了,沒有大公司支持應該是做不出來的。比如 Spanner 里用了原子鐘這樣的黑科技來解決時鐘同步問題,打破光速傳輸的限制。在這裡只能對 google 表示膜拜。

我們在之前提到,分散式存儲系統有一系列的理論、演算法、技術作為支撐:例如 Paxos, CAP, Consistent Hash, Timing (時鐘), 2PC, 3PC 等等。那麼如何掌握好這些技術呢?以我個人的經驗,掌握這些內容一定要理解其對應的上下文。什麼意思呢?就是一定要去思考為什麼在當下環境需要某項技術,如果沒有這個技術用其它技術替代是否可行,而不是一味的陷入大量的細節之中。例如:如何掌握好 Paxos? Paxos本質上來說是一個三階段提交,更 high level 講是一個分散式鎖。理解paxos必須一步一步從最簡單的場景出發,比如從最簡單的 master-backup 出發,發現不行,衍生出多數派讀寫,發現還是不行,再到 paxos. 之後再了解其變種,比如 fast paxos, multi-paxos. 同理為什麼需要 Consistent Hash, 我們可以先思考如果用簡單range partition 劃分數據有什麼問題。再比如學習 2pc, 3pc 這樣的技術時,可以想想他們和paxos 有什麼關係,能否替代 paxos。

以上是我關於分散式存儲系統內容的一些總結,推薦一些相關的論文 ,有興趣的讀者可以看看:

The Google File System
Bigtable: A Distributed Storage System for Structured Data.
Dynamo: Amazon"s Highly Available Key-value ...
Introduction to HBase Schema Design
Consistency Tradeoffs in Modern Distributed Database System Design
Spanner: Google』s Globally-Distributed Database
F1: A Distributed SQL Database That Scales
Tachyon: Reliable, Memory Speed Storage for Cluster Computing
RAMCloud and the Low- Latency DatacenterCassandra - A Decentralized Structured Storage System
MapReduce: A major step backwards
MapReduce and Parallel DBMSs: Friends or Foes?
A comparison of approaches to large scale data analysis


分散式計算系統

聊完了分散式存儲系統,讓我們來聊聊分散式計算系統 :) 首先解決一個很多初學分散式計算的同學的疑惑:分散式計算和並行計算是一回事嗎?最初我也有這樣的疑惑,而現在我的理解是這樣的:

傳統的並行計算要的是:投入更多機器,數據大小不變,計算速度更快。
分散式計算要求:投入更多的機器,能處理更大的數據。

換句話說二者的出發點從一開始就不同,一個強調 high performance, 一個強調 scalability. 舉例來說,MapReduce 給業界帶來的真正的思考是什麼?其實是給我們普及了 google 這樣級別的公司對真正意義上的「大數據」的理解。因為在 04 年論文出來之前,搞並行計算的人壓根連 「容錯」的概念都沒有。換句話說,分散式計算最為核心的部分就是「容錯」,沒有容錯,分散式計算根本無從談起。MapReduce 統要做成這個樣子(map + reduce),其實就是為了容錯。

然而很多初學分散式計算的同學對容錯的概念多多少少是有誤解的。包括我在初學 mapreduce 的時候也會思考:好好的計算怎麼就會出錯了呢?一方面,由於硬體的老化,有可能會導致某台存儲設備沒有啟動起來,某台機器的網卡壞了,甚至於計算運行過程中斷電了,這些都是有可能的。然而最平凡發生的錯誤是計算進程被殺掉。因為 google 的運行環境是共有集群,任何一個許可權更高的進程都可能 kill 掉你的計算進程。設想在一個擁有幾千台機器的集群中運行,一個進程都不被 kill 掉的概率幾乎為零。具體的容錯機制我們會在後面介紹具體的系統時提到。

另一個有意思的話題是,隨著機器學習技術的興起,越來越多的分散式計算系統是為了機器學習這樣的應用設計的,這也是我比較關注的研究領域,也會在後面重點談到。

如同分散式存儲系統一樣,我對分散式計算系統也做了一個分類,如下:

1. 傳統基於msg的系統
2. MapReduce-like 系統
3. 圖計算系統
4. 基於狀態(state)的系統
5. Streaming 系統

當然不同的人可能會有不同的分類方法,不過大同小異。我們接下來聊聊這些系統都在幹些什麼。

傳統基於msg的系統 . 這類系統里比較有代表性的就是 MPI (message passing interface). 目前比較流行的兩個 MPI 實現是 mpich2 和 openmpi . MPI 這個框架非常靈活,對程序的結構幾乎沒有太多約束,以至於大家有時把 MPI 稱為一組介面 API, 而不是系統框架。在這些 API 里最常用的兩個就是 send 和 recv 介面(還有一系列非阻塞擴展介面,例如:Isend, Irecv 等)。MPI 除了提供消息傳遞介面之外,其框架還實現了資源管理和分配,以及調度的功能。除此之外,MPI 在高性能計算里也被廣泛使用,通常可以和 Infiniband 這樣的高速網路無縫結合。

除了 send 和 recv 介面之外,MPI 中另一個介面也值得注意,那就是 AllReduce. 這個介面在很多機器學習系統開發里都很用。因為很多並行機器學習系統都是各個進程分別訓練模型,然後再合適的時候(例如一輪迭代結束)大家同步一下答案,達成共識,然後繼續迭代。這個 「達成共識」 的操作往往可以很方便的通過 AllReduce 來完成。 AllReduce 介面具有兩個優點:1. 高效。 2. 實用簡單。 先說說為什麼使用簡單。使用 AllReduce 通常只需要在單機核心源碼里加入 AllReduce 一行代碼,就能完成並行化的功能。說 AllReduce 高效的原因是因為其底層消息傳遞使用了 tree aggregation,儘可能的將計算分攤到每一個節點。

可是,既然 AllReduce 這麼好,為什麼在實際大大規模計算中很少看到呢?原因很簡單,就是因為 MPI 不支持容錯,所以很難擴展到大規模集群之上。不過最近陳天奇寫了一個支持容錯的 allreduce 介面,叫rabit,有興趣的同學可以關注一下。 大名鼎鼎的 xgboost 底層的分散式介面就是 rabit.

MapReduce-like 系統. 這一類系統又叫作 dataflow 系統,其中以 MapReduce (Hadoop) 和 Spark 為代表。其實在學術界很有很多類似的系統例如 Dryad, FlumeJava, Twister 等等。這一類系統的特點是將計算抽象成為 high-level operator, 例如像 map,reduce,filter 這樣的函數式運算元,然後將運算元組合成 DAG ,然後由後端的調度引擎進行並行化調度。其中,MapReduce 系統屬於比較簡單的 DAG,只有 map 和 reduce 兩層節點。MapReduce 這樣的系統之所以可以擴展到超大規模的集群上運行,就是因為其完備的容錯機制。在 Hadoop 社區還有很多基於 mapreduce 框架的衍生產品,比如 Hive (並行資料庫OLAP), Pig(互動式數據操作)等等。

MapReduce-like 的編程風格和 MPI 截然相反。MapReduce對程序的結構有嚴格的約束——計算過程必須能在兩個函數中描述:map 和 reduce;輸入和輸出數據都必須是一個一個的 records;任務之間不能通信,整個計算過程中唯一的通信機會是 map phase 和 reduce phase 之間的 shuffuling phase,這是在框架控制下的,而不是應用代碼控制的。因為有了嚴格的控制,系統框架在任何時候出錯都可以從上一個狀態恢復。Spark 的 RDD 則是利用 Lineage,可以讓數據在內存中完成轉換。

由於良好的擴展性,許多人都機器學習演算法的並行化任務放在了這些平台之上。比較有名的庫包括 Mahout (基於Hadoop), 以及 MLI (基於 Spark) . 然而這些系統最大缺點有兩點:

1. 這些系統所能支持的機器學習模型通常都不是很大。導致這個問題的主要原因是這系統在 push back 機器學習模型時都是粗粒度的把整個模型進行回傳,導致了網路通信的瓶頸。有些機器學習的模型可以大到無法想像,比如我們用 Field-aware factorization machine (FFM)做 criteo 的 ctr prediction 時模型大小可以達到100 GB.

2. 嚴格的 BSP 同步計算使得集群的效率變的很低。也就是說系統很容易受到straggle的影響。

圖計算系統. 圖計算系統是分散式計算里另一個分支,這些系統都是把計算過程抽象成圖,然後在不同節點分散式執行,例如 PageRank 這樣的任務,很適合用圖計算系統來表示。最早成名的圖計算系統當屬 Google 的 pregel,該系統採用 BSP 模型,計算以 vectex 為中心。隨後又有一系列圖計算框架推出,例如:GPS (對 Pregel 做了優化,除了vectex-centric computation,還有 global computation,動態調整分區等等。)Giraph / Hama 都是基於 Hadoop 的 Apache 的開源 BSP 圖計算項目。

除了同步(BSP)圖計算系統之外,非同步圖計算系統里的佼佼者當屬 GraphLab,該系統提出了 GAS 的編程模型。目前這個項目已經該名為 dato.,專門推廣基於圖的大規模機器學習系統。

基於狀態(state)的系統. 這一類系統主要包括 2010 年 OSDI 上推出的 Piccolo, 以及後來 2012 年 nips 上 Google 推出的 distbelief,再到後來被機器系學習領域廣泛應用的 Parameter Server 架構。這裡我們重點介紹一下 Parameter Server 這個架構。

我們之前說,MPI 由於不支持容錯所以很難擴展至大規模集群之中;MapReduce 系統無法支持大模型機器學習應用,並且節點同步效率較低。用圖抽象來做機器學習任務,很多問題都不能很好的求解,比如深度學習中的多層結構。而 Parameter Server 這種 state-centric 模型則把機器學習的模型存儲參數上升為主要組件,並且採用非同步機制提升處理能力。參數伺服器的概念最早來自於 Alex Smola 於 2010 年提出的並行 LDA 架構。它通過採用分散式的 memcached 作為存放參數的存儲,這樣就提供了有效的機製作用於不同worker節點同步模型參數。 Google 的 jeff dean 在 2012 年進一步提出了第一代 Google Brain 大規模神經網路的解決方案 Distbelief. 在後來的 CMU 的 Eric xing 以及百度少帥 李沐 都提出了更通用的 Parameter server 架構。

如果要深入 Parameter server 系統的設計,需要一些機器學習的背景,比如什麼是 ssp 協議, 在此我們就不詳細討論了。

Streaming 系統. Streaming 系統聽名字就能看出來是為流式數據提供服務的。其中比較有名的系統包括 Storm, Spark Streaming, Flink 等等。由於本人對這個領域並不是很熟,就不詳細介紹了。


以上是我對分散式計算系統的一些介紹,其實每一個方向深入下去都是一個研究領域,在此推薦一些論文:

MapReduce: Simplified Data Processing on Large Clusters
Resilient Distributed Datasets
Scaling Distributed Machine Learning with the Parameter Server
Distributed GraphLab: A Framework for Machine Learning
Piccolo: Building Fast, Distributed Programs with Partitioned ..
Petuum: A New Platform for Distributed Machine Learning on Big Data
Spark Streaming
Dryad: Distributed Data-parallel Programs from Sequential Building ...
Large Scale Distributed Deep Networks - NIPS Proceedings

分散式管理系統:

(未完待續)


如果是新手的話,到沒必要一上來就讀論文。首先要對分散式系統的特點,尤其是它和單機系統的不同有個大致的了解。推薦看

  • Distributed systems for fun and profit Chapter 1
  • Fallacies of Distributed Computing
    Explained
  • A Note Distributed System

上面幾篇文章揭開了分散式系統的冰山一角,你對faliure這個詞的印象應該非常深刻,因為它差不多出現了好幾百次。

然後你可以花上幾天,認真讀一下 Distributed systems for fun and profit 。這本小書可讀性很強,基本的東西也都覆蓋差不多了。它比較好多一點是不糾結演算法細節,重在梳理思路。當然它也給了reference,假如你需要的話。

最後你可以看 Distributed systems theory for the distributed systems engineer 。這篇文章除了把之前你已經看過的東西重新梳理的一邊,同時也推薦了好多paper幫你更深入的了解。關於讀paper,我覺得如果你沒有很強的驅動力是很難啃下去的。要麼工作中在用的某個系統,需要深入了解;要麼自己在實現一個類似的系統。總之要綜合實踐才好繼續深入。


推薦CMU兩門課。CMU是系統方向不錯的學校(CMU做系統的老師覺得自己最多只弱於MIT,呵呵)。

一是15-440。這是分散式系統的入門課,主要是針對本科生。推薦下14年Dave和Srini上的,特色之一是用了Go(那陣子Dave特別著迷於go)地址在 http://www.cs.cmu.edu/~dga/15-440/S14/

二是15-712。面向PhD,主要是讀paper。我上過12年的那次 15-712 Advanced and Distributed Operating Systems, Spring 2012 上課老師Hui Zhang是神人之一,大局觀特別好,上了之後啟發很大。我算是從這課入的門。

建議順序是先學習440的課件,然後完成作業,有餘力再712.

不過提醒一點是,這兩門課都沒有錄像,所以光看課件效果會差很多。尤其是15-712這門課,純自己讀paper和老師在你讀後講一講差很遠。這個主要是因為系統是藝術而不是科學。裡面的很多設計決定和哲學相關。所以不僅僅是懂怎麼做的 ,更多是體會為什麼要這麼設計。


竟然碰上老本行問題,已經離開幾年,基於之前的經驗試答如下,不足之處請真正的專家指教 @劉縉 :

「分散式系統」包含較廣的範圍,從簡單的玩具型memcached集群到工業級的infrastructure(GFS, Borg, Chubby等等),從幾台機器到數萬台機器,系統環境和解決方案差異很大,所以如果題主問這麼籠統的一個問題,比較合適的建議是:

1. 理解「分散式系統」一般要面臨的問題
2. 了解目前業界的研究方向和解決方案
3. 如果有機會的話,為某個工業級分散式系統工作一段時間

對於12兩點,可以參考的資料包括:
1. Leslie Lamport的個人網站,有大量他的論文。因為在分散式系統基礎研究方面的卓越貢獻,他獲得2013年的圖靈獎。此人對於分散式系統,就類似愛因斯坦對於相對論,強烈建議深度閱讀其著作。
2. 工業級系統的相關論文,關鍵詞包括GFS,Chubby,MapReduce,Microsoft Dryad,Amazon Dynamo,Hadoop,等等。
3. MSRA作品PacificA,有比較完善的論文,看過演示,做得相當不錯。

下面是一些常見問題,僅做拋磚引玉之用:

1. 硬體底層軟體的失效與高可用性高性能的矛盾。硬碟,交換機,進程,甚至OS本身都有失敗/崩潰的可能,在包含很多機器(比如&>1000)的廉價(使用非企業級硬體)集群中,這個問題表現為「你的系統總有一部分處於故障狀態,如何保證高可用性?」,它的另一半是「如何在盡量少系統開銷的前提下,保證此可用性?」。一個簡單的例子是,為防止單點故障,數據通常都有備份。備份越多,可用性通常越好,但需要更多的磁碟空間和網路帶寬,導致性能降低。那麼多少備份合適?如何將這些備份分散到集群上(例如跨硬碟,跨機器,跨交換機,等等要求)?

2. 編程模型與單機不同,如何克服習慣帶來的影響。一個最簡單的例子是關於「鎖」的。在單機上,如果進程A和進程B都想修改數據D(例如做一個D++操作),有很多種方法可以避免衝突。但分散式系統就要面臨選擇:要麼用單機管理數據D(並忍受由此帶來的低可用性,因為單機失效將造成整個集群不可用),要麼用多機共同管理數據D(並忍受複雜的協議,一大堆代碼,還有性能開銷)。Paxos就是以上問題的經典解決方案(分散式的),發明者即Leslie Lamport。

3. 工業級的分散式系統意味著一整套工具集,除了那些運行在生產系統上的集群軟體,還有龐大的部署、運維、診斷軟體群,數量巨大的硬體(伺服器、交換機、機架、電源,這些都很可能是定製的),甚至包括建築物(數據中心的規劃、設計、內部結構等)。已經超出我的經驗範圍,作為一個引子,題主可自行了解。


鄙系的經典課程
CSE 552 Fall 2013 Lecture Topics , 來自分散式系統巨牛Tom Anderson

把上面的論文都看一遍都差不多了。
有些基本的概念是必須要搞懂的

1. 分散式時鐘, 又叫Lamport Clock
2. 一致性問題,分散式系統的幾種一致性,以及具體系統實現上的權衡
3. 容錯性分散式系統的協議以及實現方式,偉大的PAXOS (又是lamport的貢獻), 以及replicated state machine (另一點陣圖靈獎的貢獻,來自MIT的Babara Liskov)

Model Checker算是『高深武功』,基本上是用Formal Verification的思路來Verify 分散式系統,因為分散式系統是在是太難開發跟調試了。但是分散式系統的Model Checking還是個火熱的研究領域,換句話說並不成熟,Lamport的TLA+雖然厲害,但是懂得怎麼寫TLA+ Specification的人地球上太少了,等修鍊到一定程度再玩兒吧。


分散式系統的教材。。。我看過的都不怎麼好,廢話一堆,沒有重點。慎用教材
需要的知識很簡單:

  1. 略通一門程序語言能夠幫助你理解論文或者教材的偽代碼
  2. 強力的離散數學功底,可能需要拓撲和圖論,幫助你理解分散式演算法的證明。
  3. 略通網路通信協議,略懂就行。
  4. 略懂英文,很多新的分散式系統演算法都是英文論文,我上課的時候教授都是對著論文講課,也沒有教材這種東西。這個領域比較新。就用略懂的水平湊合著看,大概也能看明白論文在講什麼。

各位同學,阿里雲大學剛剛新鮮出爐的分散式課程:

【阿里雲大學課程】分散式技術第一彈,分散式調度系統

本章知識針對分步式系統中的調度技術進行闡述,比較Hadoop MR,Yarn等系統見的區別,並指出阿里雲伏羲系統在任務調度和資源調度時的處理方法。

點擊免費學:分散式系統開發--調度技術 - 阿里雲大學

講師簡介:

陶陽宇,阿里巴巴高級專家,主要從事大型分散式系統和高並發系統的開發,在系統架構設計,性能優化等方面有豐富積累,參與研發了阿里雲」飛天」分散式平台,支持5000節點大規模集群,主持研發了在線服務框架FuxiService、實時計算系統FuxiOnlinejob等多個線上產品,2015年帶領團隊在世界排序大賽SortBenchmark』2015中奪得冠軍,打破兩項世界紀錄。曾在國際會議VLDB、CSDN等雜誌發表過多篇技術文章,作為教師講授清華大學大數據課程。

課程目錄:

課時1:分散式調度系統現狀
課時2:任務調度
課時3:資源調度
課時4:容錯機制和規模挑戰
課時5:安全與性能隔離
課時6:未來發展方向

更多技術優質課程,請點擊關註:阿里雲大學 - 知乎專欄 以及 阿里雲大學開發者課堂


分散式,一來就直接看書,除非你有比較深厚的技術功底,要不還是很晦澀難懂的。

先想想為什麼會有分散式,分散式怎麼來的。傳統的電信、銀行業,當業務量大了之後,普通伺服器CPU/IO/網路到了100%,請求太慢怎麼辦?最直接的做法,升級硬體,反正也不缺錢,IBM小型機,大型機,採購了堆硬體。
但是互聯網不能這麼干,互聯網沒有那麼財大氣粗,還有很多初創,能不能賺錢還不知道。所以就有了軟體方面的解決方案:分散式系統,簡單說,就是一台伺服器不行,我用兩台、10台、100台...這就要軟體系統需要支持。

那麼軟體設計者就需要考慮了,那麼多台機器,我如何讓他們協同工作,這就需要一個調度中心(或註冊中心);肯定涉及到機器間通信,那麼需要一個高效的RPC框架;一個請求過來了,如何分發,需要一個請求分發系統(負載均衡);然後還要考慮每個角色都不能成為性能瓶頸;還有要能方便的進行橫向擴展,還有考慮單節點故障。

這些事你在設計分散式系統需要考慮的問題。筆者現在在互聯網行業,說的都是互聯網業的方案。比如現在負載均衡用nginx/HA,前者更輕量,後者負載均衡演算法更豐富;RPC框架用dubbo(可用噹噹的dubbox);用zookeeper中註冊中心,所有服務註冊在這裡。

需要分散式系統,並發量肯定不低,那麼有了上面的還是不夠的,還需要考慮cache、mq、job、db等方面的問題。cache,現在第三方緩存也比較成熟,redis/memcache等;mq,rabbitmq,kafka等等也不錯;job,現在第三方任務框架有elasticjob和tbschedule,或者你用quartz也支持分散式環境下的任務,不過quartz就沒有運維工具了。DB,資料庫最好在項目前期就考慮好業務拆分,系統拆分後DB對應的垂直拆分,後期可做讀寫分離,一主多從,甚至多主多從,業界也有了相應的解決方案。

總結一下,樓主要自己了解分散式原理,然後對應著每個功能區找業界內成熟的產品來實時。互聯網行業,基本都有開源的產品供你選擇。


對這個問題我很感興趣,最近也在摸索和實踐!,
我的第一個感悟是要理解清楚分散式系統和集群的關係!我在這上面迷惑了一段時間,當我差不多搞清楚後,很多問題豁然開朗!

  • 我給分散式系統的定義

其實,我們一直都在開發分散式系統,只不過使用的技術和業務場景都相對簡單!舉例來說,你在開發一個信息管理系統,這個系統需要訪問資料庫,通常資料庫都是作為一個單獨的系統,對外通過rpc實現通信!而整體上,你會認為資料庫服務是你的信息系統的一部分,對了,這就是分散式系統的基本模式:
不同的子系統或服務,彼此之間通過一定的方式或協議進行交互,對外表現為一個整體,隱藏了內部的複雜性,為用戶提供一致的,可伸縮,可用的服務。
而集群,顧名思義,同樣的內容分布到不同的地點,提供同質的服務。還是用上面的例子,你可以做一個資料庫的集群,而這個集群整體上是上面所述的分散式系統的一部分。說道集群一般會涉及負載均衡,這裡提一下,不做深入描述。

  • 分散式系統的技術組成

不知道分散式系統的技術組成,很難說如何入手學習分散式系統。而且,目前系統開發涉及內容紛繁複雜,用的技術真是亂花漸欲迷人眼,是我不得看清楚。一個技術人員的精力有限,所以要抓住分散式系統的核心技術,深入學習,夯實基礎,才能無往不利。
下面我總結一下我認為的分散式系統的技術組成,個人想法,如有雷同,請手動給贊:
1-開發分散式系統,第一個肯定是網路編程和rpc了。沒有這個,你分布個屁(說髒話了,罪過)
2-為啥開發分散式系統,不就是傳統系統不能滿足性能的要求了嗎?那麼並發、進程、線程技術以及ipc和同步互斥技術怎麼能不學習,是吧?
3、分散式系統,我認為最最不好實現的,也是最最關鍵的,那就是一致性的事務管理,通常都是鬆散的一致性。這裡涉及到事務、一致性演算法等內容
這三點是分散式系統的基礎,有了這些基礎,那麼分散式系統息息相關的可伸縮性、容錯、緩存等關鍵特性,理解和實現起來都將得心應手,不在迷惑。

  • 分散式系統的書籍推薦

自己也是在摸索實踐,我就按照我看過的書籍、論文或者計劃要看的書籍和論文大致推薦一下吧。希望高手指點、朋友間互相學習,實現共同富裕嗎!!!

神書 number 1:《unix 網路編程 卷一》

網路編程進階神器,誰用誰知道!
神書 number 2:《Concurrent Programming in Java?: Design Principles and Patterns, 2rd》 by Dog Lea

這本書是針對有一定多線程編程基礎的人推薦的,不過竊以為,你都想學習分散式設計了,還沒有多線程基礎嗎?這是一本模式類的書,講的是道,不是術,哈哈!
神書 number 3:《從PAXOS到ZOOKEEPER分散式一致性原理與實踐》 阿里系的書

這本書是介紹事務的,分散式事務。如果想了解資料庫事務管理,推薦tom 的 Export Oracle 系列!
神書 number 4:谷歌三大論文
這裡不上圖了,去google搜一下,這幾篇論文經典的很,也廣泛的傳播很。

  • 開源學習:

看看別人的代碼,找找靈感嗎,如果心情不好還可以提幾個bug。
說道學習分散式,那第一個出現的開源框架我認為zookeeper。原因太多了,是不是看看就知道。

千里之行始於足下,學習分散式開發也是一個道理。寫到這了,與大家共勉!


學習分散式系統,建議去「雲棲社區」看《分散式系統:概念與設計》這本書。這本書全面介紹網際網路及其他常用分散式系統的原理、體系結構、演算法和設計,內容涵蓋分散式系統的相關概念、安全、數據複製、組通信、分散式文件系統、分散式事務等,以及相關的前沿主題,包括web服務、網格、移動系統和無處不在系統等。


不管編程功底多紮實,在涉及分散式的時候,學一下model checker或者系統驗證的一些基礎知識對你以後是有極大的幫助的——M$RA搞分散式的同事如是說。


把計算機專業的本科階段的知識學好,就足夠玩分散式了。如果時間還多,可以翻翻研究生階段的分散式系統教材,裡面有幾個高級知識,但本科基礎紮實後,你會發現這些高階理念其實只是本科知識的組合而已。


搭一個小的memcached集群玩玩。
原理簡單,功能強大,使用範圍廣,實用性強。
玩明白了,稍稍舉一反三,各種NoSQL,大數據不在話下。
===========廣告=========
推薦教材
《大型網站技術架構:核心原理與案例分析》(李智慧)【摘要 書評 試讀】


從單機到分散式是有個質變的。
以前在一個機器輕鬆搞定的問題,在分散式下可能變得很困難。
如何通過增加機器,使得處理能力線性增長是很困難的。
推薦你學習Erlang,理解它背後的思想,對你學習分散式系統有幫助。
書籍:Erlang程序設計。


這個問題很難回答,題主要求教材,其實有很多, 經典的要算這本 Distributed Systems: Principles and Paradigms (2nd Edition)。編程語言也有很多選擇,我就推薦Erlang Programming 。


此外,看到上面答案中提到Model Checker,答主頓時感到非常親切。我研究生的時候,有一門課叫Concurrent System Analysis就涉及到了這個技術。當時一個瑞典的牛人單獨給我上課,此時還記憶深刻,這是我最難忘的課程了。具體不多說,核心就是讓系統按照你形式化的描述來測試你指定的系統。推薦我當時用過的兩個工具,有興趣的自己學習一下。當時我也是分散式剛入門,感覺學習一下,受益匪淺,不需要你多精通。

SPIN

quickcheck

第一個工具是NASA開發的,實現了Java虛擬機,功能非常的強大。 第二個相對比較簡單,可以用來做簡單測試。


不是說題主,只是一點感想。

只是覺得現在很多人本身操作系統和計算機架構都不太明白呢,強上分散式到最後也不過是背下來幾段概念而已。


高票答案寫得很全面了,我來從初學者角度說一下學習分散式系統開發的前置條件。
1)首先要有伺服器端編程的經驗,也就是說最好先學學怎麼在單伺服器上架設服務端程序。
2)然後學習一下多進程協作的程序如何編寫,也就是說多個服務端程序互相通信和協作,涉及到進程間通信的知識。多個進程可能在不同伺服器上。
3)學習一下伺服器中間件,如ACE、ICE。

相信有了以上基礎,學習分散式系統開發會有很大幫助。


如果是想學習分散式系統的構建而不是簡單的使用,最好系統地學習一個課程。推薦MIT的6.824: Distributed Systems (https://pdos.csail.mit.edu/6.824/)。網站上有所有的課程信息:papers, lecture notes和labs。Youbute上有部分的授課視頻。我就是按照這個課程來學的。


https://www.andrew.cmu.edu/course/15-440-s13/index/lecture_index.html
沒有AFS但不妨礙做課程項目


分散式系統在互聯網公司中的應用已經非常普遍,開源軟體層出不窮。hadoop生態系統,從hdfs到hbase,從mapreduce到spark,從storm到spark streaming,
heron, flink等等。常見的分散式系統分為數據存儲系統如hdfs,hbase;數據處理計算系統如storm、spark、flink;數據存儲兼分析混合系統,這類系統在數據存儲的基礎上提供了複雜的數據搜索查詢功能,如elasticsearch、druid。對於存儲兼計算的系統,我們仍然可以分開分析。

分散式系統

每個人都在提分散式系統,那麼什麼是分散式系統?其基本概念就是組件分布在網路計算機上,組件之間僅僅通過消息傳遞來通信並協調行動。

A distributed system is one in which components located at
networked computers communicate and coordinate their actions only by passing
messages. (摘自分散式系統概念和設計)

· 節點

節點可以理解為上述概念提到的組件,其實完成一組完整邏輯的程序個體,對應於server上的一個獨立進程。一提到節點,就會考慮節點是有狀態還是無狀態的?判斷標準很簡單,該獨立節點是否維護著本地存儲的一些狀態信息,或者節點是不是可以隨時遷移到其他server上而保持節點的行為和以前一致,如果是的話,則該節點是無狀態,否則是有狀態的。

· 異常

異常處理可以說是分散式系統的核心問題,那麼分散式異常處理相對於單機來說,有什麼不同呢?在單機系統中,對於程序的處理結果是可以預知的,要麼成功,要麼失敗,結果很明確。可在分散式環境中,處理結果除了明確返回成功失敗,還有另外一種狀態:超時,那超時意味著處理結果完全不確定,有可能成功執行,也有可能執行失敗,也有可能根本沒執行,這給系統開發帶來了很大的難度。其實各種各樣的分散式協議就是保證系統在各種異常情形下仍能正常的工作,所以在學習分散式系統時,要著重看一下文檔異常處理fault-tolerance章節。

· CAP理論

學習分散式系統中需要重要理解的理論,同時在架構設計中也可以用到這個理論,例如在一些情形下我們可以通過降低一致性來提高系統的可用性,將數據的每次資料庫更新操作變成批量操作就是典型的例子。

CAP理論,三個字母代表了系統中三個相互矛盾的屬性:

1. C(Consistency): 強一致性,保證數據中的數據完全一致

2. A(Available):在系統異常時,仍然可以提供服務,註:這兒的可用性,一方面要求系統可以正常的運行返回結果,另一方面同樣對響應速度有一定的保障

3. P(Tolerance to the partition of network ):既然是分散式系統,很多組件都是部署在不同的server中,通過網路通信協調工作,這就要求在某些節點服發生網路分區異常,系統仍然可以正常工作。

CAP 理論指出,無法設計一種分散式協議同時完全具備CAP屬性

從以上CAP的概念我們得出一個結論,在技術選型時,根據你的需求來判斷是需要AP高可用性的系統(容忍返回不一致的數據)還是CP強一致性的系統,或者根據系統提供的參數在AC之間權衡。(可能會有讀者會問,為什麼一定需要P呢?既然是分散式系統,在網路分區異常情況下仍然正常提供服務是必須的。)

數據存儲系統

當數據量太大以及已經超過單機所能處理的極限時,就需要使用到數據存儲分散式系統。無論是選擇開源系統還是自己設計,第一個要考慮的問題就是數據如何分散式化。

數據分布方式

· 哈希方式

哈希方式是最常見的數據分布方式。可以簡單想像有一個大的hash表,其中每個桶對應的一台存儲伺服器,每條數據通過某種方式計算出其hash值分配到對應的桶中。 int serverId =
data.hashcode % serverTotalNum上面只是一個簡單的計算公式示例,通過這種方式就可以將數據分配到不同的伺服器上。

· 數據範圍分布

將數據的某個特徵值按照值域分為不同區間。比如按時間、區間分割,不同時間範圍劃分到不同server上。

· 數據量分布

按數據量分布,可以考慮一個簡單例子:當使用log文件記錄一些系統運行的日誌信息時,當日誌文件達到一定大小,就會生成新的文件開始記錄後續的日誌信息。這樣的存儲方式和數據的特徵類型沒有關係,可以理解成將一個大的文件分成固定大小的多個block。

· 一致性哈希

前文剛提到的哈希方式,當添加刪除節點時候,所有節點都會參與到數據的遷移,整個集群都會受到影響。那麼一致性哈希可以很好的解決這個問題。一致性哈希和哈希的數據分布方式大概一致,唯一不同的是一致性哈希hash的值域是個環。

存儲架構模型

關於數據的分布和副本的模型這些細節問題已經詳細敘述,那麼從系統整體架構來看,數據存儲的一般流程和主要模塊都有哪些呢?從元數據存儲以及節點之間的membership管理方面來看, 主要分以下兩類:

· 中心化的節點membership管理架構

· 去中心化的節點membership管理架構


推薦閱讀:

為什麼有的人好像什麼都知道但現實中卻一事無成?
TED 哪個演講最打動你?
中國的四大名著有沒有閱讀的必要?
底層出身的孩子,假設當年你沒能上 985 或者 211,你會損失和錯過什麼?
有哪些讓人慾罷不能的學習方法?

TAG:互聯網 | 學習 | 分散式系統 | C++ |