1. 首页>>分享

ClickHouse的抉择:用Rust重构150万行C++代码?安全与性能的博弈

作者 | Joab Jackson

译者 | 平川

策划 | Tina

本文最初发布于 THENEWSTACK 博客。

图片

ClickHouse 是个开源的分析型数据库系统,它含有 150 万行代码,当中大部分是用 C++ 编写的。大家都知道,这是一种不安全的语言,因为用其编写的代码可能会让恶意攻击者利用那些难以发现的漏洞 。

就常常会有文章表述到,Rust编程语言由于其在内存以及线程安全方面具备的优秀处理能力能够将C/C++取而代之。并且存在着许多大型代码库,像是Linux内核采用C编写,Windows采用C++编写,它们使用的是几十年前的语言变体,所以有很多人都在思考同样的问题。

踏上这条道路的是 ClickHouse 的维护者,其目标在于对 ClickHouse 里用 C++ 编写的功能予以转换,甚至还有可能重写整个代码库。

在ScylaDBvirtual P99大会之上,进行主题演讲之际,Clickhouse首席技术官以及联合创始人Alexey Milovidov,提出了一个关键的问题,那便是:“要是今天重新起始,我们会运用Rust语言去编写Clickhouse吗?”。

Milovidov 做了解释,那就是,最终,核心开发人员挑选了一条渐进式迁移路线,他们先是把 Rust 整合到构建系统里,之后又为各种功能构建模块。

在这个进程里边,他们碰上了数目繁多的挑战,当中涵盖着要保证构建进程具备可重现的特性,以及对依存关系进行管理 。

Milovidov表明,“Rust或许堪称完美,然而一旦你把C++与Rust一同加以运用,说不定就会出现问题” 。

C++ 的代价是需要一个巨大的构建系统

就如同 Milovidov 所点明的那般,运用 C++ 去编写关键任务应用程序依旧存在诸多优势 ,他讲道 ,“它技术已然成熟 ,受到广泛认可 ,应用极为广泛 ,招聘拥有 C++ 技能的人才颇为容易 ,并且大学依旧在教授 C 语言 。”。

他又补上了另外的话,称,“然而选用C++是得拿出不少精力来的”。你会碰到内存损坏方面的状况,还会遭遇段错误的情形,以及免不了会出现竞态相关的条件问题,总之均是这样的情况,情形如此这般。

实际上,ClickHouse 最终搭建起一个“庞大的”出于通过如此方式来确保一切这般类型的漏洞均可被精准捕捉以及妥善修复之目的而基于 CMake 的持续集成系统。

其代码库,平均每天,有七十 个拉取请求,以及一百四十五次提交,持续集成系统,会进行“数十亿次测试”,实际上,是通过不同的组合,执行“数千万次”的独立测试, 所有这些,都旨在确保,新代码不会引入任何新的漏洞。

图片

C++是不是会让人感到头疼呀,Milovidov因为这个专门去筹备好了仅仅一整张的幻灯片呢……

Rust 之旅

觉得也许是时候用Rust重写了的核心开发团队,这种语言提供了内存安全和线程安全,它提供的库也是以新兴的数据标准方面更多,像Apache Iceberg,并且,所有年轻且有抱负的软件工程师似乎正会被这种语言所吸引。

然而,要把 ClickHouse 完全用 Rust 进行重新编写,将会耗费数年的时间。

相反,该团队选取了改用一种递嬗办法为之,把 ClickHouse 体系的各个构成部分运用 Rust 重新制作,接下来借助 Corrosion 跟 CMyake 予以整合。

起初呢,他们给SQL增添了个为BLAKE3哈希所设的函数,此函数是用Rust编写而成,并且被封装成C++接口。紧接着,在外部贡献者的助力之下,他们强化了命令行界面clickhouse - client,对历史记录管理以及导航体验予以了优化。除此之外,他们接纳了一项SQL替代方案的拉取请求,这个方案是一个名为PRQL(流水线关系查询语言)的库,同样是借助Rust语言开发而来的。

图片

