来自 Google、YouTube、Twitter、Amazon、eBay、Facebook 和 Instagram 的可扩展性经验教训

【搬运】
文章来源:https://www.dodgycoder.net/2012/04/scalability-lessons-from-google-youtube.html

我在一个地方收集了来自七个流量最大的网站的一些可扩展性课程。我主要从优秀的高可扩展性博客上的各种文章中获取了这一点,并在下面总结了每家公司的要点。

以下是我在这七家公司中注意到的一些共同想法…

保持简单 - 随着时间的流逝,复杂性会自然而然地出现。
自动执行所有操作,包括故障恢复。
迭代您的解决方案 - 当您想要将工作组件扩展到下一个级别时,请准备好丢弃它。
使用正确的工具来完成工作,但不要害怕推出自己的解决方案。
在适当的情况下使用缓存。
知道何时更倾向于数据一致性而不是数据可用性,反之亦然。

Google

可靠的存储 可靠的可扩展存储
是任何应用程序的核心需求。Google 文件系统 (GFS) 是 Google 的核心存储平台,它是一个大型分布式日志结构化文件系统,他们将大量数据投入其中。他们为什么要建造它而不是使用现成的东西?因为他们控制着一切,而正是这个平台将他们与其他人区分开来。从GFS中,他们获得了:跨数据中心的高可靠性,数千个网络节点的可扩展性,巨大的读/写带宽,支持千兆字节大小的大型数据块,以及跨节点的高效操作分配,以减少瓶颈。

基础设施作为竞争优势
,谷歌可以更快、更便宜、更大规模地推出新的互联网服务,很少有其他公司可以与之竞争。许多公司采取了完全不同的方法,将基础设施视为一项费用。每个小组将使用完全不同的技术,并且几乎没有规划和共同性来构建系统。

在平台之上构建应用程序 平台
方法的一个被低估的优势是,初级开发人员可以快速、自信地创建健壮的应用程序。如果每个项目都需要创建相同的分布式基础设施,你很快就会遇到困难,因为知道如何做到这一点的人相对较少。协同作用并不总是废话。通过使系统的所有部分协同工作,一个部分的改进可以帮助他们所有人。改进文件系统,每个人都能立即、透明地受益。如果每个项目都使用不同的文件系统,那么整个堆栈就没有持续的增量改进。

自动化和恢复
– 构建无需关闭系统即可工作的自我管理系统。这使您可以更轻松地在服务器之间重新平衡资源、动态添加更多容量、使计算机脱机以及优雅地处理升级。

创建达尔文式基础设施
并行执行耗时(受 CPU 限制)的操作,并赢得胜利。当您有备用 CPU 容量但 IO 有限时,这尤其有用。

不要忽视学院
学术界有很多好的想法,但这些想法没有被转化为生产环境。谷歌所做的大部分工作都有现有技术,只是没有事先的大规模部署。

考虑数据压缩
当您有大量 CPU 要占用且 IO 有限时,压缩是一个不错的选择。

YouTube

保持简单 寻找可以解决问题空间的最简单
的东西。有很多复杂的问题,但第一个解决方案并不需要很复杂。随着时间的流逝,复杂性会自然而然地出现。选择最简单的解决方案,并保证最宽松的实用性。你想要所有这些东西的原因是你需要灵活性来解决问题。一旦你过度指定了一些东西,你就会把自己画到一个角落里。你不会做出这些保证。你的问题会自动变得更加复杂当你试图做出保证时,你会让自己没有出路。

作弊:知道如何伪造数据
最快的函数调用是不会发生的函数调用。当您的计数器(如视图计数)持续增加时,每次更新都需要执行数据库调用。或者你可以每隔一段时间打一个电话,并在两者之间随机更新一个数量 - 人们会相信它是真实的。知道如何伪造数据。

抖动:将熵重新添加到您的系统中
如果您的系统没有抖动,那么您就会收到雷鸣般的人群,他们都在同一时间请求相同的资源。对于流行的视频,他们会尽可能地缓存内容。他们可能会缓存 24 小时的最受欢迎的视频。如果所有东西都同时过期,那么每台机器都会同时计算过期时间。这创造了一个雷鸣般的牛群。通过抖动,您说在 18-30 小时之间随机过期。这样可以防止事情同时发生,并将请求分散在很长一段时间内。

近似正确性
系统的状态是用户看到的状态。如果用户无法分辨出系统的某个部分存在偏差和不一致,那么它就不是。如果你写了一条评论,有人同时加载了页面,他们可能半秒钟都看不懂,只是阅读页面的用户不会在意。不过,评论的作者会关心,因此您要确保撰写评论的用户会立即看到它。这可以让你作弊一点。在评论方面,您的系统不必具有全局一致的事务。那将是超级昂贵和矫枉过正的。评论不是金融交易 - 知道什么时候可以作弊。

Twitter 实现 API Twitter 的 API
流量是 Twitter

网站的十倍。API 是 Twitter 为扩大用户群所做的最重要的事情。保持服务的简单性使开发人员能够在他们的基础设施之上进行构建,并提出比 Twitter 所能想出的更好的应用程序创意。你永远无法完成用户能做的所有工作,你可能不会那么有创造力。因此,请打开您的应用程序,让其他人尽可能轻松地将您的应用程序与他们的应用程序集成。

