以下內容調研截止到2021/11/5日
- IPFS簡介
IPFS是一種內容可尋址、點對點、分布式文件系統。IPFS采用內容-地址尋址技術,即通過文件內容進行檢索而不是通過文件的網絡地址。簡單來說,就是對文件內容進行hash運算,將hash值作為文件名保存在本地數據庫中,所以,只要文件內容不變,則文件名也保持不變。
- IPFS文件存儲形式
多個運行IPFS程序的節點構成IPFS存儲網絡,存儲在IPFS網絡中的數據被划分成多個塊,存放在不同節點中。當節點請求網絡中的數據時,會在節點本地緩存該文件。即每個節點都保存其下載過的文件的緩存,用來保證即使某一個存有該資源的節點推出IPFS網絡,該資源仍然可以被其他節點訪問。當用戶把文件上傳到IPFS節點存儲時,節點會將文件分塊后進行存儲,每個文件塊以Merkle有向無環圖(如圖1所示)的形式組織,而Merkle有向無環圖的根哈希則用來表示該文件。同時采用分布式Hash表(如圖2所示)實現通過hash值到文件內容的定位。
本地表中存儲文件的K/V值。正如我們在前面所提到的,每個文件在保存到 IPFS 網絡中都可能進行分片,即把大的文件分成小的碎片,每個碎片有自己的哈希,根據碎片的哈希生成對應的 Link,以碎片在文件中出現的順序,使用這些 Link 生成連接數組,使用連接數組生成最終的頂層 Object 對象,以此來表示文件。每一個分塊都可以作為Object對象進行訪問。
圖1 Merkle有向無環圖
圖2 IPFS存儲對象數據結構
圖3 分布式hash表
當存儲小文件時,會直接將該文件存到DHT(分布式hash表)上。存儲大文件時,會存儲文件的根hash和對應節點的ID。DHT中存儲三種類型的記錄。
- 內容標識(用戶正在尋找的內容CID)到節點標識的映射
- 節點標識到節點地址的映射
- ipns名稱到ipns指針的映射
圖4 K桶
如果一個節點的ID,前面所有位數相同,從倒數第n位開始不同,這樣的節點只有2(i-1)個,與基礎節點的距離范圍為[2(i-1), 2i);對於0000110而言,這樣的節點歸為“k-bucket i”;
圖5 M節點維護的路由表
Kademlia協議對每個桶內維護的節點數設置了一個上限,一旦桶內節點數超過,便根據一定的淘汰算法進行更新,一般上限設置為20。
搜索時間復雜度為O(log2n),n是指網絡的規模。
當節點查到文件根hash時,同時也拿到了link數組,發起廣播,詢問誰有數組中的hash塊,請發給我。
(1)新節點加入情況:
當有新節點N加入時,需要通過訪問網絡中的任一節點S ,以S作為中介加入網絡,具體來說:
- 將S加入本地路由表,成為N的種子節點;
- N向S發起一次節點查詢請求,查詢的目的節點其實是自身;該請求的目的有二:第一告訴S新增了節點N,第二通過S發現集群中更多的節點。而發起了指向自身的查詢請求也很有意思:其一是因為N此時還不知道系統更多的節點信息;其二是通過這種方式N可以快速地找到更多距離自己更接近的節點。
- S收到N的查詢目標節點請求,首先將節點N加入自身的路由表中,然后給 N最多返回K個距離N更接近的節點信息;
- N收到S的響應,將響應中的節點加入自身路由表,然后對這些節點分別發起查詢請求,當然,查詢的目標還是自身。
- 最后,節點N在更新路由表的過程中,主動存儲文件Hash值距離自己比訪問節點更近的數據文件。
(2)節點離線:
節點離線在Kademlia協議中無需做特殊處理,如果某個節點離線,那么其離線事件最終會反饋到網絡節點的路由表中,將其從路由表中剔除即可。
(3)數據冗余存儲:
並不能保證在任一時刻目標節點N均一定存在或者在線,因此Kad網絡規定:任一條目,依據其key的具體取值,該條目將被復制並存放在節點ID距離key值最近(即當前距離目標節點N最近)的k個節點當中;之所以要將重復保存k份,這完全是考慮到整個Kad系統穩定性而引入的冗余;
- 基於IPFS的文件下載方式
運行IPFS的節點,既是客戶端又是服務器。客戶端通過發送文件名到服務器,請求下載文件,服務器會根據文件名到分布式Hash表中查找對應的文件,查找成功后將文件發送給客戶端,當文件下載完成后,客戶端通過對文件內容進行hash運算,將hash值和文件名作比較就可以確定文件的完整性。
IPFS采用Kademlia協議實現節點路由及內容查詢。當查詢一個內容時,先計算hash值,再將該hash值與節點ID進行異或,得到距離,根據距離去對應的K桶中查找,若查找不到,詢問誰是距離最近的節點,得到最近的節點,在該節點上再次執行該算法,直到找到對應節點。
找到對應節點后,再次查詢該DHT表,找到該節點對應的ip地址等信息定位到該節點,再查詢該節點的本地數據庫,得到要查找的文件內容。
- 基於IPFS的EOS存儲模塊
通過在GitHub網站中EOS倉庫中提問得出EOS並未實現基於IPFS的存儲。以下內容摘自EOS存儲白皮書及網上博客資料。
EOS存儲的核心是IPFS,它提供了一個任何人都可以托管文件的去中心化網絡,這些文件可以通過地址遠程訪問。區塊生產者實際代表了21個超級節點,每個超級節點需要擁有支持高吞吐EOS交易量的數據中心,可以在全球范圍提供文件托管服務,而且只要有至少一個超級節點在線,用戶的文件就是可以訪問的。
EOS設計了一套文件系統智能合約,發行了一種 token 叫TOK。它允許每個EOS客戶端可以定義一個本地home目錄,用於存放IPFS文件鏈接。鏈接內容主要包括本地home目錄路徑、文件名(文件內容的hash值)、文件大小。
圖6 目錄結構
用戶上傳文件時,將文件鏈接打包成交易信息,簽名后廣播給區塊生產者,然后用戶通過EOS存儲軟件定義的標准化REST應用程序接口將文件上傳到其中一個區塊生產者。區塊生產者會驗證文件和文件名匹配,然后將交易廣播發送到整個區塊鏈系統,其他的區塊生產會通過IPFS網絡復制那個文件。這樣用戶就成功的上傳了一個文件,同時在的home目錄下保存了該文件的鏈接。和使用EOS資源類似,當用戶需要存東西的時候,系統就會鎖定一部分的TOK,當然如果用戶不需要存東西了,系統就會解鎖TOK。
圖7 上傳流程
文件上傳成功后,當客戶端需要下載文件時,只需要將文件名發給生產者服務器,然后,服務器通過IPFS檢索到對應的文件發送給客戶端即可。一般來說,IPFS文件系統中的文件都是只讀的,因為文件內容的細微修改就會導致客戶端校驗失敗。
- 長安鏈采用的鏈下數據存儲方案
長安鏈暫未使用IPFS進行存儲。長安鏈現已實現使用LevelDB、RocksDB、MySQL進行存儲。同時長安鏈會將區塊的歷史數據歸檔在鏈下數據庫中進行存儲,采用MySQL數據庫進行存儲,存儲狀態數據和非狀態數據。
- 狀態數據,僅存儲最新的數據快照,無歷史版本。
- 非狀態數據,如:區塊、交易、歷史讀寫集。
長安鏈采用MySQL數據庫實現鏈下存儲,IPFS存儲格式后續會進行支持。
- 長安鏈IPFS使用方式
長安鏈暫時還沒有實現基於IPFS的存儲系統,但長安鏈采用了基於IPFS的組網方式。
長安鏈基於IPFS提供的DHT,實現TLS的證書認證服務。
長安鏈支持自動發現、自動連接的組網方式,默認在線的每個節點都可以作為種子節點為其他節點提供網絡發現服務,每個種子節點都會記錄網內節點地址信息。當有新節點連接到某個種子節點時,新節點會向該種子節點查詢網內其他可連接節點的地址,拿到其他節點地址后,新節點會主動嘗試與這些節點建立連接;另外,種子節點在接受了新節點鏈接后,會通過網絡發現服務將該新節點的地址通知給其他在線的種子節點,其他節點在獲得該新節點地址后,也會主動嘗試與該新節點建立連接。
- 采用IPFS存儲的代表性區塊鏈
EOS、Filecoin(github上點贊數1.9K)等。
- IPFS與MySQL擴容方案對比
IPFS是一個對標HTTP協議的內容尋址協議,底層采用leveldb作為數據庫。
若采用MySQL實現存儲量彈性擴展,首先是查詢性能較K/V數據庫較低,二是SQL語句過於靈活,難以控制。
- IPFS存儲優勢
- 存儲負載均衡
- 分布式存儲,去中心化,P2P通信
- 文件分塊存儲,解決重復存儲問題
HDFS:中心化、距離的度量是物理距離。一個HDFS集群是由一個NameNode和若干個DataNode組成的。其中NameNode作為主服務器,管理文件系統的命名空間和客戶端對文件的訪問操作;集群中的DataNode管理存儲的數據。