IPFS分布式文件系统(教学)

什么是IPFS分布式文件系统?

IPFS是一个分布式文件系统,中文翻译为星际文件系统,名字听起来很酷炫很科幻。在IPFS这个文件系统中,文件被储存在由网络上很多节点所组成的IPFS系统。每一个文件都可以被计算出唯一的Hash值,其中透过DHT算法可以在众多的网络节点上进行定位,概念就像一大堆文件散布在一大堆节点中,取文件的时候透过DHT快速找到文件的位置进行存取。这样的机制其实已经有很成熟的实践,像是下载文件常用的BitTorrent,也是一样的工作原理。

在IPFS中,没办法保证传上去的文件永久都可以被取得,概念就跟BT种子死亡的意思一样,一旦整个网络没有了任何一个节点有这个文件的副本(Cache),那么你即使有了Hash也无法取得文件内容。为了解决这个问题,在区块链2017最大的ICO 项目Filecoin 就是透过数字货币奖励来供养这些提供Filecoin IPFS网络的节点,好让文件在分布式文件系统中可以被完整(永久!?)保存。虽然Filecoin底层使用了IPFS,但是Filecoin使用的DHT网络与IPFS公用网络是不同的,Filecoin未来有研究再分享了。

IPFS 使用教学

我们先看看怎么玩吧!从 https://dist.ipfs.io/#go-ipfs这里可以下载不同作业系统版本的IPFS主程式,这里测试的环境是Ubuntu 64,解压缩后直接安装,如下:

1
2
3
4
5
6
7
wget https://dist.ipfs.io/go-ipfs/v0.4.17/go-ipfs_v0.4.17_linux-amd64.tar.gz
tar -zxvf go-ipfs_v0.4.17_linux-amd64.tar.gz
cd go-ipfs
sudo ./install.sh
cd ..
rm go-ipfs_v0.4.17_linux-amd64.tar.gz
rm -rf go-ipfs

初始化IPFS

ipfs init

init 之后会在Home 建立一个.ipfs 目录,并且放置IPFS 相关文件与Cache,如下:

输入「ipfs id」可以显示IPFS Node 相关资讯,包含每一个Node 唯一的Peer ID,如下:

我们先尝试建立一个文件,透过ipfa add 放进IPFS 文件系统中(又是Hello World):

echo 'hello world!' > my-file.txt

ipfs add my-file.txt

执行ipfs add 后我们可以得到文件在IPFS 中的Object Hash,如上图「QmeV1kwh3333bsnT6YRfdCRrSgUPngKmAhhTa4RrqYPbKT」,这个File Hash 在IPFS 网络中是唯一的,而且绝对不会重复,如果重复,你可以再做一次(跟重开机的概念一样)。接下来我们可以透过ipfs cat 取得这个文件的内容,如下:

ipfs cat QmeV1kwh3333bsnT6YRfdCRrSgUPngKmAhhTa4RrqYPbKT

在没有连上IPFS 公用网络以前,文件就只是存在自己的cache 中,如果其他节点想要透过取得Hash 取得文件,是行不通的。要让其他节点取得内容,必须连先上IPFS网络,连上公用IPFS 命令如下:

ipfs daemon

启动后可以开启浏览器输入「http://localhost:5001」,点击左边的「Connections」可以出现一个很炫的介面,会显示整个银河系(星际)中所执行的节点,显示的当下有796个节点。如下:

我们到另一台IPFS Node,这是一个ARM Base 的环境,先透过tmux 开启两个画面,一个输入「ipfs daemon」连上DHT 网络,另一个用来操作。我们尝试在另一个节点透过IPFS 抓前面刚刚新增的文件,如下:

ipfs cat QmeV1kwh3333bsnT6YRfdCRrSgUPngKmAhhTa4RrqYPbKT

画面显示hello world! 文件内容,如下:

看起来IPFS 工作的还算顺利,没有遇到什么问题,这只是最基本的操作。

