shosti/wraft: 使用Rust和WebRTC在浏览器中实现分布式Raft


是一个基于 WebRTC 的 Raft 实现,用 Rust 编写,用于 WebAssembly。
这里有几个演示应用程序,代码在 GitHub 上开源的。这是一个有趣且具有挑战性的项目,所以我想我会写一篇关于这种体验的博客文章,作为一种“事后分析”。
以下是该项目所涉及技术的极其快速的摘要:

  • Rust或多或少是唯一一种没有垃圾收集器的内存安全的主流语言(感谢其独特的所有权模型和借用检查器)。这使它能够在垃圾收集语言挣扎的情况下茁壮成长,包括……
  • WebAssembly(或 Wasm),它是前端 Web 应用程序(以及现在的其他应用程序,尽管这是另一篇博文的主题)的二进制格式。这个想法是,Wasm 程序可以在浏览器中以接近本机的速度运行,这使其成为实现……的有趣选择。
  • Raft,这是一种分布式共识算法。Raft 安全可靠地将数据复制到多个节点(通常是服务器),并且是etcd和其他几个分布式数据库背后的大脑 。当然,节点之间要相互复制数据,就需要能够相互通信,这对于基于浏览器的应用程序来说有点挑战!但可能要归功于……
  • WebRTC,这是一种基本的点对点协议,允许浏览器内的程序相互通信。WebRTC 的“真实世界”用例通常涉及视频和音频共享,但该协议还包括用于在 Web 浏览器之间传输任意数据的数据通道,这就是我在 WRaft 中使用的。

我最初的想法是构建类似“用于浏览器的 etcd”的东西,即分布式点对点键值存储。奇怪的是,Raft 论文没有提及键值存储或数据库。相反,它含糊地提到了“复制状态机”。一旦项目取得进展,我最终就从字面上理解了这一点;最终结果是 WRaft 将在浏览器窗口之间复制任何类型的状态机(由Rust trait指定)。
这种方法非常适用于 React 风格的 Web 应用程序,因为它们往往建立在数据流的状态机之上。作为演示,我使用Yew TodoMVC 示例应用程序并在 WRaft 中复制了整个应用程序状态。(Yew类似于 Rust/Wasm 的 React/Redux 克隆。)您可以在https://wraft0.eevans.co/todo 上试用结果。
深入研究整体架构,一个 WRaft“集群”看起来像这样:

在当前的实现中,一个集群总是恰好有三个“节点”(即浏览器窗口)。节点通过基于 WebSocket 的介绍器服务(稍后会详细介绍)找到彼此,然后它们开始通过 WebRTC 数据通道进行通信。每个节点都使用本地存储本地存储数据(我用IndexedDB进行了一些试验,但它似乎非常慢)。
只要两个节点在线,整个集群就“健康”,可以继续工作;离开集群的节点(例如,如果您重新加载页面)将尽最大努力重新加入集群并赶上。不幸的是,集群目前无法从所有节点宕机中恢复(我可能会在某个时候尝试修复它)。
集群成员可以在同一台机器上,也可以在局域网上的不同机器上(理论上它甚至可以在互联网上工作,但我还没有测试过)。性能似乎相当不错:使用一个非常基本的基准测试应用程序,我在 Chromium 上看到每秒超过 2000 次写入,这对于我能想到的任何用例来说可能已经足够了

原文点击标题