21.1 Heroku:一个使用 Go 的高度可用一致数据存储
Heroku 是一家位于美国旧金山的硅谷公司,最近被 Salesforce.com 公司(它为 Ruby 和 Rails、Java、Clojure 和 node.js 应用程序提供强大的、可扩展的、特别是非常易于管理的云主机)收购。Heroku 的两位工程师,Keith Rarick 和 Blake Mizerany 设计了一个开源的 “分布式启动系统”,名为 Doozer,用于管理跨集群机器的进程,并从实例故障和网络故障中优雅地恢复分区。其中一个需求是,他们需要可靠地同步和在许多服务器之间共享信息。
系统中的每台服务器都需要有很多关于系统整体的信息(配置数据、锁 (lock) 等),以便能够进行协调,而且这些信息需要保持一致,即使在数据存储失败时也可以使用。因此他们需要一个具有坚实一致性保证的数据存储。为此,他们开发了 Doozer,一个用 Go 语言编写的、新的、一致的、高度可用的数据存储,并且仿照谷歌的(封闭源码)Chubby 程序来管理他们的后端基础设施。
Doozer 以 Paxos 为基础(Paxos 是一个由不可靠节点组成的的不可靠网络中解决共识问题的协议族),虽然 Paxos 对运行容错系统至关重要,但它因难以实现而臭名昭著。即使是在网上可以找到的实例实现也很复杂,很难遵循,尽管已经为了教育目的而被简化过。而现有的生产系统以更糟糕而闻名。
Doozer 是作为建立分布式系统的一个坚硬的基础而被开发的。
- 一个高度可用的(在网络分区期间工作)。
- 数据存储(用于少量的数据)。
正如开发人员所说:
它提供了一个单一的基本同步元素:比较-设置对 (compare-config)。
用例:
- 数据库主选 (Databases master election)
- 配置
为什么选择 Go,Go 的特点如何使其成为一个成功的产品:
Paxos 是以独立的、并发的进程来定义的,这些进程通过传递消息进行通信。这正是 Go 的并发原语(goroutines 和 channel,见 第 14 章)所擅长的问题。在 Doozer 中,这些进程被实现为 goroutines,他们的通信被实现为通道操作。就像 Go 的垃圾收集器将内存使用量降到最低一样,Doozer 的开发者发现 goroutines 和通道改进了基于锁的并发方法。这些工具让他们避免了复杂的“记账” (bookkeeping) 方式,并将注意力集中在手头的问题上。他们仍然惊讶于只用了几行代码就实现了以困难著称的东西。
Go 中的标准包是对于 Doozer 的另一个大成功,其中最值得一提的是 包。
他们还喜欢自动格式化工具 gofmt,以实现一致的代码风格和布局,从而避免了对这些话题的讨论。
其他语言也提供了一些类似的并发机制——比如 Erlang 和 Scala,但 Go 的设计也是为了提供最大的效率和控制。在另一篇文章中()Keith Rarick 指出:
在 Doozer 中,Go 主要作为一种系统编程语言使用。更多的技术描述可以在(引用 38)找到;代码可在 找到。