写点什么

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

  • 2022-10-13
    北京
  • 本文字数:4262 字

    阅读完需:约 14 分钟

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

前段时间,数据库初创企业 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++ 语言作为主要的开发语言,之前没有遇到过上述问题吗?


吴英骏:我之前也遇到过,但上学期间,Rust 没有现在完善,使用者很少,因此也不会考虑到使用 Rust 去开发数据库。此外,我之前接触的数据库是比较成熟的产品,比如 IBM DB2,大部分时间都在调试,很难有精力和时间去把这么一个诞生了几十年的数据库进行重写,但创业是不一样的,尤其是早期起步阶段。


在大型企业内部,重写某个项目大概率项目本身并不是那么重要,或者没有很多用户,否则需要投入大量的精力和资源。对起步阶段的创业公司来说,还是有机会重写的,一旦面对客户交付的压力,重写是不太可能。


InfoQ:重写之前的系统已经完成了多少?


吴英骏:简单来说,框架是比较清晰的水平。重写不至于发现之前的 Bug,但的确会通过这个过程重写考量各个部分设计的合理性。

Rust 的爽点


InfoQ:Rust 比较爽的特性是什么?


吴英骏:首先,安全性肯定是让我们觉得是比较爽的,这对数据库项目非常重要。其次,包管理非常少,C++ 有非常多的库,包管理非常复杂,可能需要花费几个小时去想如何在 CMake 里面配置一个包管理工具,甚至是在花费了很多时间之后,我们发现装不上去,还可能会遇到重名的问题(其他项目中使用的变量名称可能和我们使用的库中的名字重合了),这些问题都需要手动解决,而且改起来费时费力。

重写收益比


InfoQ:重写前后的收益情况如何?


吴英骏:总结来讲,这件事情的收获非常大。从收益比的角度看,我们损失的是时间,因为分段重写大概花费了一个月左右,但这些时间并没有浪费掉,这个过程让我们又反思了一遍不同模块的设计思路,改掉了其中不合理的部分。对数据库系统而言,这是一个长周期的项目,早期孵化阶段的时间宝贵程度和正式上线后肯定是有区别的,当对象是直接用户时,数据库系统出现任何问题都是不能忍的。


我们收获的是系统更加稳定、安全,且代码清晰,尤其是包管理部分有非常大的提升。此外,Rust 本身在高速发展中,整个社区非常有活力,提问基本都能够得到及时回复,这是我们从 Rust 生态中受益的地方。

使用 Rust 重写要注意的地方

学习成本


InfoQ:重写之后,原来那批 C++ 工程师都自学了 Rust 吗?


吴英骏:团队中有部分工程师之前就懂 Rust,只是未在工作中使用,这部分工程师还是比较容易转型的。我们也专门让一些工程师评估从零开始学 Rust 需要多久,绝大多数工程师一个月之内基本能够掌握 Rust,但还达不到全面掌握,只是可以使用 Rust 写一些代码。


整个过程比较顺利也得益于部分工程师会利用业余时间自学并将经验告知其他人,这是非常重要的。我认为,如果公司决定重写,必要条件是公司内部有一到两个,甚至更多使用 Rust 进行过实战的工程师,或者至少是愿意用业余时间时间并将经验传授给其他同学,这可以降低整个事情的难度,毕竟 Rust 的学习曲线是比较陡峭的。


InfoQ:从不同的语言基础开始学习 Rust 会有区别吗?


吴英骏:会有差异,而且比较明显。C++ 属于底层语言,掌握了 C++ 意味着你基本明白内存管理、指针、面向对象等理念。对于其他语言,比如 Python,最大的特点是简化编程,开发者不需要考虑内存管理等事情,但 Rust 是需要这方面基础的,所以不同的语言背景转换 Rust 的成本是不同的。

编译时问题


InfoQ:Rust 一直存在编译时的问题,你们有感受到吗?


吴英骏:Rust 确实存在编译时问题,但编译 C++ 相对也比较慢,但目前还在可承受的范围之内,如果时间比较长,工程师会定期查看编译进度,并尝试是否有办法可以缩短这个时间。


重写理由


InfoQ:你会建议什么类型的公司或者业务团队在什么情况下选择重写?


吴英骏:如果是在一个大型公司内部选择重写,大概率表明该项目不是那么重要,或者是核心项目的边缘模块,用户没有那么多、公司又有钱、有资源、有人力,这种情况下可以考虑重写。对创业公司而言,早期还有精力重写,一旦用户量上来了就会面临交付压力,基本不太会做这种决定。


此外,需要梳理清楚转换语言的理由,出于性能、安全性或者其他原因,而不是为了火。以数据库领域为例,现在很多成功的数据库距今已经诞生十年以上,经历了长时间的磨炼,其实转 Rust 的需求并不大。总的来说,我觉得是非常看中实际需求,需要全面了解需求再做决定。


生态环境


InfoQ:你觉得目前 Rust 的生态环境如何?


