ipfs filestore

≯℡__Kan透↙ 提交于 2020-03-02 11:11:04

版本: go-ipfs@v0.4.23

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记录这目录内的文件信息以及大文件的分块信息。

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!