2天时间,聊今年最热的 Agent、上下文工程、AI 产品创新等话题。2025 年最后一场~ 了解详情
写点什么

我们为什么要选择小众语言 Rust 来实现 TiKV?

  • 2017-09-21
  • 本文字数:2753 字

    阅读完需:约 9 分钟

本文是 InfoQ 策划的语言专题其中的 Rust 篇。其他更多内容将在月底结集推出,敬请期待。Rust 是什么?

Rust 是由 Mozilla 研究室主导开发的一门现代系统编程语言,自 2015 年 5 月发布 1.0 之后,一直以每 6 周一个小版本的开发进度稳定向前推进。语言设计上跟 C++ 一样强调零开销抽象和 RAII。拥有极小的运行时和高效的 C 绑定,使其运行效率与 C/C++ 一个级别,非常适合对性能要求较高的系统编程领域。利用强大的类型系统和独特的生命周期管理实现了编译期内存管理,保证内存安全和线程安全的同时使编译后的程序运行速度极快,Rust 还提供函数式编程语言的模式匹配和类型推导,让程序写起来更简洁优雅。宏和基于 trait 的泛型机制让 Rust 的拥有非常强大的抽象能力,在实际工程中尤其是库的编写过程中可以少写很多 boilerplate 代码。

Rust 的生态

Rust 由于有 Cargo 这样一个非常出色的包管理工具,周边的第三方库发展非常迅速,各个领域都有比较成熟的库,比如 HTTP 库有 Hyper,异步 IO 库有 Tokio, mio 等,基本上构建后端应用必须的库 Rust 都已经比较齐备。 总体来说,现阶段 Rust 定位的方向还是高性能服务器端程序开发,另外类型系统和语法层面上的创新也使得其可以作为开发 DSL 的利器。

Rust 的使用情况

Rust 作为一种新锐的语言,具备其独有的优越性,目前在全球落地的项目中比较知名的比如,Dropbox 的后端分布式存储系统(闭源),Firefox 的新的内核 Servo,操作系统 Redox,当让包括 PingCAP 的分布式数据库 TiDB 的存储层 TiKV,TiKV 作为其中的一员,自上线以来非常引人注目,在 GitHub Rust 语言的全球排名项目中,基本上一直徘徊在前几名的状态。

TiKV 是一个事务型分布式 Key-Value 数据库,是作为 TiDB 项目的核心存储组件,也是 Google 著名的分布式数据库 Spanner 的开源实现。对于这样一个大型的分布式存储项目,在 TiKV 的开发语言选择上,我们选择了 Rust 语言从零构建。在今天这个文章里,我想详细聊聊什么驱动我们选择了 Rust。

对于数据库这类基础软件来说,在过去很长的一段时间,我们能选择的编程语言基本只有 C/C++。Java 和 Go 这类编程语言的主要问题还是由于 GC 引起抖动,尤其在读写压力比较大的情况下。另外一方面,对于 Go 来说,一个非常吸引人的特性是轻量级线程 Goroutine,对于开发者来说极大的降低的开发并发程序的复杂度,但是相应的代价是 Goroutine 的 Runtime 会带来额外的上下文切换开销。 对于数据库这样的基础软件,性能显然是很重要的,另一方面,系统需要尽可能的保持 ”确定性”,在性能优化和调试阶段能够更加方便,但是引入 GC 和另一个 Runtime 的问题是会增加这种不确定性,所以在很长的时间内,C/C++ 是唯一的选择。