吴英骏:整体来看,Rust 的生态环境还比较不错,主要问题是在于缺少大型项目验证,比如 Go 最成功的项目是 Kubernetes。当然,我们现在已经看到有不少科技公司考虑使用 Rust 重写某些服务,比如 InnoDB,也看到很多公司加入了 Rust 基金会,比如 AWS、Google、Facebook 等,相信通过这些公司的长期支持,未来会出现一些非常不错的项目。Rust 能够获得这些大公司、初创企业(背后的投资人和投资机构)的支持,我相信社区最终能够比较好的发展。

团队状态


InfoQ:是否选择用 Rust 重写与团队规模和状态之间是否有关系?


吴英骏:我觉得重写和团队规模的关系不是很大,但我建议更加年轻的团队选择 Rust,当然这也因人而异。至于最终是否要转,也要遵循团队大多数人的意见,因为如果在学习了一段时间的 Rust 语言之后发现还是没有熟练掌握可能会有比较强的挫败感,这需要团队成员的共同努力,仅凭兴趣是很难做好的,仅凭兴趣也最好不要去创业以及对外提供商业化服务,这是非常不负责的。


2022-10-13 08:0018602
用户头像
赵钰莹 极客邦科技 总编辑

发布了 883 篇内容, 共 647.9 次阅读, 收获喜欢 2680 次。

关注

评论 1 条评论

发布
用户头像
c++工程师都是10年以上的精英了,而rust团队平均下来不到一年的经验,对开发代码的质量不需要担心吗?
2022-10-18 14:47 · 北京
回复
没有更多了
发现更多内容

「死磕」传统工业软件路径不通 他们给自己造了把梯子

ToB行业头条

肝了三个月Linux内核,面试薪资直接翻番,我才明白TA的重要性!

Yt

c++ Linux服务器开发 Linux内核 驱动开发

流式数据质量监控的技术调研及选型思考

字节跳动数据平台

sql 字节跳动 数据质量 流式数据 flik

推荐一款少见开源的支付类项目(Spring Boot+Shiro+MyBatis+Redis)

北游学Java

Java redis spring mybatis

金融云原生漫谈(一)|银行业如何快速提升应用研发效能和交付效率?

York

金融云原生漫谈(四)|如何构建高可用、高并发、高性能的云原生容器网络?

York

云原生 金融科技 高性能网络

直播系统聊天技术(六):百万人在线的直播间实时聊天消息分发技术实践

JackJiang

消息推送 即时通讯 IM 直播技术 直播聊天室

Swift 在手淘商品评价的技术重构与实践

阿里巴巴终端技术

ios swift 移动开发 客户端

纯 MongoDB 实现中文全文搜索

MongoDB中文社区

mongodb

静态代理模式——时间都去哪儿了

蝉沐风

设计模式 代理模式

资讯|WebRTC M96 更新

网易云信

大数据 WebRTC 开发

后端老司机的跨域之旅

勇哥java实战分享

后端 CORS

创业公司COO:用宜搭落地管理思想,打破数据壁垒|《102个开发者故事》第五期

一只大光圈

低代码 数字化转型 企业管理 钉钉宜搭

Rainbond 对接 Istio 原理讲解和代码实现分析

北京好雨科技有限公司

Kubernetes istio PaaS rainbond

音视频开发:FFmpeg时间戳详解

赖猫

音视频 ffmpeg

基于Paddle Serving&百度智能边缘BIE的边缘AI解决方案

百度开发者中心

飞桨

金融云原生漫谈(二)|中小银行破局之道:云原生架构转型全攻略

York

Git fork的学习笔记

Changing Lin

1月月更

Apache APISIX 社区双周报 | 功能亮点更新进行中

API7.ai 技术团队

开源 云原生 API网关 社区 Apache APISIX

定了!皮皮APP助力电子竞技游戏师职业技能标准发布!

联营汇聚

防火墙是什么?怎么理解?

行云管家

运维 网络安全 防火墙 堡垒机

堡垒机和防火墙的区别是什么?能防删库跑路吗?

行云管家

运维 网络安全 防火墙 堡垒机

Flutter VS React Native,跨端方案大 PK

融云 RongCloud

flutter React Native Discord

2021年度优质创作者评选名单公布!

InfoQ写作社区官方

热门活动

【MongoDB白皮书】DIRT和复杂性的高成本

MongoDB中文社区

mongodb

恒源云(GPUSHARE)_云GPU服务器如何使用FinRL?

恒源云

算法 框架 PyTorch

青藤:一招制敌!微隔离,让勒索软件不再横行

青藤云安全

2022开篇之作,Docker与微服务实战教程

编程江湖

金融云原生漫谈(三)|银行云原生基础设施构建:裸金属VS虚拟机

York

云原生 金融科技 新基建

为什么要避免在 Go 中使用 ioutil.ReadAll?

AlwaysBeta

Go 源码 io Go 语言

常见的跨域场景

郑州埃文科技

数据库 IP 跨域

那位用Rust重写数据库的创始人来复盘了:删除27万行C++代码,值吗?_架构_赵钰莹_InfoQ精选文章