Go 博客

Heroku 上的 Go

Keith Rarick 和 Blake Mizerany
2011年4月21日

本周的博客文章由 Keith Rarick Blake Mizerany 撰写,他们是 Heroku 的系统工程师。用他们自己的话说,他们“食、饮、睡都离不开分布式系统”。在这里,他们讨论了使用 Go 的经历。

构建分布式系统带来的一大问题是物理服务器的协调。每台服务器都需要了解整个系统的各种事实。这些关键数据包括锁、配置数据等等,并且即使在数据存储故障期间也必须保持一致性和可用性,因此我们需要一个具有可靠一致性保证的数据存储。我们对这个问题的解决方案是 Doozer,这是一个用 Go 编写的新型、一致的、高可用性数据存储。

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

幸运的是,Go 的并发原语大大简化了任务。Paxos 是根据独立的、并发的进程定义的,这些进程通过消息传递进行通信。在 Doozer 中,这些进程实现为 goroutine,它们的通信实现为通道操作。就像垃圾收集器改进了 malloc 和 free 一样,我们发现 goroutine 和通道改进了基于锁的并发方法。这些工具使我们能够避免复杂的簿记工作,专注于手头的问题。对于实现如此一个以困难著称的任务所需的代码行数之少,我们仍然感到惊讶。

Go 的标准包是 Doozer 的另一个巨大优势。Go 团队在纳入哪些包方面非常务实。例如,我们很快发现有用的一个包是 websocket。一旦我们有了一个可用的数据存储,我们需要一种简单的方法来内省它并可视化活动。使用 websocket 包,Keith 在乘坐火车回家时就添加了网络查看器,而且无需外部依赖。这真实地证明了 Go 在系统和应用编程方面的出色结合。

我们最喜欢的生产力提升之一是由 Go 的源代码格式化工具提供的:gofmt。我们从未争论过大括号的位置、制表符与空格的选择,或者是否应该对齐赋值。我们只是同意,最终以 gofmt 的默认输出为准。

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

最后,Go 对简单性和正交性的狂热关注与我们对软件工程的看法一致。就像 Go 团队一样,我们在 Doozer 中纳入哪些功能方面是务实的。我们抠细节,宁愿修改现有功能也不愿引入新功能。从这个意义上说,Go 与 Doozer 是完美的匹配。

我们已经考虑了 Go 的未来项目。Doozer 只是一个更大系统的开端。

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