简介

我们知道,一个存储服务,最基本的功能就是存和取。IPFS 中提供了这两种语义,那就是 add 和 get 操作。
在 IPFS 系统中执行 add 操作,就是执行了一次存操作,放在网络的概念里,就是“上传”操作。而 get 就更好理解了,就是取操作,在网络世界里,也叫 “下载”。

IPFS 号称点对点无中心化文件系统,没有单点故障,也就是文件一旦被“上传”到 IPFS 网络中,就会被永久保存。而要想下载一个本地没有的文件,只要 IPFS 网络中有,简单的执行 get 就很快能下载到数据。那么 add 操作的背后到底做了什么?get 又是怎么获取数据的?

这就是本文要探究的主题!

先来看一下 add 和 get 的基本操作过程

 
 

当一个 IPFS 节点执行 add 操作时,它会把文件进行分块 block,通过构建一个 Merkle 树根节点,来把每个子块节点都连接起来,每个 block 都会用一个唯一的 Cid 进行标识。

block 数据会被保存到本地的 blockstore 中。但是需要注意的是,除此之外,block 数据并不会立刻主动上传到 IPFS 网络中(也即,与其连接的 peers 节点中)。除非,某 peer 节点曾经请求过该 block 数据。

add 执行逻辑如下图所示:

 
 

理解这一点非常重要,因为,我们很容易会把 IPFS 想象成一个会自动备份数据的分布式数据库,就像传统的冗余备份机制一样。实际上,IPFS 并不会这样做。这是由 IPFS 在公网环境中运行和传统分布式数据库在私有网络中运行的场景要求不一样所导致的。作为互联网基础设施,这种设计不仅减少网络带宽占用,还能为网络提供可靠、恒久的数据保存机制。

现在就来来了解一下 get 操作背后的原理,先看下图:

 
 

上图展示了 ipfs 执行 get 命令的执行流程。

对于当前节点来说,所有与其连接的 peers 节点会构成一个 swarm 网络。

当本地节点发出一个 get 请求时,它首先会从本地的 blockstore 中查找请求的数据,如果没有找到,它便会向 swarm 网络发出请求,通过 DHT Routing 找到拥有该数据的节点,一旦找到一个拥有所请求数据的节点,该节点会把数据反馈回来。然后,本地节点会把收到的 block 数据缓存一份到本地的 blockstore 中,这样,整个网络中就相当于多了一份原数据的拷贝。当有更多的节点都请求该数据的时候,就变得更加容易,而由于越来越多的节点都存有该数据,数据就变得几乎不可丢失。

这也就是 IPFS 网络能够永久保存数据的原理,只要有任何一个 IPFS 节点拥有某数据,这个数据就可以被全网所获取。

那么,执行 IPFS 的 add 命令之后,为什么直接访问 ipfs.io 网关就能获取到数据呢?

比如,在浏览器中打开类似 https://ipfs.io/ipfs/QmR4WZy1rfXX868yFsTcqHun5y61c1jh2oQhDqWD97FEM2 这样的网站地址,就能直接访问到刚才我们添加的数据!

原理是这样的:

IPFS 网关,即 ipfs.io,实际上扮演的是一个 IPFS 节点的作用,当我们打开上述网站的时候,其实就是向 IPFS 网关发出了一次请求,IPFS 网关会代理我们(因为我们不是 IPFS 节点,我们只是浏览器而已)向拥有这个数据的 Peer 节点(就是我们本地节点)发出 get 请求,一旦获取到数据,网关会先自己缓存一份,然后把请求到的数据通过 HTTP 协议转发给我们!

也就是说,任何一台机器,只要打开浏览器,都能通过上述地址访问到我们刚才执行 add 命令时添加的数据。一旦 IPFS 网关第一次缓存节点数据之后,再次请求时,它就无需再向原节点请求数据了,只要 Hash 值没有变化,就可以直接把之前缓存的数据返回给浏览器。

 
 

当然,这个缓存的数据是有时效的,通常是一周左右就会失效。这个是由 ipfs daemon 内置的默认时效所设定。因为作为网关节点,其磁盘容量也是有限的,不可能无限保存所有的数据,采用缓存时效机制不仅能解决资源访问问题,还能避免数据膨胀给节点带了的负担,当越来越多的机器加入 IPFS 网络并且承担网关的作用,那么数据时效的概率就会大大降低。

更多细节

实际上,Peer 节点在执行 add 命令时,还会广播自己拥有的块信息。同时,它还会维护一个该 swarm 网络中所有已发给当前节点的 block 请求列表,一旦 add 命令都添加的数据满足请求列表,就会向对应节点主动发送数据,并更新该列表。