使用你所知道的
Twitter 经常使用消息传递。生产者生成消息,这些消息经过排队,然后分发给使用者。Twitter 的主要功能是充当不同格式(SMS、Web、IM 等)之间的消息传递桥梁。发送消息以在后台使朋友的缓存失效,而不是单独同步执行所有操作。Twitter 开发人员对 Ruby 最为熟悉,因此他们从 DRb 迁移到了 Starling,这是一个用 Ruby 编写的分布式队列。分布式队列是通过将它们写入磁盘来在系统崩溃时幸存下来的。根据 Twitter 的经验,大多数性能改进不是来自语言的选择,而是来自应用程序的设计。

知道何时缓存以及缓存
什么 例如,获取好友状态很复杂。存在安全和其他问题。因此,与其进行数据库查询,不如做朋友的 staTUS 改为在缓存中更新。它从不触及数据库。90% 的请求是 API 请求。因此,他们不会为前端进行任何页面缓存。Twitter页面对时间非常敏感,没有任何好处。Twitter 仅缓存 API 请求。

保护自己免受滥用
了解人们将如何试图破坏您的系统。设置合理的限制和检测机制,以保护您的系统不被机器人杀死。构建工具来检测滥用行为,以便您可以确定滥用行为发生的时间和地点。要狠心。将其作为用户删除。

Amazon 使用 SOA
Amazon

的架构是松散耦合的,是围绕服务构建的。面向服务的架构 (SOA) 为他们提供了隔离,允许快速且相互独立地构建许多软件组件,从而加快产品上市时间。呈现 Amazon.com 网页的应用程序就是这样一种应用程序服务器。服务于 Web 服务界面、客户服务应用程序和卖家界面的应用程序也是如此。

使用 API 打开您的系统,您将围绕您的应用程序创建一个生态系统。围绕服务进行组织可以为您提供敏捷性 - 您现在可以并行执行操作,因为所有内容的输出都是服务。禁止客户端直接访问数据库。这意味着您可以在不涉及客户的情况下扩大服务规模并提高可靠性。这很像 Google 能够独立地在其堆栈中分发改进,以造福所有应用程序。

知道何时支持一致性而不是可用性,反之亦然
要进行扩展,您必须进行分区,因此您只能为特定系统选择高一致性或高可用性。您必须找到可用性和一致性的正确重叠。根据服务需求选择特定方法。对于结帐流程,您总是希望尊重将商品添加到购物车的请求,因为它可以产生收入。在这种情况下,您可以选择高可用性。错误对客户隐藏,稍后会整理出来。当客户提交订单时,您倾向于一致性,因为多个服务(信用卡处理、运输和处理、报告)同时访问数据,并且每个服务都依赖于其数据来保持一致。

拥抱失败 认为事情失败
是理所当然的,这就是现实,拥抱它。例如,使用快速重启和快速恢复方法。通过数据和服务的良好传播,您可能会获得接近 100% 的数据和服务。创建一个自我修复、自组织、无人值守类型的操作。

只使用你需要的东西 通过确保设计中没有隐藏的需求和隐藏的依赖关系来
保持简单。将技术削减到解决所遇到的问题所需的最低限度。它无助于公司创建人为的和不必要的复杂性层。不拘泥于一种特定的方法或技术堆栈。有些地方他们使用 jboss/java,但他们只使用 servlet,而不使用 J2EE 堆栈的其余部分。C++ 用于处理请求。Perl/Mason 用于构建内容。

根据客户反馈做出决策
用衡量和客观辩论来区分好坏。让真正的客户做出选择,看看哪一个最有效,并根据这些测试做出决策。这是通过 A/B 测试和 Web Analytics 等技术完成的。如果你对你应该做什么有疑问 - 把它编码出来,让人们使用它,看看哪个替代方案能给你带来你想要的结果。

可扩展性是一种竞争优势 亚马逊的基础设施和谷歌一样,是一个巨大的竞争优势
。它们可以从原始服务中构建非常复杂的应用程序,而这些原始服务本身相对简单。他们可以独立扩展其运营,保持无与伦比的系统可用性,并快速引入新服务,而无需进行大规模重新配置。

eBay

Partition everything
如果你不能拆分它,你就无法扩展它。按功能和数据将所有内容拆分为可管理的块。

无处不在的异步 通过事件驱动的队列和管道
连接独立的组件。

拥抱故障 监控一切,即使零件开始出现故障
也提供服务。最小化和控制依赖关系,使用抽象接口和虚拟化,组件具有 SLA,消费者负责从 SLA 违规中恢复。实现一切自动化。组件应该自动调整,系统应该学习和改进自己。

拥抱不一致
选择您需要在 CAP 连续体上的每个功能,没有分布式事务,通过仔细的操作排序可以最大限度地减少不一致,通过异步恢复和协调实现最终一致性。

保存所有数据 数据
驱动寻找优化机会、预测、建议,因此请全部保存。了解哪些数据是权威的,哪些数据不是权威的,并相应地对待它。