伴随着对于Rust的信心日益增强,项目规模不断地变大。紧接下来的Rust测试,是去集成一个建基于Rust的Delta Lake格式库Delta - kernel - rs。这分明是一个Rust库超越C++库的具有代表性的实例,就算C++在未来能够达成相似的功能,其速度于Rust而言也远远比不上。

Milovidov讲,ClickHouse原本能够自行借助C++去编写一个Delta Lake库,然而此项工作会“毫无价值”。可叹有些程序员就得花费大量时间去编写解析JSON文件,以及重定向HTTP请求的代码。直接选用Databricks官方发布的Rust版本无疑要省事许多。

Rust 和 C++ 的危险之处

经由这些实验,ClickHouse开发人员知悉了Rust语言的某些欠缺之处,尤其是在与C++一同运用的时候。

一份挑战是可重现构建,它作为保障代码安全、防止意外从互联网下载的关键所在。先前,Clickhouse于C++环境里达成了可重现构建,然而转向 Rust 语言之后,他们必须得再次思索怎样确保构建过程彻底隔离。

为Rust程序去写C++ 中的封装器,实实在在成了一件颇具难度 的事情。去判定到底是要在C++ 里分配内存,还是在Rust里分配内存,这番思维权衡常常让人头疼不已。于这个进程当中,模糊测试方面的工具以及Clickhouse的CI运作系统,给错误排查的相关工作给予了极大程度的助力 。

每种语言在压力下的表现也有所不同。

Miloovidov断定,参照C++来看,Rust程序以及库出现恐慌的频次处在偏高状态。这些恐慌情形,有的源自程序自身过失;该种情况意味着它的库需要更完备更加周全的测试。还有些恐慌是原本应该算作异常终止的,被代码创作者替换成了恐慌终止;而这种行为在Rust社区里通常是不被认可接受的。

在批处理作业方面,恐慌这种情况是能够被接受的,然而,在实时运行的服务器以及交互式应用程序方面,恐慌这种情形便是不太被待见的了。

有个叫 Miloovidov 的人说,,说到 Rust 库,其存在这样的显著情况,那就是常常甚至在不合适的状况下都会过度运用 panic,鉴于此,我们必须逐个去考察筛选并且修正这些状况,不然的话,我们的服务器应用程序就会无端突然终止,就是这样。

图片

Miloovidov宣称,Rust代码不该这般时不时地诱发panic,。

恰似 Clickhouse 团队于 C++ 库之中察觉到了得修复的 Bug 那般,他们于 Rust 库里面也察觉到了数量众多的 Bug。

有一个名为 Miloovidov 的,就深入地去探讨那般具体事情了,这事即把 C++ 以及 Rust 在同一个环境里进行混合使用之时所浮现出的诸多特别问题,这里面包含着使用 sanitizer 这种情况,还有管理交叉依赖这种状况,以及存在交叉编译这种情形,甚至还有代码可组合性这般具体问题,这里面有不少问题是源自于所需构建系统的复杂性的。

有一个转向 Rust 的意想不到的副产物,那就是依赖的增加,对于整个代码库而言,Clickhouse仅仅有着156个依赖项,在引入 Rust 模块之际,他们发觉自身得额外去管理672个传递性依赖(Miloovidov打趣称,依旧不像使用NPM时那般多)。

Clickhouse 的结论

眼下,Clickhouse 做出抉择,不会运用 Rust 全部重新编写数据库系统。不过,他们对这门语言持有足够的信心,进而接纳第三方贡献者呈上他们自身写出的 Rust 语言Clickhouse 插件, .

Miloovidov 说,“Rust 是一门伟大的语言”。

点击流数据处理系统ClickHouse发表了一篇关于,从C语言变更至Rust语言的建议文章,其链接为https://thenewstack.io/moving-from-c-to-rust-clickhouse-has-some-advice一个拥有特定网址的链接 。

声明:本文为 InfoQ 翻译,未经许可禁止转载。

本文采摘于网络,不代表本站立场,转载联系作者并注明出处:https://mjgaz.cn/fenxiang/279352.html

联系我们

在线咨询:点击这里给我发消息

微信号:13588888888

工作日:9:30-18:30,节假日休息