TiKV 这个项目起始于 2015 年底,当时也是在 Pure Go / Go + Cgo / C++11 / Rust 几个语言之间纠结,虽然我们的核心团队有大量的 Go 语言开发经验,另外 TiDB 的 SQL 层是完全采用 Go 语言开发,Go 带来的开发效率的极大提升也让我们受益良多,但是在存储层的选型上,我们首先排除的就是 Pure Go 的选项,理由也很简单,在底层,我们已经决定接入 RocksDB,RocksDB 本身就是个 C++ 的项目,而 Go 的 LSM-Tree 的实现大多成熟度不太够没有能和 RocksDB 相提并论的项目,如果选 Go 的话,只能选择用 Cgo 来 bridge, 但是当时 Cgo 的问题同样明显,在 2015 年底,在 Go code 里调用 Cgo 的性能损失比较大,并不是在 Goroutine 所在的线程直接 Call cgo 的代码,而且对于数据库来说,调用底层的存储引擎库是很频繁的,如果每次调用 RocksDB 的函数都需要这些额外的开销的话,非常不划算,当然也可以通过一些技巧增大 Cgo 这边的调用的吞吐,比如一段时间内的调用打包成一个 cgo batch call,通过增加单个请求的延迟来增大的整体的吞吐,抹平 cgo 调用本身的开销,但是这样一来,实现就会变得非常复杂,另一方面,GC 的问题仍然没有办法彻底的解决, 在存储层我们希望尽可能高效的利用内存,大量使用 syscall.Mmap 或者对象复用这些有些 hacky 的技巧,会让整体的代码可读性降低,我的判断仍然是得不偿失。

所以后来认真在考虑的只剩下 Rust / C++11,先说 C++11 的问题,其实 C++11 也没啥问题,性能上肯定没问题,RocksDB 是 C++11 写的,在纠结了一小段时间后,我们认真评估了一下我们的团队背景和要做的东西,最后还是没有选择 C++,原因主要是:

  1. 我们核心团队过去都是 C++ 的重度开发者,也基本都有维护过大型 C++ 项目的经历,每个人都有点心里阴影… 悬挂指针、内存泄漏、Data race 在项目越来越大的过程中几乎很难避免,当然你可以说靠老司机带路,严格 Code Review 和编码规范可以将问题发生的概率降低,但是一旦出现问题,Debug 的成本很高,心智负担很重,而且第三方库不满足规范怎么办。
  2. C++ 的编程范式太多,而且差异很大,又有很多奇技淫巧,统一风格同样也需要额外的学习成本,特别是团队的成员在不断的增加,不一定所有人都是 C++ 老司机,特别是大家这么多年了都已经习惯了 GC 的帮助,已经很难回到手动管理内存的时代。
  3. 缺乏包管理,集成构建等现代化的周边工具,虽然这点看上去没那么重要,但是对于一个大型项目这些自动化工具是极其重要的,直接关系到大家的开发效率和项目的迭代的速度。而且 C++ 的第三方库参差不齐,很多轮子得自己造。

Rust 在 2015 年底已经发布了 1.0,Rust 有几点特性非常吸引我们:

  1. 内存安全性
  2. 高性能 (得益于 llvm 的优秀能力,运行时实际上和 C++ 几乎没区别),与 C/C++ 的包的亲缘性
  3. 强大的包管理和构建工具 Cargo
  4. 更现代的语法
  5. 和 C++ 几乎一致的调试调优体验,之前熟悉的工具比如 perf 之类的都可以直接复用
  6. FFI,可以无损失的链接和调用 RocksDB 的 C API

其中放在第一位的是安全性,之前在 C++ 中提到的内存管理和避免 Data race 的问题,我相信虽然靠老司机是可以解决,但是仍然没有在编译器层面上强约束,把问题扼杀在摇篮之中解决的彻底,Rust 这点非常符合我的口味, 对于大型项目来说,永远不要把软件的质量押宝在人身上,人永远会犯错,人是不稳定的。Rust 的做法虽然增加了上手的门槛,但是我认为是值得的。另一方面,Rust 又是一个非常现代化的编程语言,现代的类型系统,模式匹配,功能强大的宏,trait 等在熟悉以后会很大的提升开发效率,其实如果选择 C++ 的话,算上 Debug 的时间,Rust 的开发效率不算低,在我们的实践经验中,我们的工程师从零开始接触 Rust,到能够高效进行开发的时间大概是 1 个月,而且熟练的工程师的 Rust 开发效率几乎是和写 Go 差不多的。

