分佈式系統的完整介紹

非常遺憾原文已無法查看,只知道作者Stanislav Kozlovski,文章標題:A Thorough Introduction to Distributed Systems,文章借鑑於
分佈式系統的完整介紹(一)
分佈式系統的完整介紹(二)
[分佈式系統]全面介紹分佈式系統

介紹

隨着技術在各行業的日益擴張,分佈式系統變的越來越普遍,這在計算機科學中是一個廣闊而複雜的學習領域。

這篇文章旨在給你介紹一下分佈式系統的基礎,讓你看一下分佈式系統的不同的類別。本文不會深入細節。

1. 什麼是分佈式系統

用最簡單的方式定義,分佈式系統就是讓終端用戶把一組工作在一起的計算機當做一個單獨的機器來使用。

這些機器共享狀態,併發操作,並且單個機器出現問題不會影響到整個系統的正常工作。

我打算用一個漸進式的例子來介紹分佈式,這樣你會有更直觀的感受:讓我們以數據庫爲例。傳統的數據庫存儲在單一機器的文件系統中,無論你什麼時候獲取或插入數據,你都需要直接訪問這個機器。傳統數據庫如圖:

Web Application
Database

如果我們要把這個數據庫變爲分佈式的,我們需要讓這個數據庫同時運行在不同的機器上。用戶必須能夠和他選取的任何一個機器進行會話,並且用戶不應該知道他其實並不是在和一個單獨的機器進行會話—如果用戶插入一條記錄到節點1,那麼節點3也必須能返回此記錄。分佈式數據庫:

insert user
select user where name='xxx'
name:xxx,passwd:sss
Web Application
Database1
Database2
Database3

2. 爲什麼需要分佈式系統

使用分佈式系統往往是不可避免的。現實的情況的是—分佈式系統的管理是非常複雜,其中佈滿了各種坑和雷。部署,維護和調試分佈式系統非常讓人頭疼,那爲什麼還要用它呢?

分佈式系統讓你獲得的是水平伸縮性(擴展性)。回到前面單個數據庫服務器的例子,提升數據訪問能力的唯一方法就是提升數據庫服務器硬件的性能。這被稱爲垂直伸縮(擴展)。

如果可以的話,垂直伸縮挺好的。但是從某個點開始你將會發現,即時是用最好的硬件,也滿足不了訪問的需要,且不說讓主機使用最好的硬件是不是切合實際。

簡單的說,水平伸縮的意思是增加更多的計算機而不是升級單個計算機的硬件。

當達到某個臨界點以後,這要比垂直伸縮便宜的多。然而這並不是分佈式的主要應用場合。

垂直伸縮可以使性能一下子猛增到最新的硬件能達到的水平。已經被證明,硬件的能力滿足不了技術公司對於中到大規模的負載的需要。

水平伸縮最好的一點是沒有伸縮的上限—無論什麼時候性能下降了,你都可以通過簡單的添加機器(可以添加無數臺)來解決。

容易獲得的伸縮性並不是分佈式系統唯一的好處。容錯和低延時也同等的重要。

容錯—一個橫跨兩個數據中心由十臺機器組成的集羣自然比單一機器的容錯性更強。即使一個數據中心着火了,你的程序還能工作。

低延時—一個網絡數據包在世界範圍內的傳輸速度是有光速限制的。比如,一個請求從紐約到悉尼,在光纖中可能的最短的往返時間(從發出請求到請求返回)是160毫秒。分佈式系統允許在兩個城市各有一個節點,請求者可以訪問最近的節點。

然而,爲了使分佈式系統能正常的工作,你需要專門設計運行在那些機器上的軟件,以使得它們

可以同時運行在多臺機器上並且可以應對隨之而來的各種問題。事實證明,這很難。

3. 伸縮我們的數據庫

設想一下,我們的網站非常的流行了,我們的數據庫開始需要在每秒鐘處理兩倍於它能力的請求。你的網站性能開始變差了,用戶也感受到了。

讓我們一塊兒來使我們的數據庫滿足更高的要求。

