概述

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查找内容的剥离,为企业的分布式存储系统,另外配合区块链技术,通过链上链下协同技术,很容易地解决链上存储容量不足的问题。

©本文观点仅代表作者本人,绝不代表趣币网赞同其观点或证实其描述。文中部分文字/图片/视频/音频等来源于网络,如侵犯到著作权人的权利,请与我们联系(微信/QQ:1074760229)。本文不作为投资理财建议。转载请注明出处:趣币网

java ipfs文件存储_原来IPFS是这样存储文件的相关推荐

  1. java 海量文件存储_【直通BAT】海量数据面试总结

    出处:https://github.com/CyC2018 目录 海量数据计算总结 海量数据去重总结 1. 计算容量 在解决问题之前,要先计算一下海量数据需要占多大的容量.常见的单位换算如下: 1 b ...

  2. java大文件存储加密_Java IO--实现文件的加密解密

    我们知道文件存储的方式在计算机当中是以字节的方式进行存储的,可以通过对文件字节的操作来实现文件的加密. 下面的例子是通过读取文件的字节,然后使字节中的每一位取反(1变0,0变1),再进行倒置,来实现加 ...

  3. java压缩文件读取_用Java读取/写入压缩和非压缩文件

    java压缩文件读取 这篇文章的主要原因是尝试不要重复自己( DRY ),因为通常,我会遇到递归的需求,即读写压缩的和非压缩的文件(主要是JSON和CSV). 首先让我们看看如何读取文本文件. 注意我 ...

  4. java 大文件 处理_用Java处理大文件

    java 大文件 处理 我最近不得不处理一组包含历史逐笔交易的外汇市场数据的文件,并很快意识到使用传统的InputStream都无法将它们读取到内存中,因为每个文件的大小都超过4 GB. Emacs甚 ...

  5. java 扫描文件测试_适用于Java开发人员的微服务:安全测试和扫描

    java 扫描文件测试 1.简介 本教程的这一部分专门讨论安全性测试,将围绕被证明在软件开发领域(包括微服务 )中无价的测试策略进行总结. 尽管软件项目中的安全方面每天都变得越来越重要,但是令人惊讶的 ...

  6. java判断文件结束_关于java读取文件时,如何判断读取文件是否到达末尾?

    一.前言 java读取文件时,如果到达文件末尾,再进行读取时会发生异常,所以我们需要判断读取文件已经到达末尾.对于文件读取我们通常会采用不同的读取方式,如用InputStream流读取字节流.用Rea ...

  7. js清空本地存储_「IPFS红岸智能」js-IPFS 0.50.0性能再次提升

    原创:Alex Potsides 原文链接:https://blog.ipfs.io/2020-09-14-js-ipfs-0-50/ 由红岸智能编译 亮点 在多个选项卡和密码文件之间更快地共享IPF ...

  8. java 文件存储_文件存储学生信息(JavaIO流)

    package com; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStr ...

  9. java class 文件分析_大概优秀的java程序员都要会分析class文件吧

    相信大家在学java的时候都会听到这样的一些结论: enum 是一个类 泛型的实现使用了类型擦除技术 非静态内部类持有外部类的引用 需要将自由变量声明成final才能给匿名内部类访问 ... 初学的时 ...

最新文章

  1. 推荐搜索系统论文干货集锦
  2. 在T-SQL语句中访问远程数据库(openrowset/opendatasource/openquery)
  3. php组件化开发composer,PHP组件化开发 - JimmyJaw的个人空间 - OSCHINA - 中文开源技术交流社区...
  4. Java多线程闲聊(一):概论
  5. 某银行信用卡中心——大数据反欺诈应用案例 2017-06-23 10:54 本篇案例为数据猿推出的大型“金融大数据主题策划”活动(查看详情)第一部分的系列案例/征文;感谢 百融金服 的投递 作为整体
  6. C++11特性:override
  7. 柯洁获清华大学免试入学推荐资格
  8. php数组交集方法,PHP获得数组交集与差集的方法
  9. bootstrap ie兼容
  10. 欲走考研,难辞青衫,小园香径独徘徊。
  11. Borg Maze POJ - 3026 (BFS + 最小生成树)
  12. java 学生考勤系统(三、签到功能)
  13. 求三角形外接圆圆心坐标的算法
  14. 山东农业大学考研计算机专业分数,山东农业大学研究生分数线
  15. 我的完整版mbti职业性格测试
  16. Ember.js如何与后端服务交互?adapter、store、ember data关系揭秘 1
  17. flutter中的路由表和路由管理
  18. 我的世界基java版刷怪机制_我的世界1.8版本刷怪机制_我的世界代码1.8版本刷怪机制_快吧单机游戏...
  19. %d,%c,%s,%x各代表什么
  20. Cocos2D教程:使用SpriteBuilder和Cocos2D 3.x开发横版动作游戏——Part 2

热门文章

  1. R语言使用ggpubr包的ggarrange函数组合多张结论图:使用ggpubr包将表格嵌套在可视化图像中
  2. R语言plot函数可视化、ggplot2可视化把图像标题(title)的部分内容着色实战:标题的部分内容配置不同的色彩、副标题(subtitle)的内容配置不同的色彩
  3. R语言names函数获取或者设置数据对象名称实战
  4. Kaggle泰坦尼克号数据机器学习实战:从缺失值处理、数据探索性分析、组合特征生成到多模型构建
  5. python生成随机数—random模块
  6. 移动端图形化报表界面设计_B端移动设计 | 客户RFM分析
  7. 机器翻译之Facebook的CNN与Google的Attention
  8. 三代测序知识学习----Sequel
  9. Jupyter Notebook 使用流程
  10. 三十二、图的创建深度优先遍历(DFS)广度优先遍历(BFS)