ipfs filestore解讀

版本: [email protected]

IPFS中的filestore作用類似於Git中的LFS,主要用於存儲大文件,在blockstore只存儲大文件的dag root,在FileManager存放文件的metadata, 避免大文件充斥blockstore,節省blockstore的空間。

Git LFS

LFS全稱Large File System,是git用來存放大文件的地方。它有幾個優點:

1、在git倉庫只存儲了大文件的鏈接(主要存放文件的sha256),體積很小,方便clone和pull。

clone的時候只pull最新的版本,無需像其它object一樣保存所有歷史版本。

2、git diff基於文本行比較,而大文件大部分是二進制文件,diff不適用。

ipfs filestore

filestore結構體如下

// Filestore implements a Blockstore by combining a standard Blockstore
// to store regular blocks and a special Blockstore called
// FileManager to store blocks which data exists in an external file.
type Filestore struct {
	fm *FileManager
	bs blockstore.Blockstore
}

從代碼註釋可以看出,blockstore用於存儲普通文件(ipfs add file);FileManager用於存儲外部文件地址等信息(ipfs add file --nocopy)。

FileManager和git lfs都是直接管理磁盤上的文件(沒有額外的格式),不同的是,git lfs會copy文件,管理的是lfs倉庫中的文件,存有該文件的所有版本,可以管理版本;而FileManager不copy文件,管理的是源文件,無法管理版本。

FileManager和git lfs都會記錄源文件的metadata,git lfs主要記錄文件路徑(包含文件名)、文件大小及文件內容的哈希(sha256);FileManager主要記錄中key是文件CID的base32編碼,value是文件內容的哈希、路徑(包含文件名)、大小、偏移量(主要用於大文件分塊)和文件stat信息。

FileManager和git lfs雖然都記錄了源文件的metadata及其歷史版本信息,但是git lfs依賴git,可以管理版本(checkout),FileManager不行(只記錄所有歷史版本信息,沒有形成版本鏈條)。

// PosInfo stores information about the file offset, its path and
// stat.
type PosInfo struct {
	Offset   uint64
	FullPath string
	Stat     os.FileInfo // can be nil
}

// FilestoreNode is an ipld.Node which arries PosInfo with it
// allowing to map it directly to a filesystem object.
type FilestoreNode struct {
	ipld.Node
	PosInfo *PosInfo
}

實操

準備

1、修改ipfs config配置文件

  "Experimental": {
    "FilestoreEnabled": false,
    "UrlstoreEnabled": false,
  }

以上兩個功能默認是關閉的,均設置爲true。

2、add的時候添加–nocopy參數

ipfs filestore命令

$ ipfs filestore -h
USAGE
  ipfs filestore - Interact with filestore objects.

  ipfs filestore

SUBCOMMANDS
  ipfs filestore dups              - List blocks that are both in the filestore and standard block storage.
  ipfs filestore ls [<obj>]...     - List objects in filestore.
  ipfs filestore verify [<obj>]... - Verify objects in filestore.

  For more information about each command, use:
  'ipfs filestore <subcmd> --help'

現階段filestore有3個子命令:dups/ls/verify

add --nocopy

$ echo "Hello" > hello

$ ipfs add hello --nocopy
added bafkreidgubc3iuqqfrm5qqhmbf6vtwkgpyj2h42pmskokop72mwbxm27da hello

有兩點需要注意:
1、只能add文件,不能add字符串 2、add的文件的路徑必須位於ipfs root(默認是$home)底下,可以位於root的多級子目錄。

ipfs add時,ipfs使用FileManager保存文件信息的同時,也會通過dht向距離該文件CID最近的節點provide。

ipfs filestore ls

$ ipfs filestore ls
bafkreidgubc3iuqqfrm5qqhmbf6vtwkgpyj2h42pmskokop72mwbxm27da      6 Downloads/hello 0

ipfs filestore verify

$ ipfs filestore verify bafkreidgubc3iuqqfrm5qqhmbf6vtwkgpyj2h42pmskokop72mwbxm27da
ok      bafkreidgubc3iuqqfrm5qqhmbf6vtwkgpyj2h42pmskokop72mwbxm27da      6 Downloads/hello 0

ipfs cat

$ ipfs cat bafkreidgubc3iuqqfrm5qqhmbf6vtwkgpyj2h42pmskokop72mwbxm27da
Hello

最好在linux下ipfs cat,在windows不能直接ipfs cat,只能先get後cat。

由於ipfs1在add的時候已經provide,ipfs2也能cat,即通過bitswap找ipfs發送wantlist請求,獲取文件。

$ echo "Hello World!" > hello 
$ ipfs add hello --nocopy
added bafkreiadxiqe4ugre3sgotaalycnqlueyijwm6ak6h2dxvkkg6aww2vtia hello

