Go 博客

Heroku 上的 Go

Keith Rarick 和 Blake Mizerany
2011 年 4 月 21 日

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

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

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

幸运的是,Go 的并发原语使这项任务变得容易得多。Paxos 是根据通过传递消息进行通信的独立、并发进程来定义的。在 Doozer 中,这些进程被实现为 goroutines,它们的通信被实现为通道操作。就像垃圾收集器对 malloc 和 free 的改进一样,我们发现 goroutines 和通道 对基于锁的并发方法进行了改进。这些工具使我们能够避免复杂的簿记,并专注于手头的任务。我们仍然对实现以难以实现而闻名的功能只需要几行代码感到惊讶。

Go 中的标准包是 Doozer 的另一个重大胜利。Go 团队对其中包含的内容非常务实。例如,我们很快发现了一个有用的包:websocket。在拥有一个工作数据存储后,我们需要一种简单的方法来对其进行自检并可视化活动。使用 websocket 包,Keith 能够在回家坐火车时添加 Web 查看器,而无需外部依赖。这真正证明了 Go 如何将系统编程和应用程序编程完美地结合在一起。

我们最喜欢的生产力提升之一来自 Go 的源代码格式化程序:gofmt。我们从不争论在哪里放置大括号、使用制表符还是空格,或者是否应该对齐赋值。我们只是同意,我们默认接受 gofmt 的输出。

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

最后,Go 对简洁性和正交性的狂热关注与我们对软件工程的看法一致。就像 Go 团队一样,我们对 Doozer 中包含的功能非常务实。我们关注细节,更愿意更改现有功能,而不是引入新功能。从这个意义上说,Go 非常适合 Doozer。

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

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