分佈式下載方式(一)原理分析

【特殊提醒:本文理論性較強,請謹慎閱讀】

上一篇文章中分析了UC瀏覽器的視頻下載方式:UC瀏覽器視頻播放緩存以及視頻下載分析,講到了P2P的下載方式,本文就分析一下什麼是P2P的下載方式,以及P2P所屬的分佈式的下載緩存體系。

傳統的下載就是client和server端交互,這個server是固定的,就是存儲資源的服務器,這時候不管網速如何,下載的速度嚴重依賴於服務器的服務穩定性,如果服務器不太穩定,接入就比較慢,下載速度就會受到很大的限制,這也是傳統下載方式的速度優化有一個非常明顯的天花板——難以解決單一服務器帶來的帶寬壓力。鑑於這個瓶頸問題,我們想要是可以將服務器的壓力分擔出去就好了,不唯一依賴某一個或者某幾個服務器,這樣至少可以將下載速度的上限明顯提高。

很顯然,真的有這樣的下載方式,就是P2P。P2P 就是 peer-to-peer。資源開始並不集中地存儲在某些設備上,而是分散地存儲在多臺設備上。這些設備我們姑且稱爲 peer。想要下載一個文件的時候,你只要得到那些已經存在了文件的 peer,並和這些 peer 之間,建立點對點的連接,而不需要到中心服務器上,就可以就近下載文件。一旦下載了文件,你也就成爲 peer 中的一員,你旁邊的那些機器,也可能會選擇從你這裏下載文件,所以當你使用 P2P 軟件的時候,例如 BitTorrent,往往能夠看到,既有下載流量,也有上傳的流量,也即你自己也加入了這個 P2P 的網絡,自己從別人那裏下載,同時也提供給其他人下載。可以想象,這種方式,參與的人越多,下載速度越快,一切完美。

種子文件解析

我們怎麼知道有哪些客戶端有資源文件?

就輪到“種子文件”登場了,種子文件的後綴是“.torrent”,這個相信大家並不陌生,PC時代有很多P2P的下載工具,其中著名的有迅雷、電驢、風行,還有一些使用P2P技術的播放器,比較著名的有快播。哈哈,言歸正傳,種子文件中記錄中每一個節點中存放着什麼數據,並且這個節點的一些基本信息,方便我們能連接上這個節點並且下載這個資源。

給大家介紹一個在線的torrent分析站點:http://tool.chacuo.net/commontorrentinfo,我現在想解析一個本地的torrent文件,結果如下:

 

 

 

 

.torrent 文件由兩部分組成,分別是:announce(tracker URL)和文件信息。

下載時,BT 客戶端首先解析.torrent 文件,得到 tracker 地址,然後連接 tracker 服務器。tracker 服務器迴應下載者的請求,將其他下載者(包括髮布者)的 IP 提供給下載者。下載者再連接其他下載者,根據.torrent 文件,兩者分別對方告知自己已經有的塊,然後交換對方沒有的數據。此時不需要其他服務器參與,並分散了單個線路上的數據流量,因此減輕了服務器的負擔。

下載者每得到一個塊,需要算出下載塊的 Hash 驗證碼,並與.torrent 文件中的對比。如果一樣,則說明塊正確,不一樣則需要重新下載這個塊。這種規定是爲了解決下載內容的準確性問題。

從這個過程也可以看出,這種方式特別依賴 tracker。tracker 需要收集下載者信息的服務器,並將此信息提供給其他下載者,使下載者們相互連接起來,傳輸數據。雖然下載的過程是非中心化的,但是加入這個 P2P 網絡的時候,都需要藉助 tracker 中心服務器,這個服務器是用來登記有哪些用戶在請求哪些資源。

所以,這種工作方式有一個弊端,一旦 tracker 服務器出現故障或者線路遭到屏蔽,BT 工具就無法正常工作了。

  • info 區:這裏指定的是該種子有幾個文件、文件有多長、目錄結構,以及目錄和文件的名字。

  • Name 字段:指定頂層目錄名字。

  • 每個段的大小:BitTorrent(簡稱 BT)協議把一個文件分成很多個小段,然後分段下載。

  • 段哈希值:將整個種子中,每個段的 SHA-1 哈希值拼在一起。

DHT——去中心化

鑑於P2P下載的一些瑕疵,那能不能徹底去中心化呢?

爲了解決P2P下載的這個問題,DHT(Distributed Hash Table)應運而生,這是一種完全的去中心化的網絡。每個加入這個 DHT 網絡的人,都要負責存儲這個網絡裏的資源信息和其他成員的聯繫信息,相當於所有人一起構成了一個龐大的分佈式存儲數據庫。

有一種著名的 DHT 協議,叫 Kademlia 協議。這個和區塊鏈的概念一樣,很抽象,我來詳細講一下這個協議。任何一個 BitTorrent 啓動之後,它都有兩個角色。一個是 peer,監聽一個 TCP 端口,用來上傳和下載文件,這個角色表明,我這裏有某個文件。另一個角色 DHT node,監聽一個 UDP 的端口,通過這個角色,這個節點加入了一個 DHT 的網絡。