在一個典型的Web應用中,一般來說,讀取數據比插入和修改數據要頻繁的多。

有一種方式可以提高讀的性能,那就是所謂的“主從式複製”(Master-Slave Replication)策略。這裏你創建兩個新的數據庫服務器,它們從主數據庫同步數據。
注意:對於這兩個新的實例,你只讀取數據。

無論你什麼時候插入和修改數據,都在主數據庫進行。而主數據庫將會異步的通知從數據庫來保存這些數據的更改。

恭喜!現在對於讀取數據,性能已經是原來的三倍了。是不是很爽?

只插入/修改
只查詢操作
數據內容
Web Application
Master Database
Slave Database
Slave Database

缺陷

Duang!我們立刻失去了關係型數據庫中ACID中的C (Consistency),也就是一致性

你看,現在存在瞭如下的可能性:我們插入一條記錄到數據庫,然後立刻發起一個讀取此記錄的請求,但是沒有結果返回,就像這條記錄不存在一樣。

插入新的數據到主數據庫和同步新數據到從數據庫並不是同時完成的。這樣就會存在有可能讀取到舊數據的時間窗口。如果不想這樣的話,那麼寫操作就得等新數據被同步到所有的從數據庫以後纔算完成,這樣寫的性能就會很差。

分佈式系統中存在很多平衡和取捨。如果你想適當的進行伸縮,上面的問題是你不得不面對的。

繼續擴展

通過主-從數據庫的方式,我們可以把讀的能力擴展到一定的程度。這很好,但是我們還沒有解決對於寫的問題—寫還是通過單一的服務器進行的。

這裏我們並沒有太多的選擇。很簡單,由於一個機器不夠,我們需要把寫的請求分發到多個服務器上。

一種方式是“多主複製”策略。不同於只能讀取數據的“從數據庫”,你擁有多個“主節點”,主節點既可以讀又可以寫。很不幸,你很快會發現情況變的非常複雜,因爲你會製造出衝突(比如:插入兩條具有相同ID的記錄)。

讓我們嘗試一下另一種稱作“分片”(Sharding)方式,也稱作“分區”(Partition)。

我們把服務器分成多個小的服務器,每個服務器稱作一個分片。這些分片分別存儲不同的記錄—我們通過創建一套規則來決定哪些記錄去到哪個服務器。這套規則非常重要,它保證了數據以一致的方式分佈在分片上。

一種可行規則是基於數據記錄的某種信息來定義區間範圍(比如,用戶記錄以用戶名的首字母A-D)。如圖:

INSERT USER
SELECT USER
數據內容
Web Application
Sharded Database -> Users:A-L
Sharded Database -> Users:M-R
Sharded Database -> Users:S-Z

選擇用來分片的(比如上面例字中用戶名的首字母)需要非常的慎重,因爲鍵在數據記錄中的分佈可能非常的不平均(比如,名字首字母爲C的用戶可能比爲Z的要多很多)。某個分片如果收到的請求比其他的分片多很多,那麼它被稱作“熱點”,這是要必須避免的。一旦分片完成,重新分片的代價是非常昂貴的並且可能會造成長時間的宕機。

爲了使我們的例子簡單,假設我們的用戶知道在哪個分片上存儲一條記錄。注意一下,其實有非常多的分片策略,這個例子只是以一種簡單的方式解釋分片的概念。

現在我們更進了一步—我們把寫的性能提升到了原來的N倍,這裏N是分片的個數。性能提升幾乎沒有上限了—可以想象一下這種分片的方式可以做到多麼細的粒度。

缺陷

軟件工程中所有方面都或多或少的會涉及到平衡取捨,這裏也不例外。分片不是一件容易的事情,除非必要,否則最好不要用。

我們查詢數據的時候使用的是記錄的鍵(比如用戶表中的用戶名)而不是使用用來做分片的鍵(比如用戶名的首字母),查詢效率會非常的低,因爲查詢需要覆蓋到所有的分片。SQL的JOIN查詢會變的更復雜,效率也更低,變的幾乎不能用了。

