整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

HTTP PK IPFS:一个中心,还是多个中心?

HTTP PK IPFS:一个中心,还是多个中心?

言:一种新技术的诞生,总会面临着不同境况:有狂热的信仰者追捧,有沉稳的中立者观望,也有顽固的保守者评判,犹如达尔文的《物种起源》。

(一)前世——HTTP:拉开网络信息时代的序幕,独领风骚二十年

1991年8月6日,蒂姆·伯纳斯·李在位于欧洲粒子物理研究所(CERN)的NeXT计算机上,正式运行世界上第一个Web网站(http://info.cern.ch ),建立起基本的互联网基础概念和技术体系,由此开启了网络信息时代的序幕。

1991年,HTTP/0.9版首次登上历史的舞台,版本极其简单,只有一个命令GET。基于协议规定:服务器只能回应HTML格式的字符串,不能回应别的格式,服务器发送完毕,就关闭TCP连接。现在看来,是多么的简陋单一,然而就是这一小小的变化,却敲开一扇尘封已久的大门。

1996年5月,HTTP/1.0 版本发布,别看只是0.9与1.0数字上细微只差,但却是一个分水岭,为HTTP的后续发展提供了强劲的动力。

首先HTTP扩大了传输内容的类别,并非仅仅局限于文字,图片、二进制文件、视频等均囊括于内,这为互联网的后续爆发奠定了基础。其次,除了GET命令,还引入POST命令和HEAD命令,丰富了浏览器与服务器的互动手段,让HTTP请求和回应的格式也有些改变。最后,也新增了一些的功能以此更好去服务互联网。

技术一直在迭代更新,只为需求最优的方案。半年后,HTTP/1.1 版本发布,HTTP/1.1进一步完善了 HTTP/1.0 协议,它引入持久连接(persistent connection)和管道机制(pipelining),改进了HTTP协议的效率,但却存在着“对头堵塞”的问题。即便如此,HTTP/1.1一直用到了20十多年后的今天,直到现在还是最流行的版本之一。

2009年,谷歌公开了自行研发的 SPDY 协议,主要解决 HTTP/1.1 效率不高的问题。基于这个协议在Chrome浏览器上证明可行后,便被当作 HTTP/2 的基础。2015年,HTTP/2 发布,它不叫 HTTP/2.0,是因为标准委员会不打算再发布子版本,下一个新版本将是 HTTP/3,这也许意味一个时代的终结。

历史告我们,一个英雄倒下了,下一个英雄崛起,开启着属于他的辉煌。

(二)今生——IPFS:极简主义的布道者,后起之秀可争雄

2014年5月,一个叫Juan Benet墨西哥的小哥与他的几个斯坦福大学同学一起发明了IPFS。IPFS 的发明者Juan Benet是一位墨西哥移民也是一个传奇人物,毕业于斯坦福大学的计算机科学专业。之前创立的一家公司在 2013 年被雅虎收购 ,随后,他在Y Combinator 项目中成立了 Protocol Labs。

Protocal Labs刚一创立就加入美国硅谷顶级孵化器Y-Combinator,IPFS是他们做的第一个产品。Protocol Labs在创建IPFS的时候给它取名为“Inter Planetary File System(星际文件传输)”。对于这一点,Protocol Labs希望构建一个点对点的分布式文件系统,通过底层协议,让全世界所有人都能够轻松从IPFS系统上提取文件,且不受防火墙的影响。

愿景很美好,但每一条看似光鲜亮丽的道路上是荆棘遍地。IPFS主张将大文件分别存放于不同的块中,但同时存在着一个隐患,即:如果一部分存放文件的节点统统下线不可用了,并且该文件没有备份,那么整个文件都是不可用的。

简而言之,就是需要激励更多人去存储信息和分发文件。此刻,Filecoin顺势而生,作为IPFS的激励层,也可认为是IPFS网络上的通证。Filecoin共发行20亿枚,并在2017年7月进行代币私募,8月进行了通证众筹,融资超过2.5亿美元。这意味着IPFS尚未正式启动,市场价值已达到25亿美元,其魅力可见一斑!

2018年1月2日,IPFS官方网站发布:自融资完成以来,IPFS一直致力于将Filecoin的巨大潜力变为现实 - 从Filecoin的实施到执行协议的核心再到招募最优秀的人才来发展团队。直到现在,IPFS依然像一个典型的理工男一样默默深耕技术,或许正因为这份坚毅的执著和近似苛刻的严谨,才会让IPFS走得更远,真正将梦想照进现实。

他们还在为曾经的理想书写着未来,默默地砥砺前行,离成功只差临门一脚。

(三)技术间的博弈源于:是一个中心,还是多个中心?

其实一开始,Web的本意是去中心化,但它却变得越来越中心化,今天越来越多的人依靠的是少数网站的服务。HTTP变成了一个脆弱的、高度集中的、无效的、过度依赖于骨干网的协议,像美国国家安全局这样的组织,现在只需要在几个点上拦截通信来进行监视。对政府来说,阻止网站访问这些高度集中化的资源变得容易,这也使通信容易遭受DDoS攻击而面临巨大的风险。

反观IPFS,它不需要每个节点存储所有发布到IPFS上的内容。相反,每个节点只存储自己想要的数据。如果每个节点托管一点数据,所有数据通过累积就提供了比任何集中式HTTP更多的空间、带宽和可用性。分布式网络将很快成为世界上最快、最可用、以及最大的数据存储。没有人有能力关闭所有的节点,所以数据永远不会丢失。

与此同时,比及HTTP协议,IPFS会让文件下载速度更快,储存空间价格变的更加低廉,网络更加开放和安全。目前,在网络结构里面,中心化服务器的传输压力非常大,而个人电脑、家用网络、数据带宽的利用率却很低,造成了资源的浪费,如果它通过把个人的带宽资源利用起来,为用户创造更好的网络环境,同时还采用激励的方式让更多用户贡献自己的资源(参考Filecoin\HCC飓风生态),岂不是两全其美。

诚然,IPFS在某些性能上占据了优势,但就目前的存储市场而论,中心化存储远占上风,中心化存储的市场占比高达90%以上。据了解,世界最大的芯片制造厂商 Intel 有大约10万台服务器,Facebook有3万台,而 Google有超过100万台服务器。

然而,伴随着各行各业的数据一直在急剧猛增,势头如火如荼,未来对数据存储、分发的门槛也会随之拔高,传统中心化存储的性能难以为继,HTTP或许会从框架上进行改进,但终究无法解决“集中性化”带来的痼疾,IPFS也许能成为一个不错的替代方案,却也依然存在着监管复杂等一些潜在的风险。

归根结底,两者之间的博弈核心还在于“中心化”还是多中心化的选择。

(四)去中心化:展望未来,万物皆是中心

正如我们现在对于互联网使用习以为常一样,IPFS实则是重构了我们传递、获取、存储信息的方式。为此出现新型的项目,像Filecoin则为这一系统建立了激励体系来确保系统的运转,又恰如HCC飓风生态以视频为切入口,构建聚合数据储存、处理及公链开发的双底层智能生态。虽然诸如此类的项目层出不穷,但整个行业都朝着“万物皆是中心”的良好趋势前进,即便这个时间线很长。

或许,IPFS的前沿在不久的将来,会彻底改变我们看待信息的方式,成为我们日常生活的一部分。不管是区块链本身带来的金融自由,还是IPFS给我们带来的信息自由,无疑都将是人类进化史上重要的一个里程碑。

是否还记得,那台Tim Berners-Lee在CERN的NeXT电脑——世界上第一台HTTP协议的Web服务器,主机箱上贴着一张醒目的纸条,上面写着“这是一台服务器,不要关机!”即便它现存于一家博物馆,但它的“兄弟姐妹”依旧分布在全球各地,依旧贴着“不要关机”的字样。或许多年后,服务器会摆脱这个无形的标签,因为已经没有了中心。

要:IPFS 和区块链有着非常紧密的联系, 随着区块链的不断发展,对数据的存储需求也越来越高。本文从IPFS 的底层设计出发, 结合源代码, 分析了IPFS 的一些技术细节。


一、概述

IPFS 和区块链有着非常紧密的联系, 随着区块链的不断发展,对数据的存储需求也越来越高, 由于性能和成本的限制,现有的区块链设计方案大部分都选择了把较大的数据存储在链外,通过对数据进行加密, 哈希运算等手段来防止数据被篡改, 在区块链上只引用所存数据的hash 值, 从而满足业务对数据的存储需求。 本文从IPFS 的底层设计出发, 结合源代码, 分析了IPFS 的一些技术细节。 由于IPFS还在不断更新中, 文中引用的部分可能和最新代码有所出入。

阅读本文需要读者

  • 了解网络编程

  • 了解分布式存储

  • 了解基本的区块链知识

二、什么是IPFS?

维基百科上是这样解释的:是一个旨在创建持久且分布式存储和共享文件的网络传输协议。

上面的解释稍显晦涩, 我的理解是:

1. 首先它是一个FS(文件系统)

2. 其次它支持点对点传输

既然是文件系统, 那它和普通的文件系统有什么区别呢? 有以下几点区别:

  • 存储方式: 它是分布式存储的, 为了方便传输,文件被切分成多个block, 每个block 通过hash运算得到唯一的ID, 方便在网络中进行识别和去重。 考虑到传输效率, 同一个block 可能有多个copy, 分别存储在不同的网络节点上。

  • 内容寻址方式: 每个block都有唯一的ID,我们只需要根据节点的ID 就可以获取到它所对应的block。

那么问题来了, 既然文件被切分成了多个block,如何组织这些block 数据,组成逻辑上的文件呢? 在IFPS中采用的merkledag, 下面是 merkledag 的一个示意图:

简单来说, 就是2种数据结构merkle 和DAG(有向无环图)的结合, 通过这种逻辑结构, 可以满足:

  • 内容寻址: 使用hash ID来唯一识别一个数据块的内容

  • 防篡改: 可以方便的检查哈希值来确认数据是否被篡改

  • 去重: 由于内容相同的数据块哈希是相同的,可以很容去掉重复的数据,节省存储空间

确定了数据模型后, 接下来要做的事: 如何把数据分发到不同的网络节点上, 达到分布式存储和共享的目的? 我们先思考一下, 通过网络,比如HTTP, 访问某个文件的步骤,首先我们要知道存储这个文件的服务器地址, 然后我们需要知道这个文件对应的ID, 比如文件名。前者我们可以抽象成网络节点寻址, 后者我们抽象成文件对象寻址; 在IPFS中, 这两种寻址方式使用了相同的算法, KAD, 介绍KAD算法的文章很多,这里不赘述, 只简单说明一下核心思想:

KAD 最精妙之处就是使用XOR 来计算ID 之间的距离,并且统一了节点ID 和 对象ID的寻址方式。 采用 XOR(按比特异或操作)算法计算 key 之间的“距离”。

这种做法使得它具备了类似于“几何距离”的某些特性(下面用 ⊕ 表示 XOR)

  • (A ⊕ B)==(B ⊕ A) XOR 符合“交换律”,具备对称性。

  • (A ⊕ A)==0 反身性,自身距离为零

  • (A ⊕ B) > 0 【不同】的两个 key 之间的距离必大于零

  • (A ⊕ B) + (B ⊕ C) >=(A ⊕ C) 三角不等式

通过KAD算法,IPFS 把不同ID的数据块分发到与之距离较近的网络节点中,达到分布式存储的目的。

通过IPFS获取文件时,只需要根据merkledag, 按图索骥,根据每个block的ID, 通过KAD算法从相应网络节点中下载block数据, 最后验证是否数据完整, 完成拼接即可。

下面我们再从技术实现的角度做更深入的介绍。

三、IPFS的系统架构

我们先看一下IPFS的系统架构图, 分为5层:

  • 一层为naming, 基于PKI的一个命名空间;

  • 第二层为merkledag, IPFS 内部的逻辑数据结构;

  • 第三层为exchange, 节点之间block data的交换协议;

  • 第四层为routing, 主要实现节点寻址和对象寻址;

  • 第五层为network, 封装了P2P通讯的连接和传输部分。

站在数据的角度来看, 又可以分为2个大的模块:

  • IPLD( InterPlanetary Linked Data) 主要用来定义数据, 给数据建模;

  • libp2p解决的是数据如何传输的问题。

下面分别介绍IFPS 中的2个主要部分IPLD 和 libP2P。

3.1 IPLD

通过hash 值来实现内容寻址的方式在分布式计算领域得到了广泛的应用, 比如区块链, 再比如git repo。 虽然使用hash 连接数据的方式有相似之处, 但是底层数据结构并不能通用, IPFS 是个极具野心的项目, 为了让这些不同领域之间的数据可互操作, 它定义了统一的数据模型IPLD, 通过它, 可以方便地访问来自不同领域的数据。

前面已经介绍数据的逻辑结构是用merkledag表示的, 那么它是如何实现的呢? 围绕merkledag作为核心, 它定义了以下几个概念:

  • merkle link 代表dag 中的边

  • merkel-dag 有向无环图

  • merkle-path 访问dag节点的类似unix path的路径

  • IPLD data model 基于json 的数据模型

  • IPLD serialized format 序列化格式

  • canonical 格式: 为了保证同样的logic object 总是序列化为一个同样的输出, 而制定的确定性规则

围绕这些定义它实现了下面几个components

  • CID 内容ID

  • data model 数据模型

  • serialization format 序列化格式

  • tools & libraries 工具和库

  • IPLD selector 类似CSS 选择器, 方便选取dag中的节点

  • IPLD transformation 对dag 进行转换计算

我们知道,数据是多样性的,为了给不同的数据建模, 我们需要一种通用的数据格式, 通过它可以最大程度地兼容不同的数据, IPFS 中定义了一个抽象的集合, multiformat, 包含multihash、multiaddr、multibase、multicodec、multistream几个部分。

3.1.1 multihash

自识别hash, 由3个部分组成,分别是:hash函数编码、hash值的长度和hash内容, 下面是个简单的例子:

这种设计的最大好处是非常方便升级,一旦有一天我们使用的hash 函数不再安全了, 或者发现了更好的hash 函数,我们可以很方便的升级系统。

3.1.2 multiaddr

自描述地址格式,可以描述各种不同的地址

3.1.3 multibase

multibase 代表的是一种编码格式, 方便把CID 编码成不同的格式, 比如这里定义了2进制、8进制、10进制、16进制、也有我们熟悉的base58btc 和 base64编码。

3.1.4 multicodec

mulcodec 代表的是自描述的编解码, 其实是个table, 用1到2个字节定了数据内容的格式, 比如用字母z表示base58btc编码, 0x50表示protobuf 等等。

3.1.5 multistream

multistream 首先是个stream, 它利用multicodec,实现了自描述的功能, 下面是基于一个javascript 的例子; 先new 一个buffer 对象, 里面是json对象, 然后给它加一个前缀protobuf, 这样这个multistream 就构造好了, 可以通过网络传输。在解析时可以先取codec 前缀,然后移除前缀, 得到具体的数据内容。

结合上面的部分, 我们重点介绍一下CID。

CID 是IPFS分布式文件系统中标准的文件寻址格式,它集合了内容寻址、加密散列算法和自我描述的格式, 是IPLD 内部核心的识别符。目前有2个版本,CIDv0 和CIDv1。

CIDv0是一个向后兼容的版本,其中:

  • multibase 一直为 base58btc

  • multicodec 一直为 protobuf-mdag

  • version 一直为 CIDv0

  • multihash 表示为cidv0 ::=<multihash-content-address>

为了更灵活的表述ID数据, 支持更多的格式, IPLD 定义了CIDv1,CIDv1由4个部分组成:

  • multibase

  • version

  • multicodec

  • multihash

IPLD 是IPFS 的数据描述格式, 解决了如何定义数据的问题, 下面这张图是结合源代码整理的一份逻辑图,我们可以看到上面是一些高级的接口, 比如file, mfs, fuse 等。 下面是数据结构的持久化部分,节点之间交换的内容是以block 为基础的, 最下面就是物理存储了。比如block 存储在blocks 目录, 其他节点之间的信息存储在leveldb, 还有keystore, config 等。

3.2 数据如何传输呢?

接下来我们介绍libP2P, 看看数据是如何传输的。libP2P 是个模块化的网络协议栈。

做过socket编程的小伙伴应该都知道, 使用raw socket 编程传输数据的过程,无非就是以下几个步骤:

  1. 获取目标服务器地址

  2. 和目标服务器建立连接

  3. 握手协议

  4. 传输数据

  5. 关闭连接

libP2P 也是这样,不过区别在于它把各个部分都模块化了, 定义了通用的接口, 可以很方便的进行扩展

3.2.1 架构图

由以下几个部分组成,分别是:

  • Peer Routing

  • Swarm (传输和连接)

  • Distributed Record Store

  • Discovery

下面我们对它们做分别介绍, 我们先看关键的路由部分。

3.2.2 Peer Routing

libP2P定义了routing 接口,目前有2个实现,分别是KAD routing 和 MDNS routing, 扩展很容易, 只要按照接口实现相应的方法即可。

ipfs 中的节点路由表是通过维护多个K-BUCKET来实现的, 每次新增节点, 会计算节点ID 和自身节点ID 之间的common prefix, 根据这个公共前缀把节点加到对应的KBUCKET 中, KBUCKET 最大值为20, 当超出时,再进行拆分。

更新路由表的流程如下:

除了KAD routing 之外, IPFS 也实现了MDNS routing, 主要用来在局域网内发现节点, 这个功能相对比较独立, 由于用到了多播地址, 在一些公有云部署环境中可能无法工作。

3.2.3 Swarm(传输和连接)

swarm 定义了以下接口:

  • transport 网络传输层的接口

  • connection 处理网络连接的接口

  • stream multiplex 同一connection 复用多个stream的接口

下面我们重点看下是如何动态协商stream protocol 的,整个流程如下:

  1. 默认先通过multistream-select 完成握手

  2. 发起方尝试使用某个协议, 接收方如果不接受, 再尝试其他协议, 直到找到双方都支持的协议或者协商失败。

另外为了提高协商效率, 也提供了一个ls 消息, 用来查询目标节点支持的全部协议。

3.2.4 Distributed Record Store

record 表示一个记录, 可以用来存储一个键值对,比如ipns name publish 就是发布一个objectId 绑定指定 node id 的record 到ipfs 网络中, 这样通过ipns 寻址时就会查找对应的record, 再解析到objectId, 实现寻址的功能。

3.2.5 Discovery

目前系统支持3种发现方式, 分别是:

  • bootstrap 通过配置的启动节点发现其他的节点

  • random walk 通过查询随机生成的peerID, 从而发现新的节点

  • mdns 通过multicast 发现局域网内的节点

最后总结一下源代码中的逻辑模块:

从下到上分为5个层次:

  • 最底层为传输层, 主要封装各种协议, 比如TCP,SCTP, BLE, TOR 等网络协议

  • 传输层上面封装了连接层,实现连接管理和通知等功能

  • 连接层上面是stream 层, 实现了stream的多路复用

  • stream层上面是路由层

  • 最上层是discovery, messaging以及record store 等

四、总结

本文从定义数据和传输数据的角度分别介绍了IPFS的2个主要模块IPLD 和 libP2P:

  • IPLD 主要用来定义数据, 给数据建模

  • libP2P 解决数据传输问题

这两部分相辅相成, 虽然都源自于IPFS项目,但是也可以独立使用在其他项目中。

IPFS的远景目标就是替换现在浏览器使用的 HTTP 协议, 目前项目还在迭代开发中, 一些功能也在不断完善。为了解决数据的持久化问题, 引入了filecoin 激励机制, 通过token激励,让更多的节点加入到网络中来,从而提供更稳定的服务。


近IPFS/Filecoin很火,不是小火,而是大火,引起存储界一大批人士的关注。

也就是在不久之前,以太坊这位虚拟货币界的二哥,就曾把官网部署在IPFS之上,除去帮助新生的小老弟站台的原因外,大部分原因,就是看好IPFS的特殊技能——永恒存储。

毕竟这种既能节省网站所需数据的成本,又能有效防止出现“404”这种尴尬情况出现的操作,实在是太秀了

那既然以太坊都可以在IPFS部署官网,那么个人如何在IPFS部署网站呢?


01

如何在IPFS托管


现在一打开网站,就能看到开头为HTTP的网站地址,这依然是现在流行的HTTP协议,想要改变这种协议,让任何文件都能在完全不同的IPFS显现,跟着小编接下来一起操作。

1.IPFS 桌面

如果您已安装并正在运行IPFS Desktop,则可以使用常规文件选择器添加文件。只需导入包含您静态网站内容的目录即可。

IPFS CLI

IPFS CLI允许使用add的命令添加文件和目录。

最后一行打印的哈希是整个目录的CID,因此也是我们网站的CID。可以看到托管在

“https://ipfs.io/ipfs/QmeUG2oZvyx4NzfpP9rruKbmV5UNDmTQ8MoxuhTJGVZVTW/”上的示例网站

提示:

在您的网站中使用相对链接非常重要,因为IPFS网关的URL类似于<gateway>/ipfs/<cid>/file.ext。


02

Pinning


在最后一节中,添加的文件可以在我们的 IPFS节点网络中找到,这就是IPFS网关能够解析它并将其显示在浏览器中的原因。


但是,一旦关闭IPFS daemon,该站点很可能将无法访问。即使在IPFS上请求了某些内容之后,接收节点也成为该内容的主机,但是在12小时后将对这些内容进行收集。那么,如何在没有服务器的分散式网站中全天候备份您的网站?


在IPFS上固定一些内容的节点将永远托管它(直到取消pinning它)。诸如Pinata之类的固定服务,可将文件固定在其IPFS节点上。如此一来,网站将始终可用。

在Pinata中,如果内容已经上传到IPFS,则可以上传文件或仅提供其哈希值。这是我固定我们上面上传的示例网站的方式。

提示:最好使用多种固定服务固定您的站点,以实现冗余。


03

自动化部署


可以借助Fleek这样的工具,可以帮助自动完成上面列出的所有步骤。

Fleek就像Travis或CircleCi一样用于IPFS部署。您可以将其Github帐户与其关联,并使用Github挂钩,Fleek将在每次推送至Github存储库时触发部署。他们还固定部署的所有内容。

此外,我使用Hexo生成了此博客,并且能够在Fleek本身中添加一个构建步骤,因此无需生成HTML并将其推送到我的存储库。这是我使用的构建命令:

  • git submodule update --recursive --init && npm i && npm run build

需要自己安装的模块,但是不用担心,因为这是非常容易的。

链接到域

因此,现在我们可以启动并运行我们的网站,但是IPFS上的内容不像传统网络上那样容易查找。传统的网站可以在https://tarunbatra.com上找到。

但在IPFS上,我们可以通过:“https://ipfs.io/ipfs/QmTPTa1ddoSkuakaW56SaL9dicbC71BbwfjRbVjasshCXs/”访问当前版本。


04

DNSLink


使用 DNSLink,您可以将一个普通域指向 IPFS 内容。它可以很容易地设置在 Fleek 上。我已经将 IPFS .tarunbatra.com 指向了使用 Fleek 的 IPFS 版本,您将能够打开这个站点。

IPNS(星际命名服务)也存在,它类似于 DNSLink,但现在要慢得多。

做了这些暂时就能让网站能稍微初具规模


不过虽说IPFS\filecoin能给网站的建立一个永久性的阵地,但是它的主要作用还是用来存储,主要市场的方向,还是正在逐渐扩大的存储市场。

不过想要在这个存储分上一杯羹或者成为一名filecoin的矿工,除了要尽早布局,还需要不断的提升自身的竞争力。