HarmonyOS开发者限时福利来啦!最高10w+现金激励等你拿~ 了解详情
写点什么

我们为什么要选择小众语言 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:009584

评论

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

网站死链如何查看?Scrutiny for Mac网站分析检测工具来帮你!

Rose

Mac软件 mac网站分析检测工具 SEO 优化 Scrutiny 网站死链

Parallels虚拟机专用windows系统镜像(m1/intel) 含win系统安装教程

Rose

pd虚拟机 Mac双系统 win镜像 Parallels Desktop虚拟机

服务网格基础

蝉翼2u

微服务 云原生 服务网格

融合创新:传统企业数字化转型的业务、战略、操作和文化变革

天津汇柏科技有限公司

数字化转型

BricsCAD 24 mac中文完美破解版(CAD建模软件) 支持M和 macOS Sonoma 14 附安装教程

Rose

BricsCAD 23中文版 cad bricscad 24 BricsCAD 24破解版 BricsCAD 24下载

Mac上超好用的鼠标平滑滚动增强工具:SmoothScroll

Rose

Mac软件 鼠标工具 SmoothScroll 平滑滚动

华为云云绘本第2期:面对等保三级,谁还在瞎折腾?

华为云PaaS服务小智

软件开发 华为云

如何正确使用 Bean Validation 进行数据校验

得物技术

数据分析

基于开源IM即时通讯框架MobileIMSDK:RainbowChat v11.0版已发布

JackJiang

网络编程 即时通讯 IM

一篇全掌握!TDengine 在能源、电力、汽车、物流、工业制造等十大行业应用合集

TDengine

tdengine 时序数据库

HTML代码加固:保障网站安全

雪奈椰子

每日一题:LeetCode-739. 每日温度

Geek_4z9ami

Go 面试 算法 LeetCode 单调栈

Envoy网格基础概念

蝉翼2u

云原生 服务网格 envoy

Wireshark网络工具是什么?

小齐写代码

Slidepad for mac:给你的 macOS 添加一块 iPad 式的悬浮窗口

Rose

Slidepad mac效率软件

用Java实现冒泡排序:实用教程带你入门

SoFlu软件机器人

用Python实现高效数据记录!Web自动化技术助你告别重复劳动!

测试人

软件测试

PD虚拟机系统镜像 原版纯净的Windows系统安装包

Rose

windows 11 pd虚拟机 win系统下载

基于Express的微信公众号开发

派大星

Express 微信公众号开发

实现高效 Spring RESTful API:最佳实践

Apifox

Java 程序员 Spring Boot 后端 REST API

怎样解决注塑行业的难点与现状?

万界星空科技

mes 万界星空科技 万界星空科技mes 注塑MES 注塑行业

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