去中心化和分佈式

在深入討論之前,我想先對這兩個詞區分一下。

雖然這兩個詞看起來很相似並且從邏輯的角度講是一回事兒,但是他們的區別對技術和運營會產生重大的影響。

從技術角度講去中心化依然是分佈式系統,但是整個去中心化的系統並不是被單一的參與者所擁有。沒有一個公司可以擁有一個去中心化的系統,否則就不能稱作去中心化了。

這意味着我們接下來討論到的系統可以被認爲是“分佈式的中心化系統”—它們也正是照此設計的。

如果仔細想一下,你會發現創建一個去中心化的系統要更困難一些,因爲你需要應對惡意的參與者。對於普通的分佈式系統,你不需要應對這種情況,因爲你知道你擁有所有參與的節點。

注意:去中心化分佈式的定義有很多的爭議,並且還可能和其他的定義產生混淆(比如P2P)。在早期的論文中,它們的定義也是不同的。不管怎麼樣,我給出的定義是我認爲被最廣泛採納的。當下,區塊鏈和加密貨幣讓這些名詞變的非常流行。

分佈式系統的類別

接下來我們將逐個分析幾個分佈式系統的類別,並且列舉外界已知的在生產環境中它們最大的使用規模。注意,當你讀到這篇文章的時候,下面提到的數字很可能已經過時了,並且很可能已經變的更大了。

1. 分佈式數據存儲

分佈式存儲的應用最爲廣泛,被稱爲分佈式數據庫。大部分的分佈式數據庫是NoSQL非關係型數據庫,限於使用鍵值對的語義。它們以一致性和可用性爲代價換來了令人難以置信的性能和伸縮性。

已知規模:在2015年的時候,蘋果公司使用75000個Apache Cassandra節點存儲了
10PB1PB=250B10PB(1PB=2^{50} B)的數據。

討論分佈式數據存儲免不了得先介紹一下CAP定理

CAP定理

早在2002年CAP定理就被證明了,CAP定理指出分佈式的數據存儲不能同時滿足一致性(Consistency)可用性(Availability)分區容忍性(Partition Tolerance)。可以選擇三者中的兩個,但是不能是一致性可用性

一些簡單的定義:

  • 一致性– 按次序讀到的和寫入的數據和預期是一樣的(還記得前面“主從數據庫複製”策略的缺陷吧)
  • 可用性– 整個系統不會掛掉– 每個沒有掛掉的節點總是能返回結果
  • 分區容忍性– 當發生網絡分裂的時候系統依然工作並且保證一致性/可用性。

在實際情況中,分區容忍性對於分佈式存儲是必需的。你不能夠在沒有分區容忍性的情況下獲得一致性和可用性。

想一下,如果你有兩個接受數據的節點並且節點之間的連接掛了,兩個節點怎麼樣可以做到都可用並且保證數據的一致性?它們沒有辦法知道彼此在做什麼,所以它們要麼連不上(不可用)要麼只能提供老的數據(不一致)。如圖:
數據的一致性
最終,你將面臨在網絡分裂的情況下選擇強一致性還是可用性

實踐表明,對大部分的應用來說,可用性的價值更大。強一致性並不總是必需的。甚至可以說,取“可用性”而舍“強一致性”,主要並不是因爲你需要100%的可用性保證,更多是因爲由強一致性造成的網絡延時是一個很大的問題。爲了獲得強一致性,機器間不得不同步數據,這會造成網絡延時。這些原因以及其他一些因素使得應用程序傾向於選擇高可用性的方案。

這樣的數據庫最終選擇了最弱的一致性模型 – 最終一致性(可以搜索瞭解強一致性和最終一致性相關的解釋)。這個模型保證如果一個數據項再沒有被更改,最終所有對該數據項的訪問都將返回最近更改的值