IPFS 到底是怎么工作的?的更多相关文章

  1. 那么 Appium 到底是怎么工作的呢?

    因为官网文档写的没有梯度,作为新手的我花了好几个小时硬是没看明白它是怎么工作的. 网上教程也基本都是翻译,所以结构很复杂.和其他技术耦合度很高,且没有说明. 我自己总结了一份超简单 Appium 自动 ...

  2. 有一部分程序员还不知道Java 中的注解到底是如何工作的?

    作者:人晓 自Java5.0版本引入注解之后,它就成为了Java平台中非常重要的一部分.开发过程中,我们也时常在应用代码中会看到诸如@Override,@Deprecated这样的注解. 这篇文章中, ...

  3. Java中的注解到底是如何工作的?

    作者:人晓 www.importnew.com/10294.html 自Java5.0版本引入注解之后,它就成为了Java平台中非常重要的一部分.开发过程中,我们也时常在应用代码中会看到诸如@Over ...

  4. SendMessage到底是如何工作的?

    以下内容摘自<<Windows核心编程>>: 概要: SendMessage对于在同一个线程中调用的话,直接调用的是当前线程所属窗口的窗口过程函数(WndProc);如果是跨线 ...

  5. python3多线程应用详解(第二卷:多线程到底是怎么工作的)

    现在很多人都说用多线程工作快是因为多个不同任务可以同时执行,注意我说的是不同任务,要是重复做一件事达到相同效果就是画蛇添足了,其实这是个错误的说法,线程真正的本质是无法同时执行的.现在我们来看下多线程 ...

  6. IPFS如何挖矿<Filecoin系统>?(一)

    本来这篇文章应该晚一点写, 但是这几天一直有朋友在公众号留言, 迫切的想知道IPFS到底如何挖矿, 所以就提前写一篇关于IPFS挖矿的文章. 本文暂不涉及具体的技术细节, 只做大概的介绍. 首先, 好 ...

  7. (转)完全用GNU/Linux工作 by 王珢

    完全用GNU/Linux工作 王珢      (看完这篇博文,非常喜欢王珢的这篇博客,也我坚定了学gnu/linux的决心,并努力去按照国外的计算机思维模式去学习编程提高自己.看完这篇文章令我热血沸腾 ...

  8. PHP底层工作原理

    最近搭建服务器,突然感觉lamp之间到底是怎么工作的,或者是怎么联系起来?平时只是写程序,重来没有思考过他们之间的工作原理: PHP底层工作原理 图1 php结构 从图上可以看出,php从下到上是一个 ...

  9. 【转】Android开发实践:自定义带消息循环(Looper)的工作线程

    http://ticktick.blog.51cto.com/823160/1565272 上一篇文章提到了Android系统的UI线程是一种带消息循环(Looper)机制的线程,同时Android也 ...

随机推荐

  1. 【ZJOI2016】大♂森林

    题目描述 小Y家里有一个大森林,里面有 $n$ 棵树,编号从 $1$ 到 $n$ .一开始这些树都只是树苗,只有一个节点,标号为 $1$ .这些树都有一个特殊的节点,我们称之为生长节点,这些节点有生长 ...

  2. Ubuntu 16.04下使用Wine安装Xshell 4和Xftp 4

    说明: 1.使用的Wine版本是深度出品(Deepin),已经精简了很多没用的配置,使启动能非常快,占用资源小. 2.由于Xshell 5的C++库无法在这个Wine版本运行,即使升级官方原版的2+版 ...

  3. UPLINK口

    为什么我买的交换机没有UPLINK口? UPLINK端口的作用是为了解决网络设备互连时的网线(交叉线和直通线)的使用问题.现在新出的交换机有的是没有UPLINK口的,没有UPLINK口的交换机的每个端 ...

  4. 2008 SQL SERVER 用户 架构

    2008 SQL SERVER 用户: SERVER用户与数据库用户 SERVER 与 数据库用户的映射,以使 登陆用户可访问数据库 架构等同于SCHEM (表空间),即表空间管理对象,建立层次对象关 ...

  5. 【grpc】spring boot+grpc的使用

    spring boot+grpc的使用 参考:https://baijiahao.baidu.com/s?id=1573961922096412&wfr=spider&for=pc

  6. Win7下Nginx的安装与配置

    1.  下载nginx1.9.9版本:(版本随时间而变,下载最新即可) http://nginx.org/download/nginx-1.9.9.zip 2. 解压软件到对应位置,并重命名文件夹为n ...

  7. C++ 用libcurl库进行http通讯网络编程 【转】

    http://www.cnblogs.com/moodlxs/archive/2012/10/15/2724318.html C++ 用libcurl库进行http通讯网络编程 目录索引: 一.Lib ...

  8. Unity3D:Gizmos画圆(原创)

    Unity3D引擎技术交流QQ群:[21568554] Gizmos是场景视图里的一个可视化调试工具. 在做项目过程中.我们常常会用到它,比如:绘制一条射线等. Unity3D 4.2版本号截至.眼下 ...

  9. hihocoder 1032 manachar 求回文串O(n)

    #include <cstdio> #include <iostream> #include <algorithm> #include <queue> ...

  10. mac os PHP 访问MSSQL

    写在前: 项目的数据库是sql server,但是自己的系统是mac os.这样导致了需要一个烦人的系统环境搭建过程.目前要在mac 上的php环境中支持mssql环境访问,经过自己了解,有两种方式: ...