字节跳动在 Rust 方向的探索和实践
吴迪 / 火山引擎 基础架构服务框架工程师
CloudWeGo-Volo 负责人
2019 年加入字节跳动架构组 负责微服务框架开发
我们为什么选择了 Rust 语言
Go 语言的桎梏
- 深度优化困难
- 工具链和包管理不够成熟
- 抽象能力较弱
- 零成本抽象
- 不用的东西,不需要为之付出代价
- 用到的东西,也不可能做得更好
- Thrift 编解码抽象
- Apache Thrift 抽象出 TProtocol、TTransport(interface) 用于支持多种不同 Protocol、Transport 组合
- 直接依赖具体的 Binary Protocol struct 实现
- Interface 的代价
- interface 是动态分发(运行时通过类型元数据和指针 去动态调用所需方法)
- 无法 inline
Sonic: 性能最好的 Go JSON 库
Rust 三大优势: 性能 安全 协作
安全性
- Rust 1.0 之后,在非 unsafe 代码中,不可能出现内存安全问题
- 推论:一切内存 / 并发安全问题,都是 unsafe 代码导致的
协作: 工程实践出来的语言 -> 信任别人的代码
• 智能的编译器
• 完善的文档
• 齐全的工具链
• 成熟的包管理
Rust 开发者调研
业界的应用案例
Rust for Linux: Linux 内核至今为止,唯一接受的 C 以外的语言
和 C++、Go 对比
我们做了什么
公司内(之前)生态情况: 0
如何建立生态
基础库
- 必需基础库:日志、监控、链路追踪、mysql、redis、动态配置、mq • 非必需基础库:发动群众的力量
开发框架
- Web 框架:基于 Axum
- RPC 框架:CloudWeGo/Volo
- 异步运行时:Monoio
发现的问题
- 会遇到一些开源库的 bug / 不完全满足需求
- 要能够自己去解决问题 / 提 PR / 依赖自己 Fork 版本
- 很多一线同学很喜欢,想要使用
- 但是 Leader 会担心,团队只有一个人会 Rust,如果人员变动无法维护
如何推动落地
- 快速达成 MVP,开发个人、POC 项目
- 很多工程师对 Rust 感兴趣,只是缺少一个契机 / 有人带头
- 寻找典型业务,共同开发,获得收益:Proxy / 重计算但逻辑简单
- 需要一些前期投入,但是是值得的
实践:nightly + GAT + TAIT
- nightly:真香
- GAT:generic associated types
- TAIT:type alias impl trait
落地成果
业务 A(Proxy 类):
CPU Usage 630% -> 380%
MEM 9GB -> 2GB
P99 150-200ms -> 20-35ms A VG 4-5ms -> 1.5ms
业务 B(有大量业务逻辑): CPU 400% -> 130%
业务C:
CPU -50%,MEM -95%
业务 D(线上重要业务): 吞吐 +95.96%
成本 -48.97% avg -14.29% p99 -18.18% p999 -10.26%
算一算
- 437 元 / CPU*年
- 业务使用 10000 核,节省 5000 核
- 5000*437 = 2,185,000 元 / 年
- 开发/办公成本:20w*6月=1,200,000元
- 第一年净收益:985000 元
- 实际上收益远不止这个值,CPU 成本没这么便宜,开发成本也远 达不到这么高
展望未来:机遇与挑战
Rust 现状
- 一句话:好用,但不够好用
- 抽象能力表达能力很强,但是高阶抽象还有些问题(基本不会用到)
- 异步生态较为完善,但是和同步存在一些割裂,易用性也还可以提升
- Rust 2024 正在解决这些问题
- 开发者喜爱,想要尝试,用户忠诚度极高
- 开源项目爆炸性增长,关注度极高
- 越来越多公司接受并使用
Rust 应用的方向
- 基础架构组件
- 工具
- Linux
- 服务端
- WebAssembly
- 嵌入式
- OS
面临的挑战
- Rust 职位不够多Rust 人才不够多
- Rust 在中国名声不够响(与 Go 相比)
- Rust 缺少像 k8s 一样的杀手级应用(也许 Rust for Linux 算?)
机遇
- 降本增效
- 对底层技术越来越关注
- 关注度足够高,社区快速发展
拥抱开源,回馈社区