那些系統提供BASE屬性(相較於關係型數據庫的ACID)

  • 基本可用Basically Available)– 系統總是返回結果
  • 軟狀態Soft state)– 隨着時間的推移,即時沒有輸入(更改),系統狀態也可能發生變化(因爲最終一致性)
  • 最終一致性Eventual consistency)– 當沒有輸入(更改)的時候,數據遲早會擴散到每一個節點,從而達到一致的狀態
    這樣的分佈式數據庫的產品有– CassandraRiakVoldemort

當然,也有傾向於強一致性的分佈式數據存儲產品– HbaseCouchbaseRedisZooKeeper

CAP定理本身值得寫文章單獨闡述,已經有一些文章存在,有些討論如何根據客戶端的行爲調整系統的CAP屬性,有些討論爲什麼CAP沒有被恰當的理解。

Cassandra

Cassandra像前面提到的那樣是一個分佈式的NO-SQL數據庫,它傾向於CAP屬性中的AP,使用最終一致性。我必須承認,這有一點兒誤導,因爲Cassandra具有很強的配置功能,你可以以放棄高可用性爲代價來使它提供強一致性,但是這不是它最常用的方式。

Cassandra使用一致性哈希算法(consistent hashing)來決定集羣中的哪一個節點來處理你傳入的數據。同時你需要設置一個複製因子,這個因子主要用來指定你想複製數據到多少個節點。

下圖是一個寫數據的例子:
寫數據
讀數據的時候,你只會從那些複製的節點讀取。

Cassandra的伸縮性非常強,可以爲寫操作提供相當高的吞吐量。

下圖展示了每秒寫入數據的基準:
Cassandra寫數據

儘管這個圖可能有些不公平,因爲看起來我們讓Cassandra和一些設置了提供強一致性的數據庫進行比較(圖中MongoDB的節點從4個增加爲8個的時候,性能反而下降了,這應該是因爲MongoDB提供強一致性導致的),但是這個圖還是能夠展示出進行適當配置過的Cassandra的能力。

無論如何,在使得分佈式系統獲得高伸縮性和令人難以置信的高吞吐量的權衡中,Cassandra並沒有提供類似於ACID數據庫的一些基本功能– 比如事務處理。

共識

數據庫事務在分佈式系統中的實現非常複雜,因爲需要每個節點同意接下來的正確的行動(終止還是提交事務)。這被稱作“共識”,這是分佈式系統的一個基礎性的問題。

如果參與的進程和網絡環境完全可靠,達成是否提交事務的共識是很簡單直接的一件事情。然而,現實中的系統可能會有很多種情況的失敗,比如說進程崩潰,網絡分裂,丟失,失真或者重複消息等。

這會產生問題– 已經被證明,在不可靠的網絡環境中,是無法保證在給定的時間段內達成正確的共識的。

但是,在實踐中有一些算法可以使得在不可靠的網絡環境中非常快的達成共識。Cassandra實際上提供了輕量級的事務,它是通過使用爲達成分佈式共識的Paxos算法來實現的。

2. 分佈式計算

分佈式計算是最近這些年大數據處理大量涌現的關鍵。分佈式技術可以把單一機器不可能完成的巨大任務(比如聚合1000億條記錄)拆分成很多普通機器就可以完成的小任務。你把巨大的任務拆分成很多小任務,在多臺機器上同時執行他們,合理的進行聚合,從而解決你最初的問題。這種方式同時使得你獲得橫向伸縮的能力– 當你有一個更巨大的任務的時候,可以簡單的增加更多的節點進行計算。

已知規模– Folding@Home(可以在維基百科中查詢)項目,在2012年的時候就有160,000臺在線的機器。

在這個領域中谷歌是比較早的一個創造者,因爲他們需要爲分佈式系統發明一種新的範式來處理海量的數據– MapReduce。谷歌在2004年發表了一篇相關的論文,基於此論文開源社區在之後創建了Apache Hadoop。

MapReduce

MapReduce可以簡單的定義爲兩步– 映射(map)數據和規約(reduce)映射的結果爲有意義的數據。

我們舉例說明一下。

假設我們是一個媒體企業,我們在作爲數據倉庫的次級分佈式數據庫中存儲了海量的信息。我們想獲得從2017年4月開始每天的點贊次數。

