Go 博客

Heroku 的 Go

Keith Rarick 和 Blake Mizerany
2011 年 4 月 21 日

本周的博文由 Heroku 的系统工程师 Keith RarickBlake Mizerany 撰写。他们用他们自己的话说,“吃、喝、睡分布式系统”。在这里,他们讨论了他们使用 Go 的经验。

构建分布式系统时遇到的一个大问题是物理服务器的协调。每台服务器都需要了解系统整体的各种信息。这些关键数据包括锁、配置数据等,并且必须在数据存储失败的情况下保持一致和可用,因此我们需要一个具有可靠一致性保证的数据存储。我们解决这个问题的方案是 Doozer,一个用 Go 编写的、新的、一致的、高可用的数据存储。

Doozer 的核心是 Paxos,这是一系列在不可靠节点组成的不可靠网络中解决一致性问题的协议。虽然 Paxos 对于运行容错系统至关重要,但它以实现困难而闻名。即使是在线可以找到的示例实现,尽管为了教育目的进行了简化,但仍然很复杂且难以理解。现有的生产系统声誉更差。

幸运的是,Go 的并发原语使这项任务变得容易得多。Paxos 在概念上是独立、并发运行的进程,它们通过传递消息进行通信。在 Doozer 中,这些进程被实现为 goroutine,它们的通信被实现为 channel 操作。就像垃圾回收器改进了 malloc 和 free 一样,我们发现 goroutine 和 channel 比基于锁的并发方法有所改进。这些工具使我们能够避免复杂的簿记,并专注于当前的问题。我们仍然对我们用如此少的代码量实现了如此出名的困难的东西感到惊讶。

Go 中的标准包是 Doozer 的另一个巨大优势。Go 团队在软件包的组成上非常务实。例如,我们很快发现有用的一个包是 websocket。一旦我们有了可用的数据存储,我们就需要一种简单的方法来内省它并可视化活动。使用 websocket 包,Keith 可以在回家的火车上添加 Web 查看器,而无需外部依赖。这真正证明了 Go 在系统编程和应用程序编程方面的结合有多么出色。

Go 的源代码格式化工具:gofmt,为我们带来了最喜欢的生产力提升之一。我们从未争论过花括号的位置、制表符还是空格,或者是否应该对齐赋值。我们简单地同意,这一切都由 gofmt 的默认输出决定。

部署 Doozer 非常简单,令人满意。Go 构建静态链接的二进制文件,这意味着 Doozer 没有外部依赖;它是一个可以复制到任何机器并立即启动以加入运行的 Doozers 群集的单个文件。

最后,Go 对简洁性和正交性的狂热关注与我们对软件工程的看法一致。与 Go 团队一样,我们在 Doozer 的功能选择上也很务实。我们注重细节,宁愿修改现有功能而不是引入新功能。从这个意义上说,Go 与 Doozer 是完美匹配。

我们已经为 Go 规划了未来的项目。Doozer 仅仅是更大系统的一个开始。

下一篇文章:Go 与 Google App Engine
上一篇文章:Introducing Gofix
博客索引