# 扩展 Digg 和其他 Web 应用程序

> 原文： [http://highscalability.com/blog/2009/2/14/scaling-digg-and-other-web-applications.html](http://highscalability.com/blog/2009/2/14/scaling-digg-and-other-web-applications.html)

Digg 的首席架构师 Joe Stump 在 Web 2.0 Expo 上向[进行了此演示](http://www.krisjordan.com/2008/09/18/joe-stump-scaling-digg-and-other-web-applications/)。 我找不到实际的演示文稿，但是[克里斯·乔丹](http://www.krisjordan.com/2008/09/18/joe-stump-scaling-digg-and-other-web-applications/)记下了一些很棒的笔记。 这样一来，历史上的关键时刻便会永远被意外捕获。 乔也很友好，可以通过电话回答我的电子邮件问题。

在本篇文章的第一部分中，乔分享了一些您可能没有读过的永恒的智慧。 我当然会花些力气从原始演示文稿中提取所有智慧，而倾向于简单的规则。 然而，真正令我震惊的是 Joe 认为 MemcacheDB *将成为扩展*领域中最大的新手。 MemcacheDB 已经存在了一段时间，但我从未想到过这种方式。 好吧，在帖子结尾处，为什么乔对 MemcacheDB 感到如此兴奋。

## 令人印象深刻的统计

*   世界第 80 至 100 大网站*   每月 2600 万唯一*   3000 万用户。*   唯一身份流量只有该流量的一半。 流量=唯一的网络访问者+ API + Digg 按钮。*   每月 20 亿个请求*   13,000 请求/秒，高峰时为 27,000 请求/秒。*   3 位系统管理员，2 位 DBA，1 位网络管理员，15 位编码员，质量检查小组*   Lots of servers.

    ## 扩展策略

    *   缩放是专业化。 当现成的解决方案不再能在一定规模上运行时，您必须创建满足特定需求的系统。*   Web 2.0 的教训：人们喜欢胡扯并与世界分享。*   Web 2.0 具有可伸缩性。 Web 1.0 平坦，包含大量静态文件。 通过添加更多硬件来处理额外的负载。 Web 2.0 是高度交互的。 内容可以以极低的速率创建。*   语言无法扩展。 100％的时间瓶颈在
    IO 中。 当您同时处理大量请求时，瓶颈就不是语言。 使 PHP 速度提高 300％无关紧要。 当
    固定数据库时，不要通过使用单引号而不是双引号来优化 PHP。*   不分享状态。 去中心化。 需要分区才能并行处理大量请求。*   向外扩展而不是向上扩展。 期待失败。 只需添加框即可缩放并避免失败。*   需要对数据库驱动的站点进行分区，以在水平和垂直方向上进行扩展。 水平分区意味着将行的子集存储在不同的机器上。 当一台机器上无法容纳的数据量更多时，将使用此功能。 垂直分区意味着将一些列放在一个表中，而将某些列放在另一个表中。 这使您无需停机即可将数据添加到系统。*   数据分为单独的群集：用户操作，用户，注释，项目等。*   构建数据访问层，以便将分区隐藏在 API 的后面。*   带有分区的 [CAP 定理](http://camelcase.blogspot.com/2007/08/cap-theorem.html)：您只能选择以下三个中的两个：强一致性，高可用性，分区容限。*   分区解决方案需要非规范化，这已成为 Digg 的大问题。 非规范化意味着数据被复制到多个对象中，并且必须保持同步。*   MySQL 复制用于扩展读取。*   使用异步排队体系结构进行近期处理。
    -这种方法将处理块推向另一个服务，让我们将该服务调度在处理器网格上进行处理。
    -与 cron 相比，它更快，响应速度更快，但与实时响应相比，响应速度却稍慢。
    -例如，发出 5 个同步数据库请求会使您减速。 并行执行。
    -Digg 使用 Gearman。 一个示例用法是获取永久链接。 并行完成三个操作：获取当前记录，获取固定链接并获取注释。 然后将这三个全部合并，以将合并的单个答案返回给客户端。 它也用于网站爬网和日志记录。 这是另一种思维方式。
    -请参阅 [Flickr-先做必要的工作，然后将其余部分排队](http://highscalability.com/strategy-flickr-do-essential-work-front-and-queue-rest)和 [Canonical Cloud Architecture](http://highscalability.com/canonical-cloud-architecture) 了解更多信息。*   瓶颈在 IO 中，因此您已经调整了数据库。 当数据库大于 RAM 时，磁盘会一直处于命中状态，这会降低性能。 随着数据库的变大，无法再扫描该表。 因此，您必须：
    -反规范化
    -避免加入
    -避免通过对
    进行分区来跨数据库进行大型扫描-缓存
    -添加读取从属设备
    -不要使用 NFS*   在尝试解决问题之前，请先编号，以确保事情确实可以进行。*   图标和照片之类的文件是使用分布式文件系统 [MogileFS](http://www.danga.com/mogilefs/) 处理的。 DFS 支持高请求率，因为文件是在网络中分布和复制的。*   缓存永久并且明确过期。*   在基于文件的缓存中缓存相当静态的内容。*   将可变项目缓存在 memcached 中*   在 [APC](http://us2.php.net/apc) 中缓存很少更改的项目。 APC 是本地缓存。 它不是分布式的，因此没有其他程序可以访问这些值。*   对于缓存，请使用[责任链模式](http://en.wikipedia.org/wiki/Chain-of-responsibility_pattern)。 在 MySQL，memcached APC 和 PHP 全局变量中进行缓存。 首先将 PHP 全局变量检查为最快的缓存。 如果不存在，请检查 APC，memcached 并上链。*   Digg 的推荐引擎是一个最终保持一致的自定义图形数据库。 最终一致意味着写入一个分区最终将写入所有其他分区。 一次写读后，不必再返回相同的值，因为它们可以由不同的分区处理。 这比严格的一致性要宽松得多，这意味着更改必须在所有分区上同时可见。 接连进行的读取将始终返回相同的值。*   假设每天有 100 万人使用任何新功能，因此从一开始就使其具有可扩展性。 示例：Digg 上的“关于”页面对主数据库进行了实时查询，以显示所有员工。 只是做了一个快速的黑客出去。 然后，一只蜘蛛发疯了，并把该地点倒了。

    ## 杂种

    *   Digg 按钮是产生点击量的主要关键。*   使用 Debian Linux，Apache，PHP，MySQL。*   选择您喜欢开发的语言，选择编码标准，添加可提取的内联文档，使用代码存储库和错误跟踪器。 喜欢 PHP，Track 和 SVN。*   你和你的人民一样好。 必须相信你旁边的人他在做他的工作。 为了建立信任，人们可以做出
    决策。 相信人们会处理它，他们会照顾好它的。 减少会议时间，因为您知道人们会做正确的事。*   完全是 Mac 商店。*   几乎所有的开发人员都是本地的。 有些人不愿提供 24 小时支持。*   乔的做法务实。 他没有语言迷恋。 人们从 PHP 到 Python / Ruby，再到 Erlang。 使用 vim。 从命令行开发。 不知道人们如何一直在不断更改工具集。 这不是很有效。*   服务（SOA）分离是一个巨大的胜利。 Digg 使用 REST。 内部服务返回映射到 JSON，XML 等的原始结构。URL 中的版本是因为它不花钱，例如：
    /1.0/service/id/xml。 版本内部和外部服务。*   人们不了解网站中有多少活动部件。 某些事情将会发生，并且将会失败。

    ## MemcacheDB：代码的进化步骤，性能的革命步骤

    想象一下 Digg 的创始人 Kevin Rose，他在本次演讲时拥有 40,000 个关注者。 如果 Kevin 每天只进行一次挖掘，则可写 40,000。 由于最活跃的挖掘者是最紧随其后的，因此它成为巨大的性能瓶颈。 出现两个问题。

    您无法一次更新 40,000 个关注者帐户。 幸运的是，我们前面讨论的排队系统已解决了这一问题。

    第二个问题是发生大量写入。 Digg 有写问题。 如果普通用户有 100 个关注者，则一天的收入为 3 亿迪格斯。 那就是每秒 3,000 次写入，每天 7GB 的存储以及 5TB 的数据分布在 50 到 60 台服务器上。

    如此繁重的写入负载使 MySQL 无法用于 Digg。 这就是 MemcacheDB 的用武之地。在笔记本电脑上的初始测试中，MemcacheDB 每秒能够处理 15,000 次写入。 MemcacheDB 自己的[基准测试](http://memcachedb.org/benchmark.html)显示其每秒 23,000 次写入和 64,000 次读取/每秒的能力。 以这些写入速度，不难理解为什么乔对 MemcacheDB 的 digg 泛滥能力感到如此兴奋。

    什么是 [MemcacheDB](http://memcachedb.org/) ？ 这是专为持久性而设计的*分布式键值存储系统。 它不是缓存解决方案，而是持久存储引擎，用于基于键值的快速，可靠的对象存储和检索。 它符合内存缓存协议（未完成，请参见下文），因此任何内存缓存客户端都可以与其建立连接。 MemcacheDB 使用 Berkeley DB 作为存储后端，因此支持许多功能，包括事务和复制*。

    在您太兴奋之前，请记住这是一个键值存储。 您可以通过一个键来读取和写入记录。 没有多个索引，也没有 SQL。 这就是为什么它可以这么快的原因。

    Digg 使用 MemcacheDB 扩展了数据非规格化时发生的大量写入。 请记住，这是一个键值存储。 该值通常是一个完整的应用程序级对象，该对象可以从大量标准化表合并在一起。 归一化引入了冗余，因为您将数据副本保留在多个记录中，而不是在一个很好的标准化表中保留一个副本。 因此，非规范化意味着更多的写入操作，因为必须将数据复制到包含副本的所有记录中。 为了跟上他们的发展，他们需要一个能够处理其写负载的数据库。 MemcacheDB 具有这种性能，尤其是当您将 memcached 的常规分区方案放在最顶层时。

    我问 Joe 为什么不选择一种内存数据网格解决方案？ 一些原因是：*   此数据是从许多不同的数据库生成的，并且需要很长时间才能生成。 因此，他们希望将其存储在持久性存储中。*   MemcacheDB 使用内存缓存协议。 Digg 已经使用 memcache，因此开始使用 MemcacheDB 无疑是很容易的。 它易于使用且易于设置。*   由于它不是新的设置，因此操作人员很乐意将其部署到数据中心。*   他们已经具有内存缓存的高可用性和故障转移代码，因此已经可以使用。*   使用新系统将需要更多的准备时间。*   如果代码有任何问题，您可以看一下。 全部都是开源的。*   不确定其他产品是否足够稳定。

    因此，这是代码的进化步骤，也是性能的革命步骤。 Digg 正在考虑全面使用 MemcacheDB。

    ## 相关文章

    *   [扩展 Digg 和其他 Web 应用程序](http://www.krisjordan.com/2008/09/18/joe-stump-scaling-digg-and-other-web-applications/)，作者：Kris Jordan。*   [MemcacheDB](http://memcachedb.org/)*   [Joe Stump 的博客](http://www.joestump.net/)*   [具有与 Memcached 有关的高扩展性标签](http://highscalability.com/tags/memcached)*   [高速缓存相关标签](http://highscalability.com/tags/caching)*   [BigTable](http://highscalability.com/tags/bigtable)*   [SimpleDB](http://highscalability.com/tags/simpledb)*   [Anti-RDBMS：分布式键值存储列表](http://highscalability.com/anti-rdbms-list-distributed-key-value-stores)*   [数据库设计的非传统方法：碎片](http://highscalability.com/unorthodox-approach-database-design-coming-shard)的来临*   [Flickr 架构](http://highscalability.com/flickr-architecture)*   [第 4 集：DIGG 首席架构师 Joe Stump 扩展大型网站](http://deepfriedbytes.com/podcast/deep-fried-bytes-episode-4-scaling-large-web-sites-with-joe-stump-lead-architect-at-digg/)

除非他们想在 RAM 上花很多钱，否则他们会感到意外。 当 RAM 与数据库大小之比降低到 0.8 左右时，Memcachedb / Berkeley 数据库（或基于 B-Tree 的 MySQL，PostgreSQL 或其他传统数据库存储）的性能将大打折扣。

当前，写解决方案是 Hypertable，即使 RAM 与 DB 的大小比小于 0.1，它也可以每个客户端维持 10k 次写/秒。

“搜索”背后的架构是什么。 我假设正在使用某种全文数据库。 有人可以指出在 IIS / ASP.Net 环境中扩展全文本搜索的最佳方法。 我知道 SQL Server 2005 不够好。

我正在寻找使用基于非 SQL 的后端的东西，例如 berkley db。

任何指针将不胜感激？

Web 2.0 Expo 笔记的重新组合。 乔的演讲很棒！ 首先请注意，指向我的笔记的链接似乎在 href 中包含一个
，该链接中断了该链接。 最好！ 克里斯

哇，对我来说好像他们是在爆发大家伙！

RT
www.anon-tools.us.tc

您应该看一下 SOLR（基于 Lucene 的搜索服务器）。 在 Tomcat 和 Jetty 上运行良好...都在 Windows 上运行。 [http://lucene.apache.org/solr/](http://lucene.apache.org/solr/)

搜索/数据的 XML 存储是 ASP.net 应用程序的最佳选择，将 LINQ 与.net 3.5 配合使用，XML 比 SQL 快得多。 而且您不必担心整天都会向 ms-sql-s 端口发送垃圾邮件。

[http://www.keyoti.com/products/search/dotNetWeb/index.html](http://www.keyoti.com/products/search/dotNetWeb/index.html)

这些家伙有一个非常不错的搜索引擎，但是它只能通过爬网来搜索，但是您始终可以调整其源代码，对于应该支持的简单网站，也可以通过 Web 控件运行

乔录制了一个非常不错的播客，前段时间他在谈论这个话题。 你可以在找到它

[http://deepfriedbytes.com/podcast/deep-fried-bytes-episode-4-scaling-large-web-sites-with-joe-stump-lead-architect-at-digg/“](<a rel=) > [http://deepfriedbytes.com/podcast/deep-fried-bytes-episode-4-scaling-large-web-sites-with-joe-stump-lead-architect-at-digg/](http://deepfriedbytes.com/podcast/deep-fried-bytes-episode-4-scaling-large-web-sites-with-joe-stump-lead-architect-at-digg/)

凉。 谢谢。 有趣的是，这并没有出现在我的搜索中。

“ Digg 使用 MemcacheDB 来扩展数据非规范化时发生的大量写入。”

这是个绝妙的主意：**请勿非正规化！**

[http://kottke.org/04/10/normalized-data](http://kottke.org/04/10/normalized-data)

很棒的文章，我非常喜欢 memcache，并已在我的 [http://www.kiran.org.in'](<a rel="nofollow" href="http://www.kiran.org.in) >网站中实现了它

Todd
再次感谢您提供出色的摘要。

在仔细阅读了所有细节之后，我觉得 Digg 必须在其基础架构上投入大量资金才能达到这种级别的可伸缩性。

通过查看在 memcacheDB 上*不使用数据网格*的合理性，我得到的印象是，在评估此选项时没有太多的思想投入，因为有些评论对我来说没有意义。 例如，更改应用程序以将 mecacheDB 用作 MySQL 的应用程序需要进行重大更改。 使用数据网格，由于数据库可以保持不变，因此更改可能会更低。 现在，我无法与成功争论，但是，如果今天我需要扩展我的应用程序，那么在那条路线上走时将非常谨慎，尤其是在当前市场经济条件下。

今天，有更多现成的解决方案可以完成本研究中提到的大多数事情。 这包括将应用程序分解为分布式服务，扩展数据层，与负载均衡器集成以实现动态扩展的能力（请参阅有关此方面的最新文章 [http://highscalability.com/handle-1-billion [使用记忆网格的事件日数]](<a rel=) >使用内存网格（1009）每天处理 10 亿个事件。有趣的是，在过去几周中，我们参与了几个项目，这些项目展示了如何 您可以推动超过 10 万次写入/秒。我们使用 data-grid 作为前端，并保持对数据库的异步更新。我们使用 MySQL 作为基础数据库，从维护的角度来看，带来了使用标准 SQL 数据库的优势。 云计算还可以提供非常经济高效的环境来实现这种级别的扩展，而不会带来太多麻烦。

我不确定在 Digg 构建其解决方案时所有可用的替代方案是否可用，因此 Joe Stump 提出此架构是否合理。
知道乔今天是否会选择该路线会很有趣。

请参阅 [http://natishalom.typepad.com/nati_shaloms_blog/2008/11/the-impact-of-cloud-computing-on-buy-vs-build-behaviour.html“](<a rel=) >影响 基于 Fred 布鲁克斯出色的文章“ No Silver Bullets”撰写的云计算在构建与购买行为之间的关系正如 Fred 所指出的那样，在许多情况下，我们倾向于认为我们有专门的要求，并且最终在基础设施建设和投资方面进行投资 经济压力迫使人们重新评估这些假设。

男孩，

对不起，你错了。 您正在展示您的经验。 处理大数据时，必须进行规范化以最大程度地减少数据集上的锁定。 您还可以通过减少联接来提高性能。 请记住，读取量远大于写入量。

我不确定这是否相关。 假设您是 Digg，并且拥有 1 TB 的数据（可能更多，但是请在此处与我联系）。 您可以将其分布在 40 个服务器上，每个服务器具有 24 GB 的 RAM 和 24 GB 的存储。

根据我刚刚检查的 HP 网站，将 DL 360 从 1GB RAM 升级到 24GB 的费用为 998 美元。 为了简单起见，我们将其舍入到$ 1,000。 （服务器总成本不到 7,000 美元，包括 120GB RAID 1 SAS 存储）

您最终得到的是$ 40,000 的 RAM，总计 1 TB，分布在 40 台服务器上。 对于在服务器上花费 280,000 美元的公司来说，这不是一个坏交易。 这相当于 RAM 的服务器成本的 14％。

因此，敬请注意，低于 1.0 只是由于规划不当或数据集过大。 （请注意，我足够聪明地意识到 1TB 可能对于 Facebook 或 Flickr 这样的公司来说是一个舍入误差，但是他们的预算也相应地更大。）

我看到去年的播客，一个非常有趣的家伙，知道他的东西。

- [http://www.onlinebingoclub.co.uk/foxy-bingo/“](<a rel=) >狡猾

嗨，
我们正在处理一个项目，该项目实现了 MemcacheDB 作为持久性缓存的解决方案。 不幸的是，该产品似乎并不是所有的东西都那么光明：
1\. Get 时间平均变化为 50ms，标准差为 150ms（键和数据的大小小于 100bytes）
2.您 不知道 MemcacheDB 中存储了多少数据，那里“丢失”了哪些数据，并且如果您没有密钥（也不能，不支持枚举），就无法删除信息。
3.似乎 前两个事实是相关的（您不能删除废弃的项目，因此性能很差）。
4.根据产品的网站，该产品似乎已被废弃，并且在目前的状态下还远远不能管理。

最好的问候，
Moshe Kaplan。 Performacne 专家。

感谢另一篇出色的文章，从网络上一些最繁忙的站点中看到真实的示例，这为我们提供了有关准备工作的真正有价值的信息。

我在< http://www.mrkirkland.com/prepare-for-web-application-scalability/ >的最新文章中引用了 highscalability.com。

谢谢！
柯克兰先生
首席执行官 artweb.com