ThinkChat🤖让你学习和工作更高效,注册即送10W Token,即刻开启你的AI之旅 广告
# 在 30 分钟内进行 7 年的 YouTube 可扩展性课程 > 原文: [http://highscalability.com/blog/2012/3/26/7-years-of-youtube-scalability-lessons-in-30-minutes.html](http://highscalability.com/blog/2012/3/26/7-years-of-youtube-scalability-lessons-in-30-minutes.html) ![](https://img.kancloud.cn/4e/bc/4ebc7ce1aebe536f313ed5d99d05d99a_177x74.png) 如果您开始建立约会网站,而最终建立了每天处理 40 亿次观看次数的视频共享网站(YouTube),那么您可能会在此过程中学到一些东西。 确实,YouTube 的原始工程师之一 Mike Solomon 确实学到了很多东西,他在 [PyCon](https://us.pycon.org/2012/) : [在 YouTube 上的可扩展性上做了演讲](http://www.youtube.com/watch?v=G-lGCC4KKok) 。 这不是架构驱动的讨论,我们将通过介绍许多盒子相互连接的方式进行介绍。 迈克可以这样讲。 他致力于建立 YouTube 的 Servlet 基础结构,视频索引功能,视频转码系统,全文搜索,CDN 等。 但是,相反,他退后了一步,仔细研究了工作时间,并分享了一些深刻的经验教训,这些经验教训显然是来之不易的。 对我来说,要讲的主要内容是使用非常简单的工具完成了**。 尽管许多团队都在转向更复杂的生态系统,但 YouTube 确实做到了简单。 他们主要使用 Python 进行编程,使用 MySQL 作为其数据库,他们一直使用 Apache,甚至对于一个如此庞大的站点来说,新功能都始于非常简单的 Python 程序。 这并不意味着 YouTube 不会做酷的事情,而是做的,但是使所有事情协同工作的更多的是哲学或做事方式,而不是技术专长。 是什么使 YouTube 成为世界上最大的网站之一? 继续阅读并查看...** ## 统计信息 * 每天 40 亿次观看 * 每分钟上传 60 个小时的视频 * 350+百万台设备启用了 YouTube * 2010 年收入翻了一番 * 视频的数量增加了 9 个数量级,而开发人员的数量仅增加了 2 个数量级。 * 一百万行 Python 代码 ## 堆栈 * **Python-** YouTube 的大部分代码行仍在 Python 中。 每次观看 YouTube 视频时,您都在执行一堆 Python 代码。 * **Apache** -当您认为需要摆脱它时,则不需要。 Apache 是​​YouTube 上真正的摇滚明星技术,因为它们保持了简单。 每个请求都通过 Apache。 * **Linux** -Linux 的好处是总有一种方法可以进入并查看您的系统运行情况。 无论您的应用程序表现多么糟糕,您都可以使用 strace 和 tcpdump 之类的 Linux 工具对其进行查看。 * **MySQL** -使用很多。 观看视频时,您正在从 MySQL 获取数据。 有时它使用关系数据库或 Blob 存储。 这是关于调整和选择组织数据的方式。 * [**Vitess**](http://code.google.com/p/vitess/) -YouTube 发布的新项目,用 Go 编写,它是 MySQL 的前端。 它动态地进行了很多优化,它重写查询并充当代理。 目前,它可以处理每个 YouTube 数据库请求。 它基于 RPC。 * **Zookeeper** -分布式锁定服务器。 用于配置。 真正有趣的技术。 难以正确使用,因此请阅读手册 * **Wiseguy** -一个 CGI Servlet 容器。 * **Spitfire** -一个模板系统。 它有一个抽象的语法树,让他们进行转换以使处理更快。 * **序列化格式** -无论使用哪种格式,它们都非常昂贵。 测量。 不要用泡菜 不是一个好选择。 找到的协议缓冲区很慢。 他们编写了自己的 BSON 实现,比您可以下载的实现快 10-15 倍。 ## 一般课程 * YouTube 的 **Tao** :选择最简单的解决方案,并附带最实际的保证。 您需要所有这些东西的原因是您需要灵活性来解决问题。 在您指定的那一刻,您就会把自己粉刷成一个角落。 您不会做出这些保证。 尝试做出所有这些保证时,您的问题会自动变得更加复杂。 您不会离开自己。 * **整个过程就是**的可伸缩性。 可扩展的系统是您所无法企及的。 您没有意识到。 这不是流行语。 这是解决精神问题的一般问题。 * **大型系统设计的标志**:每个系统都是根据其特定要求量身定制的。 一切都取决于构建的细节。 * **YouTube 不是异步的**,所有内容都处于阻塞状态。 * **相信哲学胜于教义**。 简单点。 那是什么意思? 当您看到它时,您就会知道。 如果执行代码检查会更改数千行代码和许多文件,则可能是一种更简单的方法。 您的第一个演示应该很简单,然后进行迭代。 * **解决一个问题:一个字-简单**。 寻找最简单的方法来解决问题空间。 有很多复杂的问题,但是第一个解决方案并不需要复杂。 随着时间的流逝,复杂性自然会到来。 * **许多 YouTube 系统都是从一个 Python 文件**开始的,并在许多年后变成了大型生态系统。 他们所有的原型都是用 Python 编写的,并且存活了惊人的时间。 * **在设计审查**中: * 什么是第一个解决方案? * 您打算如何迭代? * 我们对该数据将如何使用了解多少? * **事情随时间而变化**。 YouTube 如何起步与以后发生的事情无关。 YouTube 最初是一个约会网站。 如果他们为此设计,他们将有不同的对话。 保持灵活性。 * **YouTube CDN** 。 最初是外包出去的。 非常昂贵,所以他们自己做。 如果您有不错的硬件伙计,则可以构建一个不错的视频 CDN。 您建立了一个非常大的机架,将机器插入其中,然后进行 lighttpd 处理,然后覆盖 404 处理程序以查找未找到的视频。 这花了两个星期的时间,而且第一天的服务量为 60 吉比特。 使用非常简单的工具,您可以做很多事情。 * **您必须测量**。 Vitess 换出了一个协议来进行 HTTP 实现。 即使在 C 语言中,它的速度也很慢。 因此,他们剥离了 HTTP 并使用 python 进行了直接套接字调用,这在全局 CPU 上便宜了 8%。 HTTP 的封装确实非常昂贵。 ## 可扩展性技术 * 这些不是新主意,但令人惊讶的是,一些核心主意如何在许多不同的方面得到应用。 * **分而治之-可伸缩性技术** * 这是可伸缩性技术。 一切都是关于划分工作。 确定如何执行它。 从 Web 层开始,适用于许多事物,您拥有许多 Web 服务器,这些 Web 服务器或多或少完全相同且独立,并且可以水平扩展它们。 那是分而治之。 * 这是数据库分片的关键。 您如何划分内容,并在细分的部分之间进行交流。 这些是您想尽早解决的事情,因为它们会影响您的成长方式。 * 简单而松散的连接确实很有价值。 * Python 的动态特性在这里是一个胜利。 不管您的 API 有多糟糕,您都可以存根或修改或修饰自己的方式来解决许多问题。 * **近似正确性-稍作弊** * 另一个喜欢的技术。 系统的状态就是它所报告的状态。 如果用户不能告诉系统的一部分是歪斜和不一致的,那不是。 * 一个真实的例子。 如果您写评论,但有人同时加载该页面,则他们可能会在 300-400 毫秒内没有收到该评论,正在阅读的用户将不在乎。 评论的作者会在意,因此您确保撰写评论的用户会看到它。 所以你有点作弊。 您的系统不必具有全局一致的交易记录。 那将是非常昂贵和过度的。 并非每条评论都是金融交易。 所以知道什么时候可以作弊。 * **专家旋钮切换** * 问,您对一致性模型了解多少? 对于评论的最终一致性是否足够好? 租电影是不同的。 租房时有钱,所以我们会尽力做到永不丢失。 根据数据需要不同的一致性模型。 * **抖动-向系统中添加熵** * 始终是他们小组中的热门词。 如果您的系统没有抖动,那么您会得到 [雷电群](http://highscalability.com/blog/2008/3/14/problem-mobbing-the-least-used-resource-error.html) 。 分布式应用程序实际上是天气系统。 调试它们与确定天气一样具有确定性。 抖动引入了更多的随机性,因为令人惊讶的是,事情趋于堆积。 * 例如,缓存过期。 对于流行视频,他们会尽其所能地缓存内容。 他们可能会缓存 24 小时的最受欢迎的视频。 如果所有内容一次到期,则每台计算机将同时计算到期时间。 这产生了一个雷电群。 * 抖动表示您在 18-30 小时之间随机失效。 这样可以防止事情堆积。 他们在各处使用它。 当操作排队并试图破坏自身时,系统倾向于自我同步。 令人着迷的观看。 一台计算机上的磁盘系统运行缓慢,每个人都在等待一个请求,因此所有其他计算机上的所有其他请求突然之间完全同步。 当您有很多机器并且有很多事件时,就会发生这种情况。 每个人实际上都从系统中删除了熵,因此您必须重新添加一些熵。 * **作弊-知道如何伪造数据** * 很棒的技术。 最快的函数调用是不会发生的。 当您拥有一个单调递增的计数器(例如电影观看次数或个人资料观看次数)时,您可以在每次更新时进行一次交易。 或者,您可以不时进行一次交易,并随机更新一次,只要交易从奇数变为偶数,人们可能会认为这是真实的。 知道如何伪造数据。 * **可扩展组件-自己创造运气** * **您可以查看一个 API 并获得良好的感觉**。 输入是否定义明确? 你知道你要出去吗? 其中很多最终都与数据有关。 严格说明每个函数将输出什么数据以及它如何流动,实际上可以帮助您在没有文档的情况下理解应用程序。 您可以分辨出在调用函数之前和之后发生的情况。 * **在 Python 中,事情倾向于向 RPC** 发展。 代码的结构基于程序员的纪律。 因此要建立良好的约定,当所有其他方法都失败时,就会出现 RPC 隔离墙,以便您了解其中的内容和结果。 * **您的组件将不完美**。 知道,一个组件可能会持续一个月或六个月。 通过画出这些线条,您正在自己赚一些钱。 当事情发展到南方时,您可以将其换成其他东西。 有时用 python 和 C 重写某些内容,有时则意味着完全摆脱它。 直到您能够观察到,您才知道。 * **团队中有这么多人,没人知道整个系统**,因此您需要定义组件。 这是视频转码,与视频搜索不同。 您需要定义明确的子组件。 好的软件设计。 这些事情最终导致彼此交谈,因此拥有一个良好的数据规范将很有帮助。 他最大的罪过是 Servlet 层和模板层之间的通信,使之成为字典。 好主意。 应该添加一个 WatchPage 并说一个观看页面有一个视频,一些评论和一些相关视频。 这引起了很多问题,因为字典可以具有数百个属性。 他们并不总是做出正确的选择。 * **效率-以可扩展性为代价** * **效率是以可伸缩性** 为代价的。 最有效的方法是用 C 编写并将其塞入一个进程,但这是不可扩展的。 * **关注宏级别** **,您的组件以及它们如何分解**。 将此做为 RPC 还是以内联方式有意义? 将其分成一个子包,就可能有一天可能会有所不同。 * **关注算法** 。 在 Python 中,实现良好算法的工作量很低。 例如,有 bisect 模块,您可以在其中获取列表,做一些有意义的事情,并将其序列化到磁盘上,然后再次读回。 对 C 有罚款,但这很容易。 * **测量** 。 在 Python 中,测量就像阅读茶叶一样。 Python 中有很多与直觉相反的东西,例如抓斗成本。 他们的大多数应用程序都花时间进行序列化。 对序列化进行概要分析非常取决于您要插入的内容。对 int 进行序列化与对大 blob 进行序列化有很大不同。 * **Python 的效率-知道不该做什么** * **有关了解不要做什么的更多信息** 。 您制作事物的动态程度与运行 Python 应用程序的昂贵程度相关。 * **Dummer 代码更易于 grep 且易于维护** 。 代码越神奇,就越难弄清楚其工作原理。 * **他们并没有做很多 OO** 。 他们使用很多命名空间。 使用类来组织数据,但很少用于 OO。 * **您的代码树是什么样的?** 他希望用以下词语来形容它:简单,实用,优雅,正交,可组合。 这是一个理想,现实有点不同。 ## 相关文章 * [使用 Python 调整 YouTube 大小](http://www.slideshare.net/didip/super-sizing-youtube-with-python) * [扩展 Web 的 MySQL 数据库](http://www.percona.com/live/mysql-conference-2012/sessions/scaling-mysql-databases-web) * [YouTube 架构](http://highscalability.com/youtube-architecture) * [关于 HackerNews](http://news.ycombinator.com/item?id=3757456) 不错。 可以使用一些校对方法,因为我不得不在某些语言被弄乱的地方放慢脚步,例如“那些东西你想早点弄清楚,因为它们会影响你的成长方式。” 否则,有趣的阅读使我想给 python 多一点关注。 嗯,但公平地说,YouTube 使用 lighttpd 吗? 通过萤火虫:http://i.imgur.com/ClSH4.png “ Apache 是​​YouTube 上真正的摇滚明星技术,因为它们使它保持简单。每个请求都通过 Apache 进行。” “您建立了一个非常大的机架,将机器插入其中,然后进行 lighttpd” 如果 Apache 很棒,为什么他们选择 lighttpd 代替呢? 这是否还意味着“每个请求都通过 Apache”的语句不正确? 好文章。 还有一些 UX 良好做法。 @ Michal,@ Andy:这些语句是在 CDN 的上下文中的,因此您可以假定它们意味着 CDN 将 lighttpd 用于静态内容,而将 Apache 用于其余内容。 前 YouTuber 在这里... Apache 是​​他们处理动态 Web 请求的方式。 主页,观看页面,用户页面等。在早期,视频流媒体,视频上传者和图像上传者在 Lighthttpd 上运行,因为它能够更好地处理非交互式数据流。 当我两年多前离开时,他们正处于将大多数视频流切换到基于 Google 的基础架构的过程中,因为 Google 基础架构具有对等协议和更高的带宽成本。 在此过程中,他们似乎决定保留旧的视频流,并将其用于静态内容服务(Lighthttpd 做得很好)。 顺便提及,随机更新事物最近已获得专利。 @michal @andy,听起来好像 apache 是​​他们的 Web 服务器,而 lighttpd 驱动了 CDN,因此在外部您会收到 lighttpd 标头,但 apache 确实在做这项工作。 作为对 YouTube 的致敬,您可以将其制作成 30 分钟的视频吗? 大声笑 您可以同时使用 apache 和 lighttpd 来实现目标。 如果这篇文章更详细地解释每一个 YouTube 服务的内容,那将是很好的。 看起来.ligspd 至少提供了.css 文件,这是其静态内容。 “ YouTube 不是异步的,一切都在阻塞。” 为什么? 我以为大家都同意,最好的办法就是去医院。 也许它可以防止出现错误: “所有形式的异步 I / O 都会打开应用程序,直至出现潜在的资源冲突和相关的故障。需要仔细的编程(通常使用互斥,信号量等)来防止这种情况。” 资料来源:http://en.wikipedia.org/wiki/Asynchronous_I/O 谈到简单而可靠的工具:Youtube 什么时候切换到 PostgreSQL? 感谢您的出色总结! 哇,什么是“夏季代号”?