# Facebook：用于扩展数十亿条消息的示例规范架构

> 原文： [http://highscalability.com/blog/2011/5/17/facebook-an-example-canonical-architecture-for-scaling-billi.html](http://highscalability.com/blog/2011/5/17/facebook-an-example-canonical-architecture-for-scaling-billi.html)

![](img/05b2f60819d28aa5d0e59ecb0a2b699e.png)

可扩展，实时，高可用性服务的体系结构应该是什么样？ 可供开发人员使用的选项太多，但是如果您要寻找通用模板，则该架构由[后端团队的 Facebook](https://www.facebook.com/notes/facebook-engineering/scaling-the-messages-application-back-end/10150148835363920#) [消息](/blog/2010/11/16/facebooks-new-real-time-messaging-system-hbase-to-store-135.html)后端小组负责人 Prashant Malik 描述。 应用后端是一个很好的示例。

尽管 Messages 的任务是每月处理来自电子邮件，IM，SMS，文本消息和 Facebook 消息的 135 亿多条消息，但您可能会认为这是 BigArchitecture 的示例，不适用于较小的站点。 不是这样 这是一个很好的，经过深思熟虑的非云架构示例，展现了任何妈妈都会为之骄傲的许多品质：

1.  **分层**-组件独立且隔离。
2.  **服务/ API 驱动的**-每个层都通过定义明确的接口连接，该接口是访问该服务的唯一入口点。 这样可以避免令人讨厌的复杂相互依赖关系。 客户端隐藏在应用程序 API 的后面。 应用程序使用数据访问层。
3.  **分布式**-层透明地分布在计算机集群之间
4.  **单独的应用程序逻辑**-应用程序逻辑封装在提供 API 端点的应用程序服务器中。 应用程序逻辑是根据其他服务实现的。 应用服务器层还隐藏了直写式高速缓存，因为这是写入或检索用户数据的唯一位置，它是高速缓存的理想之地。
5.  **无状态**-状态保存在数据库层，缓存层或其他服务中，而不保存在应用程序中或塞在本地口袋中。
6.  **可伸缩组件服务**-其他本身可伸缩且高度可用的服务用于实现此服务。 消息还使用：Memcache，用户索引服务和 [HayStack](http://haystacksearch.org/) 。
7.  **完整堆栈操作**-开发了工具来管理，监视，识别性能问题并在整个堆栈中上下扩展整个服务。
8.  **蜂窝**-消息具有称为**单元**的机器和服务群集作为其系统的基本构建块。 如果需要更多的机长，则以递增方式添加单元。 一个单元由 [ZooKeeper 控制器](/blog/2008/7/15/zookeeper-a-reliable-scalable-distributed-coordination-syste.html)，应用服务器集群和[元数据存储](https://www.facebook.com/note.php?note_id=454991608919)组成。 单元提供隔离，因为处理请求的存储和应用程序功能独立于其他单元。 单元可能会发生故障，升级并在与其他单元无关的数据中心之间分布。

质量 1-7 是众所周知的，并且相当广泛地得到认可并以某种形式或另一种形式部署。 *单元*的想法没有得到广泛应用，因为它使抽象级别提高到 *11* 。

Salesforce 具有类似的概念，称为[窗格](http://www.salesforce.com/dreamforce/DF09/pdfs/BKSP005_Moldt.pdf) *。* 对于 Salesforce，每个 Pod 包含 50 个节点，Oracle RAC 服务器和 Java 应用程序服务器。 每个吊舱支持成千上万的客户。 我们已经看到其他产品以类似的方式捆绑碎片。 分片将由数据库集群和存储组成，该存储将主从配置或主主配置隐藏到高度可用且可伸缩的单元中。 [Flickr](http://highscalability.com/flickr-architecture) 是此策略的早期且出色的示例。

本文真正有趣的一点是如何处理单元中的群集管理以及如何处理作为一个单元的单元管理。 那是很难正确的部分。

在机器集群中，节点以及因此这些节点上的服务可以随时闪烁并消失。 配置可以随时更改也可以更改吗？ 如何使单元中的所有系统保持协调？ ZooKeeper。 ZooKeeper 用于高可用性，分片，故障转移和服务发现。 易碎机器集群的所有基本功能。 在单元应用程序服务器中，服务器形成一致的哈希环，并且用户在这些服务器之间分片。

跨单元操作如何处理？ 消息具有*发现服务*，它是一种用户 DNS，它位于单元上方，并维护用户到单元的映射。 如果要访问用户数据，则必须先使用该服务找到正确的单元格。 在该单元中，*分布式逻辑客户端*充当发现服务的接口并处理 ZooKeeper 通知。

[文章](https://www.facebook.com/notes/facebook-engineering/scaling-the-messages-application-back-end/10150148835363920#)写得很好，并且有很多细节。 非常值得一读，特别是如果您试图弄清楚如何构建自己的服务时。

## 相关文章 [

*   [Facebook 的新实时消息系统：HBase 每月存储 135 亿条消息](/blog/2010/11/16/facebooks-new-real-time-messaging-system-hbase-to-store-135.html)
*   [ZooKeeper-可靠，可扩展的分布式协调系统](/blog/2008/7/15/zookeeper-a-reliable-scalable-distributed-coordination-syste.html)
*   [Facebook 关于高可伸缩性的文章](http://highscalability.com/blog/category/facebook)
*   [Force.com 基础架构内的外观](http://www.salesforce.com/dreamforce/DF09/pdfs/BKSP005_Moldt.pdf)

您遇到了错误的干草堆：http://planet.admon.org/haystack-new-storage-solution-for-billions-of-photos/

谢谢埃利奥特。 我不确定这是怎么回事，可以肯定我只是复制了他们的网址。 无论如何，现在应该修复它。

我认为 Facebook 意味着另一个干草堆 http://www.facebook.com/note.php?note_id=76191543919。 阅读有关 Facebook Messages 存储基础架构的文章，网址为 http://www.facebook.com/note.php?note_id=454991608919，其中包含正确的 URL。

我们的意思是：状态保存在数据库层，缓存层或其他服务中，而不是在应用程序中或塞在本地口袋中。