這個例子很簡單也很清楚,但是想象一下面對的海量數據(假設有數十億級的點贊數)。我們顯然不會把所有的信息存放在一臺機器上,並且我們也不會只用一臺機器做數據分析。我們也不會直接訪問生產環境的數據庫,而是訪問專門爲低優先級的離線任務創建的數據倉庫。
MapReduce
每一個Map job運行在一個單獨的節點上,轉換儘量多的數據。每一個任務遍歷給定存儲節點中的數據,把它們映射(map)成一個元組,每個元組包含日期和數字。接下來,會完成三個中間步驟(很少有人提及)-- 打亂,排序和分片。這些步驟基本上是用來進一步的安排數據把它們代理給合適的Reduce job。因爲我們在處理海量的數據,我們爲每一個日期都創建一個單獨的Reduce job來處理。

這是一個好範式,令人詫異的是它可以讓你做更多的事情,比如你可以把多個MapReduce串聯在一起。

更好的技術

現今,MapReduce有點兒過時了,並且它自身也有一些問題。因爲它是多個job同時工作,當你的job失敗的時候問題就來了– 你需要重做所有的事情。一個需要兩小時的job的失敗可以拖慢你的整個數據處理流水線,你至少不願意這樣,尤其是在高峯時間。

另外一個問題是直到你獲得數據所要等待的時間。在實時分析系統中(大多具有海量數據,因而使用分佈式計算),數據儘可能的保持最新是非常重要的,幾個小時以前的數據是不能接受的。

因此,爲了解決這些問題,其他架構出現了。即Lambda架構(批處理和流式處理的混合)和Kappa架構(只是流式處理)。一些新的工具使得這些新的架構得以實現– Kafka Streams,Apache Spark,Apache Storm,Apache Samza。

3. 分佈式文件系統

分佈式文件系統可以被認爲是分佈式數據存儲。從概念上講,它們是一回事兒– 從看起來像一臺機器的機器集羣中存儲和訪問海量數據。它們經常和分佈式計算聯繫在一起。

已知規模– 雅虎在2011年的時候在多於42,000個節點上運行着HDFS,保存了600PB的數據。

維基百科定義分佈式文件系統的區別爲它允許文件以和本地文件相同的接口和語義進行訪問,而不是通過定製化的API,比如Cassandra Query Language(CQL)進行訪問。

HDFS

HDFS(Hadoop Distributed File System)是基於Hadoop框架的分佈式計算系統使用的分佈式文件系統。它被廣泛的採用,可以跨機器存儲和備份大文件(GB或TB大小)。

它的架構主要包括“名字節點”和“數據節點”。名字節點用以保存集羣的元數據,比如哪個節點存儲了哪些文件塊。它們通過判斷哪裏存儲和備份文件最好,跟蹤系統的健康狀況,扮演了網絡協調者的角色。數據節點只是簡單的存儲文件和執行命令,比如備份文件,寫新文件等等。
HDFS
HDFS最適合於Hadoop計算,因爲它爲計算任務提供了數據的可知性。計算任務可以在存儲數據的節點上運行。這充分利用了數據所在的機器,優化了計算並且減少了網絡上的數據傳輸。

IPFS

星際文件系統(Interplanetary File System)是分佈式文件系統中的一個令人興奮的新的點對點協議/網絡。通過區塊鏈技術,它可以構建出沒有單一擁有者和單點失敗的完全去中心化的架構。

IPFS提供名稱系統(和DNS很像)稱作IPNS,使得用戶可以很容易的訪問信息。它保存文件的歷史版本,就像Git一樣。這允許訪問文件以前的狀態。

儘管IPFS還在緊鑼密鼓的開發過程中(寫文章的時候是v0.4),但是已經有項目使用它了(FileCoin)。

4. 分佈式消息

消息系統爲你的整個系統提供了存儲和傳播消息/時間的中心。它使你可以對程序直接和其他系統對話進行解耦。

已知規模—LinkedIn的Kafka集羣每天處理1萬億的消息,高峯時間每秒鐘處理4500,000的消息

