赵钰莹数据库初创企业 RisingWave Labs

那位用Rust重写数据库的创始人来复盘了:删除27万行C++代码,值吗?

赵钰莹AI前线 2022-10-08 13:30 Posted on北京

Image

嘉宾 | 吴英骏博士

采访 | 赵钰莹数据库初创企业 RisingWave Labs 曾经发表了一篇博客文章,宣布完全删除掉了 RisingWave(该公司开发的云原生流式数据库) 的 27 万行 C++ 代码库,并用 Rust 语言从头开始重写了一遍系统。本文,我们采访到了该公司的创始人 &CEO 吴英骏博士,详细探讨了重写前中后期的准备、遇到的问题以及经验复盘。放弃 Rust,初抉择是 C++ InfoQ:选择哪种编程语言和 RisingWave 的特性有关系吗?

吴英骏: RisingWave 是一款云原生流式数据库,主要服务于需要超低延迟实时数据分析应用。其定位不仅是一个 SQL 数据库系统,还提供流处理能力:使用流数据执行连续查询,并以物化视图的形式动态维护结果。另外,采用分层架构,建立在现代云基础架构之上,利用云资源为用户提供对成本和性能的细粒度控制。

这个架构最大的特点在于资源是无限的,既然有无限资源,性能并不是特别大的问题,只要加资源,性能就会更好,但是资源是收费的,设备是收费的,我们希望能够在保证用户性能的前提下让整个系统更加便宜,让普通用户以一种比较低的价格使用,这是我们的核心设计理念。

这与编程语言的选择没有太大关系,开发一款数据库可以用各种各样的语言,比如 C++、Rust、Java,Scala 等,一些交易系统相关的可能还会考虑 Haskell,但即便是在 20 年之前的数据库,也鲜少有人使用 Java 、Basic、Python 这类语言,主要是因为这些语言的运行效率和性能均不高。

我们主要希望选择一门高性能的编程语言,所谓的高性能基本上是 C++、Rust 或者一些小众的语言,如果希望可以被用户广泛接受,基本是 C++ 和 Rust。

InfoQ:从之前披露的文章中可以看到团队最初选择的是 C++ 语言来构建,并集结了多位具有 10 年以上经验的 C++ 工程师,当时是看中了 C++ 的哪些特质还只是遵循市面上大部分数据库系统的选择?

吴英骏: 我本人比较擅长 C++,不管是读博期间还是创业之前做的所有数据库都是用 C++ 写的,没有用过其他任何语言写过任何项目。

创业之初,有人给我们提过可以用 Rust 写,理由是用 Rust 写容易火。在我看来,这不可以算作理由,我们又不是想要成为网红,选择一门语言肯定不是单纯为了火,我们需要考虑团队适合用、会用的语言以及数据库领域的通用语言是什么。在数据库领域,虽然 TiDB 的存储引擎 TiKV 是用 Rust 写的,但这不足以证明成功的数据库系统都是用 Rust 写的,反而绝大多数成功的数据库系统都是用 C++ 写的。

从招聘的角度考虑,我们肯定希望招到的都是数据库领域的专家,在数据库领域有多年经验的专家很可能来源于现有的各大数据库厂商,而这些厂商基本都是用 C++ 的。

相较而言,Rust 是一门比较年轻的语言,缺少比较重量级的项目,尽管这个语言是被实战过的,也有一些相对流行的项目,但还算不上重量级的巨无霸项目,还有一些项目主要是币圈在用,生态上或多或少是有不足的。

综上,我们最终决定选择用 C++ 作为主要开发语言。

再抉择用 Rust 重写 InfoQ:团队已经在这件事情上投入了 7 个多月,您也提到对初创企业而言时间是非常宝贵的,是哪个点 / 事件让团队觉得不重写不行了?

吴英骏: 首先,C++ 比较经典的问题是内存泄漏,但这类 Bug 比较容易修,我们觉得可以忍。其次,依赖管理很痛苦,虽然 CMake 工具可以自动配置 C++ 项目的编译,但使用起来还是很麻烦的,仍然需要手动配置和安装依赖库;STL 库缺乏对一些现代编程工具的支持,依赖的社区项目大多数还都缺乏长期支持;最后,我们招聘进来的成员 C++ 水平参差不弃,每个人都有自己的风格,非常难统一,代码看起来比较累,审查代码令人生畏。随着越来越多人员的加入,C++ 的问题暴露得越来越频繁。这段时间,频繁有工程师提出是不是可以考虑使用 Rust 重写。

另外,流式数据库通常用于对延迟非常敏感的关键任务。因此只能使用以下语言构建 RisingWave:保证零成本抽象,不会有性能上限;不需要运行时垃圾收集,可以控制可能由内存管理引起的延迟峰值。

起初,我们是不愿意更换语言的,毕竟已经写了这么久。最后,我们表示如果支持用 Rust 重写的工程师可以对一个独立的模块改写成功,我们就考虑整体重写。与此同时,我也想起之前在 AWS Redshift 工作中遇到的一个 Bug,三个人不断调试了两周都无解,最终发现是内存泄漏的问题,如果现在的项目继续下去很可能会遇到类似的情景,假设那时的产品已经有了很多用户,我们还需要因为这种内存泄露的问题调试许久,得不偿失。也是这个时候,我们开始认真考虑是否用 Rust 重写。

经过慎重评估,原来七个月写的代码用 Rust 重写需要花费大约两个月的时间,前后的时间差主要体现在项目的逻辑框架前期已经梳理清楚,正值暑假,公司内部纳入大量实习生,人手比较充足,且很多实习生天然有 Rust 的基础,这些都提升了重写的速度。最后经过全公司的表决投票,我们开始重写。

在替换过程中,我们选择逐个模块替代,这也保证了整个过程不会出现很严重的问题。

InfoQ:C++ 代码风格不统一的问题,用 Rust 重写以后就不存在这个问题了吗?

吴英骏: 风格不统一的问题肯定不是使用 Rust 就能解决的,但相对 C++ 会有很大程度的改善,C++ 中一些指针等的写法很难统一,还容易造成安全性的问题,工程师在阅读其他人的代码时如果对全局系统不够了解很容易出现误读,从而造成系统出错。

InfoQ:C++ 一些语言层面的缺陷由来已久,您将 C++ 语言作