建立自己的私有IPFS 网络

在公用网络测试有时候会慢慢的,那要如何建立自己的私人DHT网络呢?要建立自己的IPFS网络必须要先产生一对密钥,我们可以透过ipfs-swarm-key-gen 这个程式来产生。安装方式如下:

先安装Go (以Ubuntu 为范例)

sudo apt-get install golang-go

export GOPATH=$HOME/golang

下载ipfs-swarm-key-gen

go get -u github.com/Kubuxu/go-ipfs-swarm-key-gen/ipfs-swarm-key-gen

产生Key

~/golang/bin/ipfs-swarm-key-gen > ~/.ipfs/swarm.key

然后复制swarm.key这个文件到其他要一起加入的节点,覆盖每个节点中的 ~/.ipfs/swarm.key文件,这样Daemon启动的时候才会使用这个key加入我们私有的IPFS网络。

在每一个节点中的~/.ipfs/config 文件里面,预设一开始描述的bootstrap 都是公有云的位置,由于我们是要建立自己的私有云,因此先透过以下命令清除bootstrap 设定:

ipfs bootstrap rm --all

这里我们有两个节点分别为A 与B,我们仅需要在A 节点加入B 节点的资讯即可。如下:

ipfs bootstrap add /ip4/192.168.20.246/tcp/4001/ipfs/QmNtXfQftbXjZm8BZNexn9N2Dwhrj2CiYHvcpdNXNDkoNj

一但连上IPFS网络,节点之间就会互相沟通,交互传递邻近的Peer 资讯,我们可以由以下的命令查询每个Node 的连线状态:

ipfs swarm peers

接下来的操作就跟平常连上IPFS 公网的方式一样啰。

透过pin 保留文件副本

各位有没有发现,IPFS 其实提供了一个分布式文件路由的机制,如果文件的源头断了,似乎也无法取得文件内容。各位可以试试把执行ipfs add 源头Node 关闭,然后在其他节点执行ipfs repo gc 删除Cache 中的文件,然后重新ipfs cat 试看看,就会发现取不到了,一旦重新打开文件源头的Node 就正常了。虽然分散,但是听起来不是很保险,那我们能不能在IPFS网络中建立文件副本呢?当然可以,如果要在自己的节点保留文件资料,不因为ipfs repo gc 被删除或文件来源无法连线造成文件无法取得,可以使用pin 指令将File Object 储存到磁碟中。

我们来测试一下,在Node A新增一支文件,透过ipfs add放上网络(使用ipfs add文件会自动Pinned),在同一个节点可以透过ipfs pin ls调阅目前的pin状态是recursive (说明)表示Pinned不会因为GC而被删除。如下:

接着我们在另一台Node B 尝试先ipfs cat 取得文件内容,然后输入ipfs pin ls 看看状态,这时候会发现文件没有被Pinned,如下:

如果这时候把Node A 关闭,Node B 在执行GC 后便无法取得文件内容。

但我们想要做的是在Node B 也保留副本,这样如果Node A 挂了,至少还有一份可以存取。要偷偷存一份很简单,透过ipfs pin add 指令即可,File Object Pinned 之后,即使Node A 关闭Node B GC,一样可以取得文件,因为文件已经储存在local storage 中啰。测试如下:

IPFS其实在搜寻与定位文件的时候不算快,组织一个自己独立的分布式文件系统还算简单。目前正在思考如何作到自动备援的问题,另一个火红的CEPH  Object Storage 是透过CRUSH Map 来实现文件副本的机制,但一样的机制如果用在时常变动且不稳定的IPFS Node架构我想也不适合。如果可以找到一个自动分派副本的方法,IPFS应该蛮方便的,另一个Filecoin就有针对文件的持久性做了改进(白皮书描述),IPFS其中还有mfs与IPNS没有介绍,今天就先介绍到这里,下次见。

本文链接地址:https://www.wwsww.cn/btbjiaoxue/6586.html
郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。

相关文章阅读