概述
ipfs - interplanetary file system 星际文件系统,是一个点对点的分布式文件存储系统,ipfs的愿景是构建一个全世界的分布式网络,用来替代传统中心化的服务器模式,所有的ipfs节点组成一个分布式网络,每个节点都可以存储文件,用户可以从ipfs构建的网络中以dht(distributed hash table,分布式哈希表) 的方式获取文件,从而实现了新一代的完全去中心化的网络,旨在取代现有的万维网。ipfs功能很丰富,包括dht组网,文件存储,bitswap文件交换等功能。本文主要介绍ipfs的文件存储原理,文件上传到ipfs节点存储时,节点会将文件分块后进行存储,每个文件以merkle dag(默克尔有向无环图)的格式组织,而merkle dag的根哈希则用来表示该文件。本文将对ipfs存储进行详解,所述的ipfs的版本为v0.6.0。
cid
在介绍ipfs存储文件的远离之前,先介绍一个重要的标识——cid(content-id),cid是ipfs中用来表示内容的标识,可以用来表示一个文件,也可以用来表示一个文件块。如下所示,cid是一个字符串,它主要由version、codec和multihash三部分构成,version目前分为v0和v1版本,v0版本的cid可以由v0builder生成,v0版本的cid以qm字符串开头,v1版本的cid可以由v1builder生成,v1版本的cid主要包含三个部分codec,mhtype和mhlength,其中codec是表示内容的编码类型,例如dagprotobuf(即protobuf格式),dagcbor(即cbor格式)等,mhtype是哈希算法,例如sha2_256(默认的哈希算法),sha2_512,sha3_256,sha3_512等等,mhlength是生成哈希的长度,默认用-1表示根据哈希算法确定长度。
ipfs组件介绍
ipfs用ipfsnode表示ipfs的节点,存储相关组件的如下所示:
这些组件的关系如下图所示,最上层是dagservice,它组合了blockservice组件,而blockservice组合了gcblockstore组件,然后gcblockstroe包含baseblocks和gclocker两个组件,最后baseblocks组合了最原始的blockstore组件。
接下来分别介绍这些组件的功能:
pinning:固定cid的管理器,主要负责将文件或者文件块(又叫block)的cid固定,固定cid的块不会被gc掉。上传的文件最后的文件的cid都会被固定住,防止被gc。
blockstore:gcblockstore类型,组合blockstore和gclocker两个组件。
baseblocks:原始的blockstore,提供了对block的get/put/has/deleteblock等操作。
gclocker:用来锁住blockstore,保护blockstore防止被gc影响。
blocks:提供block的服务,组合blockstore组件,提供了getblock/getblocks、addblock/addblocks、deleteblock等操作。
dag:ipfs的默克尔dag的服务,组合blockservice组件,提供get/getmany,add/addmany,remove/removemany等操作。
文件存储流程
文件上传时将文件添加到ipfs的仓库中,上传的流程可以如下图所示,生成默克尔dag的结构,生成的结构有两种layout:balanced和trickle的。这里介绍默认的balanced结构,首先生成root作为根节点,然后将文件分割,默认按照256kb大小读取一个chunk,生成叶子节点,依次生成node1,node2,root节点会有link指向挂在root节点的叶子节点node1和node2。root节点下面能够link的叶子节点数量是有限的,ipfs中默认设置的是174个(定义的link的总的大小是8kb,每个link的大小是34 + 8 + 5【sha256 multihash + size + no name + protobuf framing】,默认的link的个数为8192/47约等于174)。
如下图所示,超过174个后则会新创建一个new root节点,并link到old root,新的chunk作为node3(这里用node3简约了,实际上是第175个节点)被new root直接link。
当继续有新的chunk添加时,则会生成node34作为node3和node4的父节点,node34含有两个link分别链接到node3和node4。
ipfs在init的时候会生成.ipfs目录,如下图所示,其中blocks则为文件块存储的目录,datastore为leveldb数据库,其中存储了文件系统的根哈希等,存储相关的配置关联在.ipfs目录下面的config文件。
经过上面的步骤,文件已经切块并转化成merkle dag的结构,接下来详细介绍每个块是如何进行存储的流程。
如下图所示,一个block存储时,首先由dagservice(实现了dagservice接口)调用add进行添加;
之后由blockservice(实现了blockservice接口)调用addblock添加该block;
再调用arccache的put,arccache是对存储的block做arc策略的缓存;
再之后由verifbs调用put进行存储,verifybs主要对cid的合法性进行校验,合法则进行put;
接着blockstore(实现了blockstore接口)调用put进行存储,put函数中会对cid进行转化,调用dshelp的cidtodskey方法将cid转化成存储的key;
再接着调用keytransform.datastore的put,put函数中会将前缀拼上,这时key加上了前缀/blocks;
然后调用measure的put函数,measure是对mount的封装;
之后调用mount的put函数,mount和ipfs的config配置文件中结构对应,根据key去查找对应的datastore,由于前缀是/blocks则可以找到对应的measure;
调用该measure的put函数;
最后调用flatfs的put函数,由put函数调用doput最终调用encode函数将完整的block写入的目录指定为/home/test/.ipfs/blocks/wd,其中wd来自于blocks/ciqfsqatubieifdecktnghokpoee7wupm5nnnsjccdromm6yhektwdy中的倒数第三第二个字符。这样该block则写入了该目录下面的文件中。
总结
ipfs文件存储格式为默克尔dag格式,每一层links大小为174个,超过了则会重新调整。文件存储过程中有多个datastore进行了组合和封装,每个datastore功能比较单一,例如arccache只做block的缓存,verifbs只做cid的校验,这样做的好处是每个组件功能明确,不好的地方在于组合太多,调用深度太深,加上内部都是用interface,好几个组件都实现了该interface,不便于阅读。
ipfs的存储模式面向互联网用户而设计,因为它的开放性,允许所有节点随意接入,已接入ipfs网络的节点可以自由查找内容,不适合直接用来作为企业的文件存储服务。但其分布式存储的特点,很容易进行存储的动态扩容,可以通过结合节点认证机制和dht查找内容的剥离,为企业的分布式存储系统,另外配合区块链技术,通过链上链下协同技术,很容易地解决链上存储容量不足的问题。
oppor11什么时候上市?oppor11最新消息:oppor11系列或2999元起售,规格配置全面曝光
4G移动通信技术的特点功能及在消防现场应急通信中的应用
人工智能可诊断前六年预测阿尔茨海默氏病
煤矿矿井基于IP/SIP应急广播通信对讲解决方案
两种典型放大器电路图分享
IPFS存储文件的方法
香侬科技李纪为解读人工智能从技术创业走到商业化的创业感受
纵目科技与江淮汽车在ADAS领域进行更深入的合作
模块电源的散热应对措施
工业物联网的边缘节点安全性
透露世界首款K波段数据转换器EV12DS460A背后的设计秘密
内置DAC和支持30V GPIO的低功耗MCU DT5M0B35介绍
涉案财物管理系统-物证管理系统
美信血糖仪参考设计
138W的移动电源也能上飞机? 大容量移动电源SuperTank大揭秘!
AI占据榜首位置 成为2019年最受网友关注的科技热词
雷军微博晒小仙女自拍灯 内置9颗LED灯珠
SK电讯与诺基亚、爱立信达成协议 与三星争相布局6G
Home键生命力顽强!传新iPad将取消但依然能用?
智能机器人视觉传感器的技术原理