没有“服务器房东”的世界:Mathias 的梨子(Pear)技术生态(上)
给 Tech Nerd 的 Peer-to-Peer 硬核历史(Mathias 版 :)

Go to the English Version
Core Contributer: 赵阳
Visuals & Editor: dca5 & Shiyu
*本文分上下两部分发出。本文为第一部分,集中于 P2P 的历史与基础技术栈的讨论。在与 Mathias 的访谈的下半节中,我们将听到更加偏应用侧的观点:Mathias 所认为的 P2P 技术在搭建媒体与数据分发应用方面“真正的超能力”;及 Pear 的技术栈和生态系统是否具备与区块链或比特币整合的需求与潜能。
Jiang:Mathias,能否请您先做个自我介绍,然后谈谈您在 Holepunch 和 Pear 开发套件上的工作?
Mathias:当然可以。我是 Mathias,目前担任 Holepunch 的首席执行官。我们是一家专注于打造纯 P2P(Peer-to-Peer, P2P)技术的公司,我们只做计算机直连并直接交换数据的项目,而不依赖服务器。我们在密码学及相关领域开展了大量工作。虽然我们不涉及区块链这一类领域,但我们开发了大量基础组件来支撑 P2P 技术的运行。
我们拥有一个名为 Pear Runtime 的平台,这个平台为开发者封装好了大量的功能模块,通过我们编写的各类组件即可运行并调用这些工具。借助名为 Bare 的 JavaScript 运行时环境,这一平台可以同时支持桌面端与移动端的运行,这非常便捷。我们既开发 P2P 技术的基础架构,也开发基于 P2P 技术的应用程序。
我们的聊天应用程序 Keet 就是基于此技术打造的 P2P 聊天工具,它类似于 Telegram,但它完全无需服务器支持,而是由用户节点直接相互连接。这种架构确保了极高的隐私性、可扩展性和成本效益,我们对 Keet 及其为通信领域带来的变革充满期待。我们还在 P2P 领域开发其他应用,所有产品都是基于 P2P 技术开发的。
技术栈的演化:从 BitTorrent, Hypercore 到 Holepunch
Jiang:非常感谢。另外,您能给我们讲一下 Hypercore 项目的历史吗?您是如何参与进来这个项目的?又是如何将其发展为这样的技术栈的?
Mathias:当然可以。我一直对 P2P 技术很感兴趣。我曾为 BitTorrent(简称BT,常被中文用户称为“比特流”)做了大量的工作。大约 15 年前我开始用 JavaScript 编程,并为 BitTorrent 编写了大量的 JavaScript 代码。参与开发 BitTorrent 的经历令人难忘。 BitTorrent 这个协议设计非常精妙,它结构简洁却功能强大,具备出色的稳定性、拓展性与抗故障能力。它既是理解 P2P 技术的绝佳切入点,同时也能让人看到该协议在某些方面的局限性。
BitTorrent 在传输静态文件方面表现优异,但对动态数据处理效率低下。它缺乏完善的数据修改机制,由于年代久远且高度聚焦于文件共享,在连接对等节点方面存在诸多限制。实际上,在 BitTorrent 中追加通用数据非常困难,若要共享数据库,必须将其视为文件进行处理。
我在该领域积累了丰富的经验,如能解决这些问题,所能开启的应用场景将非常令人振奋。因此我着手开发名为 Hypercore 的项目,它与 BitTorrent 颇为相似。实际上,它深受 BitTorrent 启发,但增加了可变性等特性,允许用户添加新区块,使区块尺寸灵活变化而非强制统一。它能共享各类内容:文件、数据库及类似数据。系统采用高度模块化设计,可在不同计算能力的环境中运行,不仅限于文件共享网络,还能嵌入多种应用场景。
于是我开始进行这项工作,并且充满热情、全身心地投入到这个项目中。在开发过程中,我们还尝试将这项技术应用于科学领域中非营利性文件的数据共享。这一领域存在大量既难以获取又因维护托管成本高昂而难以普及的数据集。
Jiang:您提到的这家非营利组织,名为“Code for Science & Society”?
Mathias:是的,就是“Code for Science & Society, 简称 CSS”。我很幸运地获得了他们的资助来开展这类项目,我们主要服务于科学用例。我在这个项目上工作了几年,组建了一家专注于 P2P 技术的公司 (Hyperdivision)。在此过程中,我结识了 Andrew,他后来成为 Holepunch 的联合创始人之一,我们为此公司全职工作。
在非营利项目工作数年后,如许多同类项目一样,它最终被遗憾终止了。我继续独立推进 Hypercore 项目。我们投入大量精力在解决有关连接性(connectivity)的挑战上。四年前,我们创立了 Holepunch,这家公司就是围绕这些技术所构建的。我们致力于推动技术规模化,渗透所有市场,力争成为解决实际应用场景的硬核技术。我们已经心系这项事业多年了,衷心希望能将其推广至世界每个角落,这正是 Holepunch 诞生的初衷。
Hypercore 的核心机制
Jiang: 网络穿透的打洞技术(hole punching)的优势在于,它能在条件允许的情况下连接互联网上的任意两个节点——这看似简单,但考虑到当前互联网的结构,实现起来相当困难。另外,我们还想请您解释一下 Hypercore 的核心机制:增量 Merkle Tree 和只追加日志。
Mathias:确实。正如我提到的,Hypercore 与 BitTorrent 非常相似。我不确定大家是否熟悉 BitTorrent 的技术细节,但它本质上是由一系列固定大小区块组成的 Merkle Tree。 Hypercore 与之非常相似,它同样是 Merkle Tree,但属于可扩展的 Merkle Tree,可以不断添加新区块。如果想象这个过程,如果你添加区块,那么树就会随之生长;但树的原有枝干保持不变,你同样也只是在原有基础上添加区块。这使得增量同步(incremental synchronization)变得非常容易。借助 Merkle Tree,你还可以做其他事情,比如稀疏同步(sparse syncing),即你只获取部分数据块,而非整个数据集。只要你能追溯通往 Merkle Tree树根(root)的路径,这种方式就非常强大,而且非常安全。
现在,如果你有一个能够扩展的 Merkle Tree中,你就不能再简单地依据Merkle Tree 的根节点了,因为它不再是静态的。在 BitTorrent 中,该(torrent 文件的)标识符实际上就是 Merkle Tree的根节点。为了解决这一问题,在 Hypercore 中,我们采用多种策略对这些更新进行签名(sign updates)。例如,使用密钥对(key pair)来对更新进行签名。我们在这方面做了大量的工作,效果非常好,这正是基础组件的核心。
其他细微但重要的改进包括:区块不必是固定大小的。在 BitTorrent 中,出于多重原因,区块大小必须是固定的,而我们支持可变大小的区块。这对文件共享影响不大,但在通用数据共享的应用场景中至关重要(尤其当存储的数据类型未知时)。以 KV(键值对)存储为例,我们开发了名为 Hyperbee 的模块,以及基于这些数据结构创建的数据库模块 HyperDB。它们通过追加可变大小的数据块实现这一点。所有数据块在结构上都具有相似性,但由于数据库数据具有结构化特征且实际大小不尽相同,因此需要一定的灵活性。借助稀疏同步机制,用户可以仅获取特定数据块,从而实现高效的数据库查询,因为用户只需检索查询所需的数据块即可完成验证。
Jiang:是的,稀疏性是 Hypercore 的优势之一。
Mathias:这正是我们一开始就想做到的。BitTorrent 本身就具备稀疏性,而且表现相当出色。这正是它的一大亮点——用户只需获取部分数据就能完成完整验证。许多区块链系统并不具备这种稀疏性。
Jiang:比如在观看流媒体视频时,你只需要读取当前正在观看的视频块。
Mathias:正是如此。这可以作为一种策略:用户在同步过程中就能浏览数据集,同时仍可同步全部内容。虽然完整同步更优(因为这样能获得更可靠的副本)但用户也可以选择只同步部分内容,满足特定需求即可。这种方式非常实用。
Jiang: 如果我没记错的话,曾经有一份关于 SLEEP 协议的白皮书。
Mathias: 是的。我们确实写过白皮书。当时我们特别热衷于搞缩写,所以尝试创造了一些缩写名称。SLEEP “睡眠”有点像对应 REST “休息”的双关梗,你知道的,就是 HTTP 领域的那个 REST(Representational State Transfer,“表现层状态转移”)。于是我们创造了 SLEEP 这个名称。虽然现在看来已相当过时,但当时看来还非常有趣。我们发表过几篇论文,直到现在仍在密集推进这项技术的迭代开发。近期论文产出不多,但我们计划加强这方面工作。实际上我们刚启动了一个项目,旨在创建全面的协议文档体系,以便提供更多支持资源。我特别喜欢通过信息图表和可视化材料来探索这些概念。这样就可以直观地看到各个模块的组合方式。目前团队正投入大量精力开展这类工作。
Jiang:关于增量默克尔树,我记得 ScuttleButt 里有人提过 Bamboo 算法。这是增量结构的替代方案。
Mathias:我想说的是,不会存在某一种终极解决方案。多元方案总是有益的。我认为我们的方案非常出色。
坦白说,若你仅需同步静态文件,且仅有这一需求,你应该使用 BitTorrent,它在这方面的实际上比我们更优。但如果权衡各个维度,我们在其他方面更具优势。在 Hypercore 中,如果你不仅仅是需要同步静态文件,还需要同步增量数据,我们的文件同步速度确实略逊于 BitTorrent,但在其他方面却表现更好。因此用户必须有所取舍,不同项目都有各自的优劣。
但我认为 P2P 技术真正可贵之处在于协议必须开放。若协议不开放,就无法验证其有效性;若无法验证,协议层面的 P2P 特性便不复存在。因此开放性越强越好,这正是推动技术进步、激发创新理念的源泉。
Pear Runtime:P2P 应用的架构与连接策略
Jiang:能给我们介绍一下 Pear 吗?你们希望构建什么样的平台?背后的技术架构是什么?
Mathias:当然可以。首先,关于 Pear 这个 P2P 平台我想讲一下它名字的由来。它之所以叫 Pear,是因为我曾与许多意大利人共事,他们说“peer /pɪər/”这个单词的时候会读成成“pear /peər/”。我们觉得这很有意思,所以决定干脆将它命名为 Pear Runtime,这样还能以梨子为图案设计一个logo。
我们从事这项工作已有约 15 年了,围绕 P2P 技术开发了大量模块。Pear 涵盖文件共享、数据库共享、协作数据库、分布式模式等各类功能,以及连接性等相关特性。这些年来我们进行了广泛的探索和开发,目前估计已有大约 500 个支持各类网络功能的模块。
我们的目标是打造一个基础平台,让应用程序能够在该平台上运行,并为跨平台运行奠定基础。这就是我们开发 Pear Runtime 环境的初衷。我们希望创建一个能够直接从网络加载应用程序的层级。通过 P2P 技术加载应用程序,用户得以运行遵循相同原理的各种程序,而应用本身也会采用相同技术来实现特定功能。
以 Keet 为例,它通过 Hypercore 进行分发,同时应用内部也运用 Hypercore 构建聊天系统。这种设计虽令人惊叹,却能打造出极其稳健的应用程序、极具弹性的扩展。
我们在这一领域进行了大量工作,近期着力于让这项技术在移动设备上稳定运行。移动端的重要性不言而喻,毕竟智能手机无处不在。但与此同时,移动端也充满挑战,因为手机与电脑有着完全不同的技术约束条件。
Jiang:是的,比如电池续航、连接性、权限设置和沙盒机制。
Mathias:沙盒是一个截然不同的运行环境,它高度依赖 UI(用户界面)。此外,桌面系统能让程序在后台运行,手机则完全做不到。我们当时也费了很大劲让 JavaScript 能在手机上实现所需功能,因为我们所有代码都是用 JavaScript 编写的,并且底层还依赖大量 C 代码提供支持。要让这套东西运行起来极具挑战性,毕竟我们所有的网络代码都是用 C 写的。
为此我们开发了一个名为 Bare 的 JavaScript 运行时环境。(所以现在有“Pear /peər/”又有“Bare /beər/”了,我们觉得这一对命名的组合非常有趣)。这是个极其轻量级的 JavaScript 运行时,使我们得以将这项技术部署到任何平台。事实上,我们在手机端运行的 P2P 功能代码与桌面端完全一致。对 Keet 而言,两者毫无差异,因为这是用我们模块编写的代码,这些既能在手机上运行,也能在桌面上运行。这是一种非常高效的应用开发方式:一次开发,多处运行。
当然,UI 存在差异。手机 UI 与桌面 UI 通常差异显著,毕竟屏幕尺寸不同,但核心功能——即支撑 P2P 系统运行的部分——是完全一致的,我认为这至关重要。
我记得您刚才也提到了打洞技术(hole punching)。我们之所以将公司命名为 Holepunch,是因为我们极度专注于连接性,致力于实现设备间的直接连接——这确实是个非常棘手的难题。我们早期重点攻关的课题就是如何穿透网络屏障,让设备能够建立连接并传输数据。我们对这项技术的极其专注,甚至以此命名公司,我认为这也非常恰当地体现了我们的专注性。
我们在各类网络库中集成了大量精密的功能模块,它们通常都能运行无阻。这种能穿透大多数网络环境的能力让我们感到自豪。当然,也存在无法穿透的特定网络,此时就要采用其他策略了,比如通过其他节点协助路由流量。但可以肯定的是,要想在 P2P 网络中实现任何功能,都必须依赖一个极其稳健的连接层。
Jiang:是的,而对于 Pear 来说,它还能够实现两个 Pear 实例之间的连接自举(bootstrap,初始化并建立最初的 P2P 连接)。
Mathias:是的,这是我们希望尽快实现的功能之一。我不太确定具体的专业术语该怎么表达,但基本原理是这样的:当我想与你建立连接时,系统会先分析当前的网络状况。网络情况大致分为三种:一种是能快速建立连接,另一种是需要较长时间才能连接,还有一种是完全无法连接。如果处于复杂的网络环境,我们通常能在 10 秒左右完成连接——但对用户来说,10 秒已经太长了。而如果遇到像极端封锁那样完全无法连通的情况,我们就真的无能为力了。
幸运的是,大多数网络环境都比较容易突破。只有极少数网络的难度较高,而完全无法连接的情况则更为罕见。但我们需要的是一个更可靠的解决方案。没人愿意开发一个只对 99% 用户可用的应用,哪怕只有 1% 的失败率,也意味着质量不够好。所以我们必须确保它在任何情况下都可用。
我们确保其始终可用的方式之一是采用一套协议机制:当我想与你建立连接时,可请求其他节点中继传输流量,因为你我均通过节点 ID(类似公钥)进行身份验证,整个过程非常安全。我可以向某个节点提出请求:“能否将我的流量转发给目标节点?”同时,我还能验证中转节点是否具备读取权限、数据流向是否正确,因为所有通信都通过加密技术和密钥对进行地址解析。一旦系统检测到更优的路径(比如点对点直连),就能无缝地将现有连接迁移过去,而不需要重新建立。这意味着从应用开发者的角度来看,整个过程是完全无缝衔接。连接初始可能速度缓慢、带宽不足,但当双方直接建立连接时,速度会突然大幅提升。
Jiang:但那些第三方节点为何愿意中继传输流量呢?
Mathias:这是个好问题。实际上,这取决于你开发的应用类型。因为第三方节点也可能就是你自己运行的一个节点,也就是说,你可以选择为自己的网络提供资源支持。另一方面,这也可能是应用程序的一个内置要求,比如你可以设计成,运行该应用就需要承担一定的中继成本,例如让 2% 的流量由其他用户协助转发,这就是协议本身的规定。当然,有人可以去修改代码,但我们的设计初衷就是如此。
Jiang:在一个五人的视频群聊中,每个人需要建立多少条连接?
Mathias:目前在 Keet 中,这一机制非常简单直接。我们采用全连接拓扑结构,所有人都相互连接。正因如此,通话功能在规模扩大时表现不佳,但在小规模下运行尚可。超过 10 人时,连接量会急剧增加,对资源消耗很大。不过,我们正在将其迁移到基于 Hypercore 的新协议中。目前通话还是依赖直接连接,而新协议下就无需直接连接了。一般来说,只需要大约平方根数量的连接,显然更高效。因此可以灵活选择策略。
视频通话的难点在于对实时性的高要求。比如我们在交谈的时候,哪怕一秒的延迟都会显得漫长。如果我说话的时候,你一秒以后才听到,就会感觉很奇怪。因此数据必须快速送达,这也意味着它无法承受过多中转。
”真正无服务器架构“吗?
Jiang:是的。Pear 是一个面向去中心化 P2P 应用的开发工具包和平台。正如我们所说,所有内容都可以由对等节点直接或间接地启动或提供服务。这实际上是对传统客户端-服务器架构的一种挑战,呈现出一种真正无需服务器的应用架构形态。
Mathias:真正无服务器吗?(Actually serverless?)是的,我一直觉得这个术语很有意思。它其实挺讽刺的,因为我们 Holepunch 的一些产品团队的同事偶尔会建议,要不要把产品改叫“无服务器架构”。但作为技术人员,在我看来,“无服务器”一词在业界已经另有所指了。这个词其实有点奇怪——所谓的“无服务器”不过是指换了种服务器形式罢了。行业里虽然这么叫,但我个人不太认同。像 Amazon Lambda 这类典型的无服务器系统,本质上只是短生命周期的服务器,某种程度上也可以说是无状态服务器。但 P2P 才是真正字面意义上的“无服务器”:你根本不需要服务器。
我觉得这里面还有一个有趣的误解。我常听到很多人认为 P2P 网络就意味着只能用自己的笔记本电脑跑节点,其实并非如此。如果你想在数据中心里运行 P2P 软件也完全可以,只不过那是一个生命周期更长的节点而已。P2P 的精髓在于你可以自由选择如何组网,我认为这正是它的优势所在。
即便在今天,如果要在数据中心里搭建一个中心化网络,我仍然会采用 P2P 架构——只不过这个 P2P 架构部署在数据中心内,因为这样能获得更强的容错能力。这种技术通常足以满足常规业务运行需求,何不借此获得一点额外的保障?如果采用 P2P 架构,即使服务器遭入侵或出现故障,也不会导致整个系统数据瘫痪,只要仍有节点存活就可以恢复。这个问题完全可以通过多部署实例甚至用笔记本电脑来解决。
我家里就有一台电脑,常年运行着多个 P2P 服务。它就一直放在家里,托管了不少 P2P 应用。毕竟宽带费用已包含在每月网费里面,无需额外支出。电力成本也相当低廉,用一台 Mac Mini 这样的设备就足够了。仅凭这样的配置,就能提供可观的算力。若要把同样的服务部署在数据中心里,成本将远高于直接购买设备,毕竟数据中心的运营成本非常高昂。因此我对这种真正意义上的“无服务器”模式非常感兴趣。
(未完待续)
☀️ 专栏相关文章



Who we are 👇
Uncommons
区块链世界内一隅公共空间,一群公共物品建设者,在此碰撞加密人文思想。其前身为 GreenPill 中文社区。
Twitter: x.com/Un__commons
Newsletter: blog.uncommons.cc/
Join us: t.me/theuncommons



Discussion