基础架构:使用正确的工具完成正确的工作
需要最大限度地利用每种资源:数据(内存)、处理 (CPU)、时钟时间(延迟)、功耗。一种尺寸很少适合所有人,尤其是在规模上。由正交的商品组件组成。

Facebook

扩展需要多次迭代
解决方案通常在开始时有效,但您必须在继续进行时对其进行修改 - 第一年有效的方法可能在以后不起作用。一个很好的例子是照片。Facebook 目前每秒提供 120 万张照片。第一代是以简单的方式构建的 - 不用担心扩展那么多 - 专注于获得正确的功能。上传者将文件存储在 NFS 中,元数据存储在 MySQL 中。它只在前 3 个月有效,但这并不重要,因为上市时间是他们拥有的最大竞争优势。拥有该功能比确保它是一个经过深思熟虑的可扩展解决方案更重要。第二代进行了优化 - 针对不同的访问模式进行了优化。较小的图像是 acce更频繁地 ssed,因此这些被缓存。他们还开始使用 CDN(内容分发网络)。第三代是覆盖系统,它创建一个文件,该文件是存储在文件系统中的 blob。图像存储在二进制 blob 中,并且你知道 blob 中照片的字节偏移量 - 因此每张照片只有一个磁盘 IO。

不要过度设计解决方案 - 保持简单
只需使用在横向扩展系统时需要使用的内容即可。弄清楚您需要在哪些方面迭代解决方案、优化某些内容或自己完全构建堆栈的一部分。Facebook花了很多时间试图优化PHP,最终编写了HipHop,一个将PHP转换为C++的工具。这节省了大量的内存和 CPU。您不必在第一天就这样做,但您可能必须这样做。在编写一门全新的语言之前,首先要关注产品。

为工作选择正确的工具,但要接受你的选择会带来开销
如果你真的需要使用 Python,那就继续这样做,但要意识到,选择这个工具会产生开销,通常是在部署、监视和操作之间。如果你选择使用面向服务的架构(SOA),你将不得不自己构建大部分后端,这通常需要相当多的时间。使用LAMP堆栈,您可以免费获得很多。一旦您离开 LAMP 堆栈,如何执行服务配置和监控等操作就由您决定。随着你对服务方法的深入研究,你必须重新发明轮子。

建立正确的
文化 在内部建立一个环境,促进先构建正确的东西,然后根据需要进行修复,不用担心创新,不用担心破坏东西,想大处着眼,思考在构建第一件事之后你需要构建的下一件事是什么。你可以得到正确的代码,你可以得到正确的产品,但你需要首先获得正确的文化。如果你没有掌握正确的文化,那么你的公司就不会扩大规模。

Instagram

利用现有的云基础设施
当您可以使用可靠且成熟的技术时,不要重新发明轮子。Instagram 在 Amazon 的 EC2 云计算基础设施上运行 100+ 个 Ubuntu 11.04 实例。他们还使用 Amazon 的 ELB(Elastic Load Balancer),它由三个 NGINX 实例组成,具有自动故障恢复功能。照片本身直接进入 Amazon S3 存储,并使用 Amazon CloudFront 作为其 CDN(内容分发网络),可帮助缩短来自世界各地用户的图像加载时间(如 在日本,他们第二受欢迎的国家)。

异步任务队列
当用户决定将 Instagram 照片分享到 Twitter 或 Facebook 时,或者当他们需要通知实时订阅者发布的新照片时,他们会将任务推送到开源 Gearman 任务管理框架中。去做 通过任务队列异步意味着媒体上传可以 快速完成,而“繁重的工作”可以在后台运行。大约有 200 个用 Python 编写的 worker 在使用任务队列 在任何给定时间,在它们共享到的服务之间进行拆分。

推送通知
他们使用一个名为 pyapns 的开源 Apple 推送通知服务 (APNS) 提供程序,它基于 Twisted。它已经为 Instagram 处理了超过 10 亿条推送通知,他们报告说它坚如磐石。

实时系统范围监控
借助 100+ 个 EC2 实例,掌握全面动态非常重要。他们使用 Munin 在系统范围内绘制指标图,如果出现以下情况,它会发送警报 任何超出其正常工作范围的东西。他们编写自定义 Munin 插件,建立在 Python-Munin 之上,用于绘制非系统级指标(例如,每分钟注册次数、每秒发布的照片等)。他们使用 Pingdom 对服务进行外部监视,并使用 PagerDuty 处理通知和事件。对于 Python 错误报告,他们使用 Sentry、 一个开源的 Django 应用程序。在 在任何给定时间,他们都可以登录并实时查看整个系统中发生的错误。

选择性地使用 NoSQL 技术(如 Redis) Redis 为主源、活动源、会话系统(这是他们的 Django 会话后端)
和其他相关系统提供支持。 Redis 的所有数据都需要放入内存中,因此它们会运行多个 EC2 for Redis 上的四倍超大内存实例,偶尔 跨任何给定子系统的几个 Redis 实例进行分片。

你可能感兴趣的:(TEE,twitter,facebook)