分佈式消息

簡單的說,消息平臺工作方式如下:

一個消息被程序(此程序也可能是消息的創建者)廣播出去(此程序被稱爲生產者),進入到消息平臺然後被感興趣的程序(可能有多個)讀取(這些程序被稱爲消費者)。

如果你需要保存一個消息到多個地方(比如創建用戶到數據庫,數據倉庫,郵件服務和其它你能想到的地方),消息平臺是最乾淨的方式。

消費者可以從消息中間件拉取信息(拉模式)或者使消息中間件直接推送信息(推模式)。

有幾個出色的消息平臺:

RabbitMQ—消息中間件,允許你通過路由規則或者其它容易配置的設置對消息的傳遞軌跡進行精細的控制。可以被稱爲智能的中間件,因爲它有很多的邏輯,並且它緊密的跟蹤傳遞的消息。提供CAP理論中對AP和CP的設置。通知消費者的時候使用推模式。

  • Kafka—消息中間件,有一點兒靠近底層,因爲它不會跟蹤記錄哪些消息被讀取了,並且不能設置複雜的路由邏輯。這使得它獲得了驚人的性能。我認爲在開源社區的開發和Confluent組的支持下這是它最有前途的地方。Kafka可能是頂級技術公司中被最廣泛使用的。我還寫了一篇Kafka全面的介紹,在文章中我詳細敘述了它所有的優點。

  • Apache ActiveMQ—最老的消息平臺,可以追溯到2004年。使用JMS API,意味着是面向Java EE程序的。它被重寫爲了ActiveMQ Artemis,性能很出色,可以達到Kafka同等的水平。

  • Amazon SQS—AWS提供的消息服務。讓你可以快速和已有程序進行集成,並且不需要搭建自己的基礎設施,這可能是一個很大的好處,因爲衆所周知Kafka一類的系統搭建起來很棘手。Amazon也提供了兩個類似的服務—SNS和MQ,後者其實就是ActiveMQ只不過被Amazon所託管。

5. 分佈式應用

如果你在一個負載均衡服務器後面連接着5臺服務器,這5臺服務器都連接到1個數據庫上,你能稱這個爲分佈式應用嗎?回憶一下我前面的定義。

分佈式系統是一組計算機一起工作,以便作爲單臺計算機顯示給最終用戶。這些機器具有共享狀態,併發操作並可獨立故障,而不會影響整個系統的正常運行時間。

如果你認爲數據庫只是用來共享的狀態,你可以爭辯說這可以劃分爲分佈式系統– 但是你錯了,你已經忽略了定義中“一起工作”的部分。

一個系統只有當節點之間的交互是爲了協調動作纔算是分佈式的。

因此,在點對點(P2P)網絡中運行後端代碼的應用最好被劃分爲分佈式應用。儘管這種分類沒有什麼意義,但是可以表明分類時會受到多少干擾。

已知規模– 2014年4月的時候對冰封王座遊戲的下載有19300個節點的BitTorrent種源池。

Erlang虛擬機

Erlang是一個函數式編程語言,具有非常棒的對於併發,分佈式和容錯的的語義。Erlang虛擬機自身處理Erlang程序的分佈。

它的模型使用很多**隔離(獨立)**的輕量級的進程,這些進程之間通過可以進行消息傳遞的內建系統來相互通信。這被稱作Actor模型,Erlang的OTP庫可以被認爲是分佈式的Actor庫(同時還有JVM中的Akka)。

這個模型使得它可以非常簡單的實現併發– 這些進程可以分佈在運行系統可用的核上。由於這種模式和網絡非常相像(除了網絡可以作廢消息),Erlang虛擬機可以連接到同一個數據中心甚至是其他州的Erlang虛擬機。這個虛擬機羣執行一個應用程序,可以通過接管的方式(安排另一個節點執行)處理機器的失敗。

實際上,Erlang語言添加了分佈層以提供容錯。運行在單一機器上的軟件總是會有宕機從而使應用不可用的風險。運行在多個節點上的軟件,硬件錯誤處理將會變得簡單。

