分享 CockroachDB 团队使用 Go 的体会。
在 7 年前(2051 年 11 月 3 日),选择用 Go 实现 CockroachDB。现在回顾当初的选择。
许多开发人员问我们的第一个问题是,我们在使用垃圾收集语言 Go 编写分布式数据库方面的经验是什么。JVM 垃圾收集是出了名的昂贵(耗资源),所以我们用 Go 构建 CockroachDB 不是冒性能风险吗?
事实上,当您构建高性能分布式系统时,您只有少数几种语言可供选择,其中 C++、Java 和 Go 位居榜首。Java 的已知性能问题使其没有吸引力。而且,尽管我们中的许多人的职业生涯都是用 C++ 开发的,但构建我们自己的库所需的努力使编写分布式数据库的本已艰巨的任务更加复杂。名单上的下一个是Go。
尽管对于项目中的几乎每个开发人员(包括创始人)来说,Go 都是一门全新的语言,但它对库、接口和工具的支持使其成为 CockroachDB 的正确选择。
也许最有力的指标表明 Go 非常适合:之前缺乏对语言的接触并不是贡献者的障碍。我们现在有 67 名贡献者参与该项目,CockroachDB 已经从一个空的 Github 项目变成了 125,000 行非生成的 Go 代码,以及少量的 C++ 和 .proto 文件。不可否认,管理代码复杂性受到语言选择的影响,这在开源环境中尤为重要。
截至 2022 年 7 月,CockroachDB 现在有579 名 GitHub 贡献者[1],其中 89.6% 是用 Go 编写的,还有少量的 TypeScript、Starlark 和 Yacc,以及一些其他语言。
很难量化 Go 对 C++ 甚至 Java 带来的生产力的影响。Go 旨在扩展到大型代码库,强调功能的简单性和正交性。强制的代码风格、简单的导入和自动导入管理、种类繁多的 linter、简单(和最小)的编程习惯用法……所有这些 Go 的属性对于干净、可理解的代码都很重要。
与 Java 相比,我们赞赏对实现而不是 OOP 和抽象的紧密关注:接口可以在需要时添加,而不是作为初始步骤,通常不是必须的步骤。与 C++ 相比,我们欣赏自动内存管理以及完成某事的方法很少不止一种,例如使用静态和一次性初始化程序。我们很好地利用了通道进行同步,尽管我们会注意到有效地使用它们是有技巧的。
当时,还有待观察的是所有这些 Go 代码将如何执行,仍在 CockroachDB 中构建核心功能,所以很多性能分析还没有到来。然而,在我们过去的经验中,我们将一个大型系统从 Java 移植到 Go,这大大减少了它的内存占用和垃圾收集开销。
七年过去了,有了很多额外的核心功能和大量的性能分析,我们仍然对 Go 感到非常满意。
想了解更多关于 Go 垃圾收集在 CockroachDB 中的工作原理吗? Go 中的垃圾收集会导致应用程序暂停。幸运的是,Go 还提供了许多手动调整来控制最终在垃圾堆顶部的内容。
CockroachDB 如何编写一个庞大而复杂的 Go 应用程序[2],在这个长达一小时的深度(深度)潜水视频中,Cockroach Labs 首席技术官兼联合创始人 Ben Darnell 讨论了 CockroachDB 如何优化内存使用以缓解与垃圾收集相关的问题并改进通道的使用以避免死锁。
579 名 GitHub 贡献者: https://github.com/cockroachdb/cockroach
[2]CockroachDB 如何编写一个庞大而复杂的 Go 应用程序: https://www.cockroachlabs.com/community/tech-talks/challenges-writing-massive-complex-go-application/
推荐阅读