任何一個 BitTorrent 啓動之後,它都有兩個角色。一個是 peer,監聽一個 TCP 端口,用來上傳和下載文件,這個角色表明,我這裏有某個文件。另一個角色 DHT node,監聽一個 UDP 的端口,通過這個角色,這個節點加入了一個 DHT 的網絡。

 

在 DHT 網絡裏面,每一個 DHT node 都有一個 ID。這個 ID 是一個很長的串。每個 DHT node 都有責任掌握一些知識,也就是文件索引,也即它應該知道某些文件是保存在哪些節點上。它只需要有這些知識就可以了,而它自己本身不一定就是保存這個文件的節點。

當然,每個 DHT node 不會有全局的知識,也即不知道所有的文件保存在哪裏,它只需要知道一部分。那應該知道哪一部分呢?這就需要用哈希算法計算出來。

每個文件可以計算出一個哈希值,而 DHT node 的 ID 是和哈希值相同長度的串。DHT 算法是這樣規定的:如果一個文件計算出一個哈希值,則和這個哈希值一樣的那個 DHT node,就有責任知道從哪裏下載這個文件,即便它自己沒保存這個文件。當然不一定這麼巧,總能找到和哈希值一模一樣的,有可能一模一樣的 DHT node 也下線了,所以 DHT 算法還規定:除了一模一樣的那個 DHT node 應該知道,ID 和這個哈希值非常接近的 N 個 DHT node 也應該知道。

什麼叫和哈希值接近呢?例如只修改了最後一位,就很接近;修改了倒數 2 位,也不遠;修改了倒數 3 位,也可以接受。總之,湊齊了規定的 N 這個數就行。

剛纔那個圖裏,文件 1 通過哈希運算,得到匹配 ID 的 DHT node 爲 node C,當然還會有其他的節點。所以,node C 有責任知道文件 1 的存放地址,雖然 node C 本身沒有存放文件 1。同理,文件 2 通過哈希運算,得到匹配 ID 的 DHT node 爲 node E,但是 node D 和 E 的 ID 值很近,所以 node D 也知道。當然,文件 2 本身沒有必要一定在 node D 和 E 裏,但是碰巧這裏就在 E 那有一份。

接下來一個新的節點 node new 上線了。如果想下載文件 1,它首先要加入 DHT 網絡,如何加入呢?

在這種模式下,種子.torrent 文件裏面就不再是 tracker 的地址了,而是一個 list 的 node 的地址,而所有這些 node 都是已經在 DHT 網絡裏面的。當然隨着時間的推移,很可能有退出的,有下線的,但是我們假設,不會所有的都聯繫不上,總有一個能聯繫上。node new 只要在種子裏面找到一個 DHT node,就加入了網絡。

node new 會計算文件 1 的哈希值,並根據這個哈希值瞭解到,和這個哈希值匹配,或者很接近的 node 上知道如何下載這個文件,例如計算出來的哈希值就是 node C。

但是 node new 不知道怎麼聯繫上 node C,因爲種子裏面的 node 列表裏面很可能沒有 node C,但是它可以問,DHT 網絡特別像一個社交網絡,node new 只有去它能聯繫上的 node 問,你們知道不知道 node C 的聯繫方式呀?

在 DHT 網絡中,每個 node 都保存了一定的聯繫方式,但是肯定沒有 node 的所有聯繫方式。DHT 網絡中,節點之間通過互相通信,也會交流聯繫方式,也會刪除聯繫方式。和人們的方式一樣,你有你的朋友圈,你的朋友有它的朋友圈,你們互相加微信,就互相認識了,過一段時間不聯繫,就刪除朋友關係。

有個理論是,社交網絡中,任何兩個人直接的距離不超過六度,也即你想聯繫比爾蓋茨,也就六個人就能夠聯繫到了。

所以,node new 想聯繫 node C,就去萬能的朋友圈去問,並且求轉發,朋友再問朋友,很快就能找到。如果找不到 C,也能找到和 C 的 ID 很像的節點,它們也知道如何下載文件 1。

在 node C 上,告訴 node new,下載文件 1,要去 B、D、 F,於是 node new 選擇和 node B 進行 peer 連接,開始下載,它一旦開始下載,自己本地也有文件 1 了,於是 node new 告訴 node C 以及和 node C 的 ID 很像的那些節點,我也有文件 1 了,可以加入那個文件擁有者列表了。

但是你會發現 node new 上沒有文件索引,但是根據哈希算法,一定會有某些文件的哈希值是和 node new 的 ID 匹配上的。在 DHT 網絡中,會有節點告訴它,你既然加入了咱們這個網絡,你也有責任知道某些文件的下載地址。

這兒引出兩個問題?

  • DHT網絡是如何維護這麼多node的?

  • DHT網絡是如何查找需要的node?具體的原理算法是什麼?

這些問題我會在下一篇文章中闡釋一下。請繼續關注。

小結

  • 傳統下載方式一般採用單一服務器方式,下載速度受到較大的制約。分佈式的下載方式解決了傳統下載方式的弊端。

  • 分佈式下載方式也有兩種:依賴tracker的“元數據集中,文件數據分散”的方式;另一種是基於分佈式的哈希算法,保證元數據和文件數據完全分開。

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