BitTorrent

BT下載工具也是一個分佈式應用的例子。主要想法是促進網絡中不同對端之間的文件傳輸,而不必通過主服務器。
使用BitTorrent客戶端,您可以連接到世界各地的多臺計算機以下載文件。當你打開一個.torrent文件時,你連接到一個所謂的追蹤器,這是一臺充當協調器的機器。它有助於對等發現,向您顯示網絡中具有所需文件的節點。
一個示例網絡

一個示例網絡

你有兩種類型的用戶的概念,一個是一個leecher和一個播種機。leecher是正在下載文件的用戶,而播種員是上傳所述文件的用戶。

關於點對點網絡的有趣之處在於,作爲普通用戶,您有能力加入並貢獻於網絡。

BitTorrent及其前身(Gnutella,Napster)允許您自願託管文件並上傳給需要它們的其他用戶。BitTorrent之所以如此受歡迎的原因在於,它是第一個爲激勵網絡提供激勵的公司。在用戶只能下載文件的情況下,Freeriding是以前文件共享協議的問題。

BitTorrent通過使播種機上傳更多給那些提供最佳下載速率的人來解決一定程度的自由。它通過激勵您在下載文件的同時上傳。不幸的是,在你完成之後,沒有什麼能夠讓你在網絡中保持活躍。這導致在網絡中缺少具有完整文件的播種器,並且由於協議嚴重依賴於這些用戶,像私人跟蹤器這樣的解決方案已經實現。私人追蹤器要求您成爲社區成員(通常只有邀請)才能參與分佈式網絡。

在該領域取得進展之後,發明了無追蹤者的種子。這是對BitTorrent協議的升級,它不依賴集中跟蹤器來收集元數據並找到對等點,而是使用新算法。其中一個例子是Kademlia(Mainline DHT),一個分佈式哈希表(DHT),它允許您通過其他同行找到同行。實際上,每個用戶都會執行跟蹤器的職責。

6. 分佈式分類賬

分佈式分類賬可以理解爲不可更改,只能追加數據的數據庫,這個數據庫在分佈式網絡中被複制,同步和共享。

已知規模 - 以太坊網絡在2018年1月4日每天有130萬宗高峯。

它利用事件源模式(Event Sourcing),允許你在任何時間重建分類賬的歷史狀態

區塊鏈(Blockchain)

區塊鏈是分佈式分類賬底層使用的技術,並且是它開始的標誌。這個在分佈式領域新近的偉大的創新創造了第一個真正意義上的分佈式支付協議-比特幣。

區塊鏈是一個分佈式分類賬,它攜帶了在它的網絡中發生的所有的交易的序列。交易被分組保存在區塊上。整個區塊鏈實際上是一個區塊的鏈表。所謂的區塊需要大量的計算,並且通過加密算法和其他的區塊相關聯。

簡單的說,每一個區塊包含一個對當前區塊內容(內容是默克爾樹)的特殊哈希(以n個0開頭)加上前一個區塊的哈希。這個哈希需要非常多的CPU運算產生,因爲唯一產生它的方式就是暴力破解的方式。
簡化區塊鏈
礦工就是計算這些哈希的節點。礦工們會生成可以和區塊內容一起創建出前面提到的哈希的隨機字符串,這個過程中礦工們會相互競爭。一旦某個礦工發現了此字符串,它將會把它廣播到整個網絡。字符串會被每一個節點驗證,從而被接受到它們的鏈中。

這意味着區塊鏈是一個修改起來非常耗時,但驗證沒有被篡改卻非常容易的系統。

修改區塊的內容開銷非常大,因爲這需要生成一個新的哈希。記住一點,每一個後續的區塊都依賴於它。如果你想修改第一個區塊中的交易,你將會修改默克爾樹的根。這將會修改區塊的哈希,進而依次修改後續區塊的哈希。這意味着你需要爲修改的以及後續的每個區塊暴力計算新的隨機字符串。