小结

总体来说,Rust 这门新兴的语言对于国内大多数开发者来说会显得比较陌生,但是并不妨碍 Rust 已经在世界范围内作为公认的 C/C++ 的有希望的挑战者。我认为,从长远来看,在对内存安全性和性能有严苛要求的场景,Rust 将会有广阔空间。

2017-09-21 19:0010254

评论

发布
暂无评论
发现更多内容

爬虫“学前班”,记住这些不踩坑!

华为云开发者联盟

爬虫 数据 搜索

来自阿里面试官的Java面试连珠炮,让你自由发挥你能撑到哪一步?

Java架构之路

Java 程序员 架构 面试 编程语言

WebSocket-技术专题-服务器端消息推送

码界西柚

「深度解析」告诉你如何选择容器存储

焱融科技

Kubernetes 容器 云原生 焱融科技 分布式文件存储

程序员不愿意说的秘密!Java进阶架构师必看:架构完美设计+程序员三门课+架构修炼之道

Java架构追梦

如何生成 Flink 作业的交互式火焰图?

Apache Flink

flink

即构SDK10月迭代:新增多款语音音效、外部采集码流控制及Android SDK 最低支持操作系统版本调整

ZEGO即构

android RTC

30 岁的码农人生 ——人生至暗时,你依然能窥见光明

苹果看辽宁体育

程序员 程序人生 感悟

求职时这样回答问题你就输了!来自IT类面试官视角的深度解读

华为云开发者联盟

面试 软件开发

你有时间吗?

池建强

时间

10 张图打开 CPU 缓存一致性的大门

小林coding

缓存 cpu 操作系统 计算机

阿里巴巴专属著作超赞,就是名字起得有点狂“成神之路”???

Java架构师迁哥

搜狗搜索或成为企鹅号流量入口:腾讯欲实现自己的流量闭环

石头IT视角

基于阿里云容器的CI/CD落地实践

LorraineLiu

阿里云 k8s Helm jenkins CI/CD

小程序云开发实战:从0搭建科技爱好者周刊小程序

薛定喵君

微信小程序 小程序云开发 云开发

最近程序员频繁被抓,如何避免面向监狱编程!?

Java架构师迁哥

MySql从青铜到王者晋级之路,阿里大牛经验总结让牛少走弯路!

Java架构之路

Java 程序员 架构 面试 编程语言

Vidyo的技术特点都有哪些?

dwqcmo

音视频 集成架构 解决方案 智能硬件

【JSRC小课堂】Web安全专题(一)认证缺失和认证缺陷漏洞

京东科技开发者

WEB安全

什么是动态代理

Rayjun

Java 动态代理

我服了,难倒无数程序员的源码面试,就这样被轻轻松松讲透彻

小Q

Java 学习 源码 架构 面试

uni-app支持PC宽屏适配

崔红保

uni-app 大前端

分布式文件存储QoS硬核黑科技,真香

焱融科技

高性能 存储 HPC 分布式文件存储 QoS

个人计算机、工作站、服务器的主要区别

德胜网络-阳

接口测试工具

测试人生路

接口文档 接口测试

API生态的发展与机遇:从5000组数据看中国API生态与开发者现状

华为云开发者联盟

华为 API

一文读懂GaussDB(openGauss) 的六大关键技术特性

华为云开发者联盟

数据库 数据 存储

谈谈贪官污吏

空山

以A.I.之力打破方言沟通障碍 科大讯飞重磅发布智慧翻译系统

Talk A.I.

大企程序员亲身经历告诉你,CRM系统,自己的才是最好的

Learun

敏捷开发

实用!8个 chrome插件玩转GitHub,单个文件下载小意思

程序员小富

GitHub

我们为什么要选择小众语言Rust来实现TiKV?_语言 & 开发_黄东旭_InfoQ精选文章