版本: 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记录这目录内的文件信息以及大文件的分块信息。
来源:CSDN
作者:zhongdahong
链接:https://blog.csdn.net/zhongdahong/article/details/104605525