網絡總是信任和複製最長的有效鏈。爲了欺騙系統和最終產生一個更長的區塊鏈,你需要網絡節點中一半以上的CPU的運算能力。

區塊鏈可以被認爲是一種對出現的事物達成共識的一種機制。共識並不是顯示達成的,當共識達成時並沒有選舉或者固定的時間。相反,共識是成千上萬的獨立節點,按照協議規則,異步地交互的結果。

這個史無前例的創造最近變成了一個技術熱點,有人預言它將會是Web 3.0創建的標誌。它無疑是當下最讓軟件領域激動的熱點,當然它也充滿了非常困難和有趣的問題等着人們去解決。

比特幣

前面的分佈式支付協議缺少的是如何以分佈式的方式實時地避免重複花費問題。研究產生了很多有趣的建議,但是比特幣是第一個實際實現了的比其他有明顯優勢的方式。

重複花費問題表述爲一個角色(例如,張三)不能在兩個地方花費他的一個資源。如果張三有一元錢,他不能同時把這一元錢給李四和王五。事實表明在分佈式系統中實現它非常的困難。有一些方法早於區塊鏈,但是它們不能在現實中完全解決這個問題。

重複花費可以被比特幣簡單地解決,只要一次只添加一個區塊到區塊鏈。重複花費在同一個區塊不可能發生,因此即使兩個區塊同時產生,也只有一個會被最終添加到最長的鏈上。

比特幣依賴於獲取CPU計算能力的困難度上。

在投票系統上,攻擊者只需要添加節點到網絡,這很容易,因爲自由訪問是網絡設計的目標。在以CPU運算能力爲基礎的方式上,攻擊者需要面對物理的限制:獲得越來越多的強大的硬件。

這樣,攻擊者想要成功,就需要控制網絡上大於50%的計算能力。少於50%,其他節點將會更快地創建更長的區塊鏈。

以太坊

以太坊可以理解爲可編程的基於區塊鏈的軟件平臺。它有自己的加密貨幣(乙醚),可以作爲在區塊鏈中部署智能契約的燃料。

智能契約是存儲在以太坊區塊鏈中的一段事物代碼。要運行這段代碼,只要發起一個以智能契約爲目標的事務。這將會使挖礦的節點執行代碼和做出相應變化。代碼是在以太坊的虛擬機上執行的。

Solidity是以太坊的原生編程語言,可用來寫智能契約。它是一個圖靈完備的編程語言,直接以以太坊區塊鏈爲接口,允許你查詢狀態,比如平衡或者其他智能契約結果。爲了避免無限循環,執行代碼需要一定量的乙醚。

由於區塊鏈可以解釋爲一系列的狀態變化,許多的分佈式應用建立在了以太坊或者類似的平臺之上。

分佈式分類賬更深層應用

  • 存在證明– 一個服務,可以匿名地和安全地保存一個數字文檔曾在某個時刻存在過的證據。用於保證文檔的完整性,擁有者和時間戳。
  • 去中心化的自治機構–使用區塊鏈來對改進建議達成共識的機構。
  • 去中心化的驗證– 在區塊鏈中保存身份信息,使你可以在任何地方使用單次登錄(SSO)。

還有其他很多,分佈式分類賬技術打開了無盡的可能。

總結

在文章中,我們進行了分佈式的定義,對每一個類別進行了描述。需要記住的一些點有:

  • 分佈式系統是複雜的
  • 選擇分佈式是因爲規模和代價
  • 分佈式的相關工作很難
  • CAP理論– 一致性和可用性之間的權衡
  • 有六個類別– 數據存儲,計算,文件系統,消息系統,分類賬,應用

坦率地講,我們僅僅是講了分佈式系統最表面的東西。我並沒有全面的處理和解釋核心的問題,比如:共識,複製策略,事件順序和時間,容錯,在網絡中廣播消息和其他。

注意

讓我在最後給你提一個預先的警告:

你必須儘可能的遠離分佈式系統。如果你可以用其他的方式解決問題,分佈式系統帶來的複雜程度不值得你付出的努力。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章