为什么 Discord 不断重写其技术栈
发布: (2026年5月5日 GMT+8 11:30)
4 分钟阅读
原文: Dev.to
Source: Dev.to

Discord 多次重写他们的技术栈——并不是因为他们做错了,而是因为他们已经超出了原有架构的承载能力。
2013 — 初始栈
- Elixir 用于实时消息
- Python 用于 API
- Go 用于微服务
- MongoDB 用于存储
- Electron 用于桌面端
标准的创业公司选择。快速上线,后续再完善。
2017 — 必须放弃 MongoDB
- 500 万用户;MongoDB 赶不上增长。
- 切换到 Cassandra(12 节点)——运行良好。
- 到 2022 年集群扩展到 177 节点;维护变得痛苦,成本上升。
- 转而使用 ScyllaDB。
一个问题。九年。三种数据库。
2019 — Elixir 对所有场景都不够快
在 Elixir 中对大数据集进行排序每次需要 170 ms。
在 Discord 的规模下,这完全不可接受。
- 将该组件重写为 Rust。
- 延迟降至 1 ms。
这就是更换的全部原因。
2020 — Go 的垃圾回收器成了敌人
Discord 的 Read States 服务会记录每条已读消息,并在每次应用交互时被调用。
- Go 的垃圾回收器每 2 分钟 运行一次,扫描全部内存。
- 当缓存了数百万用户时,扫描会导致延迟峰值。
调优和升级 Go 均未奏效。
- 将服务重写为 Rust(无 GC,内存即时释放)。
- 延迟从毫秒级降至微秒级。
疫情期间月活跃用户激增至 1 亿,这使得 Rust 重写成为必然,而非偶然。
从未改变的部分
- Elixir 仍然负责实时消息;BEAM VM 在数百万并发进程和即时重启方面表现出色。
- Python 仍然为 API 提供动力。
- Electron 仍然运行桌面客户端。
- React Native 最终在多年分离的代码库后统一了 iOS 与 Android。
并非所有东西都需要更换。
背后的模式
每一次切换都有明确的触发点——某个指标突破阈值且无法通过调优解决。
- 没有一次切换是为了追热点,也没有提前切换。
这篇文章的教训不是哪种语言或数据库最好,而是要使用有效的工具,在数据逼迫时进行切换,并且要明白 为什么 要切换。
Discord 并不是在第一天就为 5 亿用户而构建。他们为今天而构建,为明天而修正。
Also published on Medium.