嗨,
是Memgraph the Core Team的Kostas,我很高兴分享更多有关我最近作为附带项目工作的很酷的事情。正如您可能从标题中猜到的那样 - 一切都与WebAssembly有关。由于要涵盖许多细节,因此这将是一个由三部分组成的文章系列,它将逐渐解释我们决定在Memgraph上使用WebAssembly的方式以及为什么。但是在我深入研究Websembly世界之前,我想分享一个短篇小说。
对于大多数人来说,数据库无非是存储数据并处理连接的服务。客户端通过客户端适配器库(例如mgclient
,pymgclient
等)进行交互式(例如Memgraph Lab
,mgconsole
)或编程性互动。但是对于我们来说,经验丰富的工程师,我们知道在引擎盖下还有更多。数据库实现需要深入了解数据库内部设备(即交易,查询执行,优化等)以及对存储和查询引擎的仔细手工艺。
最重要的是,建立了一个网络协议,该协议有效地允许数据库与外界进行通信。具体而言,对于客户端适配器库,上述还指出了一个隐含的要求:您要么需要实现网络堆栈,并且针对每种受支持的编程语言都需要实现全部数据类型,或者您可以在C中实现一次并通过bindings Interface进行调用目标语言(例如Java Jni,Node Napi等)。对于后者,您也可以加倍努力并使用Swig之类的发电机。但是实际上,没有免费的午餐,Swig附带了自己的一系列限制,我稍后会解释一下。
有两个关键要点:
- memgraph遵循第二种方法,可以实现没有swig这样的发电机的客户适配器,并且客户主要由核心团队维护。
- 两种方法都要求程序员本身重新实现协议,或使用目标编程语言提供的深奥绑定API(爆炸性的认知开销)。对于第二种方法而言,更多是正确的,绑定的API不是通用的,也就是说,每个方法都在很大程度上取决于每种语言的深奥扭转。
这就是我的故事开始的方式。在2022年冬季,我致力于实施时间类型。为此,我还必须扩展Memgraph的客户库库的网络堆栈,其中包括使用非宇宙和非标准化语言(即绑定)修改广泛的库。正是在那时,我开始思考体系结构以及如何简化抽象层,减少认知开销和可能的错误数量。这是我发现Swig的地方,但正如我之前宠坏的那样,这不是灵丹妙药。即使它简化了建立新客户的过程,但调试错误或代码生成失败/错误还是可怕的。我认为解决此问题所需的是与C客户端无关的中间表示,所有其他具有相同语义的语言都可以消费。听起来很熟悉?如果没有
WebAssembly(abbreviated Wasm) is a binary instruction format for a stack-based virtual machine. Wasm is designed as a portable compilation target for programming languages, enabling deployment on the web for client and server applications.
在外行术语中,WebAssembly是某种基于执行的运行时实现的IR,或者是完全编译的,或者是jited的。就像llvl ir提供了独立于架构的伪组件一样,WASM指定了一个独立的执行环境,这意味着任何WASM运行时都可以消耗并实现IR。
这里的新颖性是将mgclient
(我们的C客户端库)编译到WASM模块中,并使用它来实现所有其他客户端。这是点燃的,因为现在所需的一切都是通用运行时。这种运行时存在,它被称为Wasmer,这有效地削减了绑定依赖的联系。将WASM用作中间表示,还有一个整洁的好处 - 我们得到了非常好的关注点。简而言之,对网络堆栈的更改集中在C实施中,并且客户成为低级实现的高级API包装器。这样,在网络堆栈上引入的错误是独立的。如果存在内部问题,则不是绑定,而是与API相关的,而是实施。我们知道在哪里看,我们可以快速看。另一个好处是,现在我们不需要了解JNI,NAPI或任何其他绑定库,因为一切都集中在一项技术围绕一项技术中:WebAssembly。
当然,实际上事情不是理想的,但是从我到目前为止,我想说它们非常接近。在这一点上,您可能想知道这一切如何在内部合作?好吧,如果您想了解有关WebAssembly的更多信息,请查看该系列的下一篇文章。它将深入研究WebAssembly的世界,以慢慢建立本系列最后一部分所需的理解:第一个Memgraph的基于WASM的客户适配器库,用于JavaScript,jsmgclient
。
这就是所有人 - 希望您喜欢系列的第一部分!