原來IPFS是這樣儲存檔案的

買賣虛擬貨幣
概述IPFS - InterPlanetary File System 星際檔案系統,是一個點對點的分散式檔案儲存系統,IPFS的願景是構建一個全世界的分散式網路,用來替代傳統中心化的伺服器模式,所有的IPFS節點組成一個分散式網路,每個節點都可以儲存檔案,使用者可以從IPFS構建的網路中以DHT(Distributed Hash Table,分散式雜湊表) 的方式獲取檔案,從而實現了新一代的完全去中心化的網路,旨在取代現有的全球資訊網。IPFS功能很豐富,包括DHT組網,檔案儲存,Bitswap檔案交換等功能。本文主要介紹IPFS的檔案儲存原理,檔案上傳到IPFS節點儲存時,節點會將檔案分塊後進行儲存,每個檔案以Merkle DAG(默克爾有向無環圖)的格式組織,而Merkle DAG的根雜湊則用來表示該檔案。本文將對IPFS儲存進行詳解,所述的IPFS的版本為v0.6.0。CID在介紹IPFS儲存檔案的遠離之前,先介紹一個重要的標識——CID(Content-ID),CID是IPFS中用來表示內容的標識,可以用來表示一個檔案,也可以用來表示一個檔案塊。如下所示,CID是一個字串,它主要由Version、Codec和Multihash三部分構成,Version目前分為v0和v1版本,v0版本的CID可以由V0Builder生成,v0版本的CID以Qm字串開頭,v1版本的CID可以由V1Builder生成,v1版本的CID主要包含三個部分Codec,MhType和MhLength,其中Codec是表示內容的編碼型別,例如DagProtobuf(即protobuf格式),DagCBOR(即cbor格式)等,MhType是雜湊演算法,例如SHA2_256(預設的雜湊演算法),SHA2_512,SHA3_256,SHA3_512等等,MhLength是生成雜湊的長度,預設用-1表示根據雜湊演算法確定長度。

IPFS元件介紹

IPFS用IpfsNode表示IPFS的節點,儲存相關元件的如下所示:

這些元件的關係如下圖所示,最上層是DAGService,它組合了BlockService元件,而BlockService組合了GCBlockstore元件,然後GCBlockstroe包含BaseBlocks和GCLocker兩個元件,最後BaseBlocks組合了最原始的blockstore元件。

接下來分別介紹這些元件的功能:

Pinning:固定CID的管理器,主要負責將檔案或者檔案塊(又叫Block)的CID固定,固定CID的塊不會被GC掉。上傳的檔案最後的檔案的CID都會被固定住,防止被GC。

Blockstore:GCBlockstore型別,組合Blockstore和GCLocker兩個元件。

BaseBlocks:原始的blockstore,提供了對Block的Get/Put/Has/DeleteBlock等操作。

GCLocker:用來鎖住blockstore,保護blockstore防止被GC影響。

Blocks:提供Block的服務,組合Blockstore元件,提供了GetBlock/GetBlocks、AddBlock/AddBlocks、DeleteBlock等操作。

DAG:IPFS的默克爾DAG的服務,組合BlockService元件,提供Get/GetMany,Add/AddMany,Remove/RemoveMany等操作。

檔案儲存流程

檔案上傳時將檔案新增到IPFS的倉庫中,上傳的流程可以如下圖所示,生成默克爾DAG的結構,生成的結構有兩種Layout:balanced和trickle的。這裡介紹預設的balanced結構,首先生成root作為根節點,然後將檔案分割,預設按照256KB大小讀取一個chunk,生成葉子節點,依次生成node1,node2,root節點會有Link指向掛在root節點的葉子節點node1和node2。root節點下面能夠Link的葉子節點數量是有限的,IPFS中預設設定的是174個(定義的Link的總的大小是8KB,每個Link的大小是34 + 8 + 5【sha256 multihash + size + no name + protobuf framing】,預設的Link的個數為8192/47約等於174)。

如下圖所示,超過174個後則會新建立一個new root節點,並Link到old root,新的chunk作為node3(這裡用node3簡約了,實際上是第175個節點)被new root直接Link。

當繼續有新的chunk新增時,則會生成node34作為node3和node4的父節點,node34含有兩個Link分別連結到node3和node4。

IPFS在init的時候會生成.ipfs目錄,如下圖所示,其中blocks則為檔案塊儲存的目錄,datastore為leveldb資料庫,其中儲存了檔案系統的根雜湊等,儲存相關的配置關聯在.ipfs目錄下面的config檔案。

經過上面的步驟,檔案已經切塊並轉化成Merkle DAG的結構,接下來詳細介紹每個塊是如何進行儲存的流程。

· 如下圖所示,一個Block儲存時,首先由dagService(實現了DAGService介面)呼叫Add進行新增;

· 之後由blockService(實現了BlockService介面)呼叫AddBlock新增該Block;

· 再呼叫arccache的Put,arccache是對儲存的Block做arc策略的快取;

· 再之後由VerifBS呼叫Put進行儲存,VerifyBS主要對CID的合法性進行校驗,合法則進行Put;

· 接著blockstore(實現了Blockstore介面)呼叫Put進行儲存,Put函式中會對CID進行轉化,呼叫dshelp的CidToDsKey方法將CID轉化成儲存的Key;

· 再接著呼叫keytransform.Datastore的Put,Put函式中會將字首拼上,這時Key加上了字首/blocks;

· 然後呼叫measure的Put函式,measure是對mount的封裝;

· 之後呼叫mount的Put函式,mount和IPFS的config配置檔案中結構對應,根據key去查詢對應的datastore,由於字首是/blocks則可以找到對應的measure;

· 呼叫該measure的Put函式;

· 最後呼叫flatfs的Put函式,由Put函式呼叫doPut最終呼叫encode函式將完整的block寫入的目錄指定為/home/test/.ipfs/blocks/WD,其中WD來自於blocks/CIQFSQATUBIEIFDECKTNGHOKPOEE7WUPM5NNNSJCCDROMM6YHEKTWDY中的倒數第三第二個字元。這樣該Block則寫入了該目錄下面的檔案中。

總結

IPFS檔案儲存格式為默克爾DAG格式,每一層Links大小為174個,超過了則會重新調整。檔案儲存過程中有多個Datastore進行了組合和封裝,每個Datastore功能比較單一,例如arccache只做Block的快取,VerifBS只做CID的校驗,這樣做的好處是每個元件功能明確,不好的地方在於組合太多,呼叫深度太深,加上內部都是用interface,好幾個元件都實現了該interface,不便於閱讀。

IPFS的儲存模式面向網際網路使用者而設計,因為它的開放性,允許所有節點隨意接入,已接入IPFS網路的節點可以自由查詢內容,不適合直接用來作為企業的檔案儲存服務。但其分散式儲存的特點,很容易進行儲存的動態擴容,可以透過結合節點認證機制和DHT查詢內容的剝離,為企業的分散式儲存系統,另外配合區塊鏈技術,透過鏈上鍊下協同技術,很容易地解決鏈上儲存容量不足的問題。

免責聲明:

  1. 本文版權歸原作者所有,僅代表作者本人觀點,不代表鏈報觀點或立場。
  2. 如發現文章、圖片等侵權行爲,侵權責任將由作者本人承擔。
  3. 鏈報僅提供相關項目信息,不構成任何投資建議

推荐阅读

;