$ ipfs filestore ls
bafkreidgubc3iuqqfrm5qqhmbf6vtwkgpyj2h42pmskokop72mwbxm27da      6 Downloads/hello 0
bafkreiadxiqe4ugre3sgotaalycnqlueyijwm6ak6h2dxvkkg6aww2vtia     13 Downloads/hello 0

$ ipfs filestore verify bafkreiadxiqe4ugre3sgotaalycnqlueyijwm6ak6h2dxvkkg6aww2vtia
ok      bafkreiadxiqe4ugre3sgotaalycnqlueyijwm6ak6h2dxvkkg6aww2vtia     13 Downloads/hello 0

$ ipfs filestore verify bafkreidgubc3iuqqfrm5qqhmbf6vtwkgpyj2h42pmskokop72mwbxm27da
changed bafkreidgubc3iuqqfrm5qqhmbf6vtwkgpyj2h42pmskokop72mwbxm27da      6 Downloads/hello 0

重新add --nocopy後,bafkreidgubc3iuqqfrm5qqhmbf6vtwkgpyj2h42pmskokop72mwbxm27da標註爲"changed",表明已被修改;bafkreiadxiqe4ugre3sgotaalycnqlueyijwm6ak6h2dxvkkg6aww2vtia標註爲"ok",表明是最新版本。

此時我們再ipfs cat下

$ ipfs cat bafkreidgubc3iuqqfrm5qqhmbf6vtwkgpyj2h42pmskokop72mwbxm27da
Error: data in file did not match. Downloads/hello offset 0

$ ipfs cat bafkreiadxiqe4ugre3sgotaalycnqlueyijwm6ak6h2dxvkkg6aww2vtia
Hello World!

果然,bafkreidgubc3iuqqfrm5qqhmbf6vtwkgpyj2h42pmskokop72mwbxm27da的內容已經無法獲取,bafkreiadxiqe4ugre3sgotaalycnqlueyijwm6ak6h2dxvkkg6aww2vtia的內容可以獲取。 因爲Downloads/hello源文件已經改變,無法得知舊版本的內容,只能獲取最新的內容。

有趣的測試

add 大文件(2.16MB)

$ ipfs add IMG_5152.JPG --nocopy
added QmaSDkQpknQeN1iM34SaV8eznkQuuvFHS33zigjCyGnrxa IMG_5152.JPG
 2.16 MiB / 2.16 MiB  100.00%

$ ipfs filestore ls
bafkreiaxtlgx2cligrkinkgq6374kd25q2hrbsessdxlzkxd7seh2mrqqq 262144 ipTest/IMG_5152.JPG 1835008
bafkreib5755rqduckwwysb3tkjdlhqt3slkqfkxx7dwihrhko6ezpqizq4 262144 ipTest/IMG_5152.JPG 786432
bafkreic3idfydr2s5wpblk5jmcqdm4d7hu5w3zat73vygswpmomlh37o74 262144 ipTest/IMG_5152.JPG 1310720
bafkreictqthw2fhcxvfwitz5xzjth2if7o534pje6zwfvb52ojv4tpzdw4 262144 ipTest/IMG_5152.JPG 1048576
bafkreiewb3z4zviruicvplcqmsnhqheue3lb44vm335vo4t2h3htz7b7l4 262144 ipTest/IMG_5152.JPG 524288
bafkreif3yikabcsik7wqodrpfeiwjzggbpgmii4kum7otchsnz3ri334zy 262144 ipTest/IMG_5152.JPG 0
bafkreiflbeifymhqb6il5t7kbmlrhtlxjeruztv5bujldrtcgfxksnktmq 262144 ipTest/IMG_5152.JPG 262144
bafkreigfn7y3au6ie4qfrs2njypwp5z52eske7m7bwvzozzqcsvubpmynm 171316 ipTest/IMG_5152.JPG 2097152
bafkreih6hyyn6w4swilsr3aibki4wzqbjqjgr2uxlhewaoodc3twaa4rsm 262144 ipTest/IMG_5152.JPG 1572864

add 目錄

$ mkdir test
$ cd test
$ echo "3" > 3
$ echo "4" > 4
$ cd ..
$ ipfs add test/ -r --nocopy
added bafkreiarehh4zvmrh4fgh7webjx72rhkmt45ye24mzruxiab2ef46qycui test/3
added bafkreid54fkv34gcoabst2avxe5tfrlrypvfjxewpoe6qgvxhomxfnzndu test/4
added QmcdtREQsVfNc3RatR2PwR7i3VuSeLfNND5vGXYNL1sgrx test
 4 B / 4 B  100.00%

可見,FileManager只存儲文件,目錄和大文件的dag root依然保存在blockstore中, 這些dag root記錄這目錄內的文件信息以及大文件的分塊信息。

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