现在的位置: 首页 > 综合 > 正文

7 Years of YouTube Scalability Lessons in 30 Minutes

2013年09月08日 ⁄ 综合 ⁄ 共 6013字 ⁄ 字号 评论关闭

原文地址:http://highscalability.com/blog/2012/3/26/7-years-of-youtube-scalability-lessons-in-30-minutes.html

如果你一开始打算做一个交友网站,到最后却做成一个视频网站(例如youtubu,一个日访问量达到4亿的视频网站),那么在这个过程中你仍然可以学到一些东西。事实上,Mike Solomon,原来youtube的一个工程师,学到了很多知识。他在PyCon上做了一个关于“可扩展性在youtube"的讲说。

这不是一个架构驱动的演讲。在这个演讲里,Mike通过一些盒子如何连接起来来引导大家。Mike曾经就职于建立Youtube的servlet的基础设施,视频索引,视频转码系统,他们的全文搜索,CND等等。But instead, he’s taken a step back, took a long look around at what time has wrought, and shared some deep lessons, obviously hard won from experience.
对于我(Mike)来说,这个演讲的重点在于要用简单的工具做很多。当很多团队转移到更加复杂的生态系统的时候,Youtube却做到了真正让这个生态系统变得简单。他们主要用Python编程, MySQL数据库,Apache作为服务器。甚至这个大规模站点的某个新特性也是由一个简单的Python开始的。
这并不意味着说Youtube不能做出很cool的东西,Youtube能做的出来。但是让这一切(文宇:一切说的是什么呢?)共同工作起来是一门哲学或者是做事的方法,而不是技术上把戏。是什么使Youtube成为世界最大的网站之一呢,请往下看。

注:Servlet是一种服务器端的Java应用程序,具有独立于平台和协议的特性,可以生成动态的Web页面。 它担当客户请求(Web浏览器或其他HTTP客户程序)与服务器响应(HTTP服务器上的数据库或应用程序)的中间层。 Servlet是位于Web 服务器内部的服务器端的Java应用程序,与传统的从命令行启动的Java应用程序不同,Servlet由Web服务器进行加载,该Web服务器必须包含支持Servlet的Java虚拟机。
 
1,     关于Youtube的统计数据
每天4亿的访问量
每分钟上传60个小时的视频
YouTube使用350多万台的设备
2010年收入翻番
视频的数量上升了9个数量级,开发者的数量仅仅上升了2个数量级
1万行的Python代码
2,    Stack
Python-YouTube的大部分代码都是Python ,每当你看一个YouTube上的视频时,就在运行一堆的Python 代码。
Apache–当你想不在使用Apache 时是做不到的。Apache在YouTube 是一个非常受用的技术,因为Apache能使YouTube保持简单。每个请求都通过Apache 。
Linux - 用linux的好处就是总能找到一个方法获取到你的系统运行的怎么样。无论你的系统的App运行的多烂,你也可以通过linux工具例如strace和tcpdump来检查这些App。
MySQL – 用的更多。当你看视频时获得到的数据都是来自MySQL的。有些时候MySQL用于关系型数据库或者blob (翻译为二进制)存储。这是关于你如何组织你的数据的调整和选择。
Vitess -  YouTube发布的一个新项目,Go语言写的,这是一个前端到MySQL。在fly上做了很多的优化,他作为代理rewrite(重写)了请求和行为。现在它为YouTube数据库请求提供服务。它基于RPC。
注:RPC(Remote Procedure Call Protocol)——远程过程调用协议,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。RPC协议假定某些传输协议的存在,如TCP或UDP,为通信程序之间携带信息数据。在OSI网络通信模型中,RPC跨越了传输层和应用层。RPC使得开发包括网络分布式多程序在内的应用程序更加容易。
Zookeeper–一个分布式的锁服务。它用于配置。非常有意思的一种技术,很难正确使用,请使用参考手册。
注:zookeeper :是一个为分布式应用提供一致性服务的软件,它是开源的Hadoop项目中的一个子项目
zookeeper : http://apps.hi.baidu.com/share/detail/32587499
            http://baidutech.blog.51cto.com/4114344/743012
Wiseguy –一个CGI servlet 容器.
Spitfire–一个模板系统。它有一个抽象句法树,在做数据转换的时候能变得更快捷。
Serialization formats(序列化格式,来自文宇译:格式是个复数,表示序列化格式有很多种形式。来自百度:将对象的状态信息转换为可以存储或传输的形式的过程。在序列化期间,对象将其当前状态写入到临时或持久性存储区。以后,可以通过从存储区中读取或反序列化对象的状态,重新创建该对象。) -无论使用哪种序列化都是花销昂贵的。需要权衡。不要胡乱使用。不是一个好的选择。发现协议缓冲慢。他们有自己的BSON实现,这种实现方式比任何一种网上下载的实现方式都要快10到15倍。
注:BSON是一种类json的二进制存储格式。
详见http://wenku.baidu.com/view/a745126f561252d380eb6eb4.html

3,    可借鉴的地方  General Lessons
Tao of YouTube:最切实可行的是在没有太多保证的情况下选择最简单的解决方案。为什么这么说呢?是因为你需要去灵活的去解决问题。举个例子,你在说一些你陷入困境的事情的时候是没有任何保证的。事情变得复杂的时候是当你要试图做到某种保证的时候,就会让你无路可走。
整个过程是说可扩展性是关于什么的:一个可扩展的系统不是遵循你的方式的系统,并不在你意识驱动下的。他是个通用的解决问题的方式。
大规模系统设计的优质所在:任何一个系统都是由它具体的需求定制的。所有的一切都依赖于你建立的需求。
YouTube是同步的,而非异步的,所有的一切都是封闭堵塞的。
关注更多的理念而不是原则,让一切变得简单。简单的意思是什么呢?简单就是你看到了你就明白了。如果你在做一个代码复查,更改了上千行的代码和无数个文件,那么一个可行的简单的方法就是你首先要做一个简单的demo,然后才去迭代。
解决问题,一个字,简单。寻找最简单的事情将会定位问题所在。在有很多复杂的问题的情况下,首先解决的不需要是复杂的,复杂的问题随着时间自然的解决了。
YouTube系统开始于一个简单的Python程序。随着时间的推移才变成一个大的代码的生态系统系的。所有的原型都是由Python写的并在很惊人的时间里继续使用。
设计复查   In a design review:
1)什么是首要先解决的?
2)怎么样去持续下去?
3)关于这些数据怎么被使用下去这件事我们知道的有多少?
随着时间的推移事情发生改变。YouTube怎样开始不关乎YouTube今后的发展。YouTube起初于一个交友网站。如果当初就设计一个视频网站,那么今天就是不一样的结果了。所以保持灵活性哦!
YouTube CDN。由于非常昂贵,所以他们自己做了一个。如果你有一个很好的搞硬盘的兄弟你就能建立一个漂亮的视频CDN。你创建了个非常大的架子,挂满的机器,然后用lighttpd,然后控制404请求以便找到你没有找到的视频。这将话费2周的时间并且第一天就服务60个gigabits。你能用简单的工具做到很多。
衡量。Vitess是用C写的,HTTP协议,并且非常慢。因此YouTube抛弃了HTTP用python做了个直接的socket连接。在整个CPU上降低的8% 的成本。(注了解socket和HTTP的差别来自文宇)http://blog.csdn.net/zeng622peng/article/details/5546384

4,    可扩展技术    Scalability Techniques
这些都不是新概念了,但是却是难以想象的核心的理念,能够应用于很多不同的领域。
1)    分而治之 Divide and Conquer - The Scalability Technique
这是个可扩展的技术。所有的一切都是关于分开来工作的。重点是确定怎么执行分开来操作。在网络层,如果你有很多的Web服务器,这些服务器或多或少的一致和独立,你从同一个层次去对待他们(来自文宇,翻译不是很到位)。这就是分而治之。
这是数据库分片(分区)的关键。你怎么把事情分开来并且将分开的部分沟通得当,这是你要最初就考虑好的,因为这会影响你的后续发展。
简单并且松散的链接是相当有价值的。
Python的动态特性就体现在这里。无论你的API多么的烂,你都能用你的方法来修改这些问题。
2)    近似正确性  Approximate Correctness - Cheat a Little
另一个有趣的技术。一个系统的平衡就是它所报告的。如果一个用户不能说出一个系统的一部分是有偏差的或者不一致的,那么它就不是平衡的。
一个有意思的例子。如果你在写一个评论与此同时另一个人在load这个页面,在300到400毫秒中是不会或得到的,看页面的人才不在乎,但是写评论的人在乎,因此你要确保写的人能够看到所写的评论。这就是一丁点的欺骗。你的系统没必要做到全局的关心所有的交互。
那将是超级花销大并且极端的情况。并不是每个评论都是金融上的交易。所以你要知道什么时候做这种欺骗是合适的。
3)    Expert Knob Twiddling(一致性,持久性)
问:关于你的一致性模型你了解吗?评论做到一致了吗?借阅电影是不同的。当涉及到钱的时候我们将做到更好。不同的一致性模型依赖于数据的不同。
4)    Jitter(抖动-添加一些平均信息量到你的系统中)。抖动就是一种随机,来自文宇。详见http://www.douban.com/group/topic/2121317/     Jitter - Add Entropy Back into Your System
如果你的系统没有Jitter,那么你的系统将会有雷鸣般的嗡嗡声。分布式应用就像是天气系统。调试他们就像是分析天气预报的确定性一样。Jitter带来了更多不可思议的随机性,使事情都堆积到一块去了。
举个例子,缓存过期。尽可能的缓存一个受欢迎的视频,最受欢迎的视频有可能被缓存24小时。如果所有的视频同一时间过期了,与此同时所有的机器将计算过期时间。这将是雷鸣般的嗡嗡声。
通过抖动可以把过期时间设定在18到30个小时之间,这阻止了事情都堆在一起。在所有的地方使用这个。系统有这么个趋向去自我同步就像是业务流水线一样。 在一台机器上你拿到的是一个变慢的硬盘系统,每个人都在等待一个请求,因此 突然在所有其他的机器上,所有这些其他的请求被完全的同步。当有很多台机器和很多事件时这就发生了。每一个没系统中移去了平均信息量,所以你不得不把平均信息量添回去。
(来自文宇,主要是说Entropy 的,这里翻译为平均信息量。不知道翻译的对不对了)
5)    欺骗-了解怎么伪装数据   Cheating - Know How to Fake Data
棒极了的技术。最快的函数调用不可能发生的。当你有个单调递增的计数器的时候,像是电影浏览过的数量或者电影概要查看过的数量,你需要每次都要更新它。还是你要做到每隔一段时间或者一个随机的量去更新它(当数量发生从奇数到偶数的变化时)。人们都会相信这个数据是真的。现在知道什么是伪造数据吧。

6)    可扩展的组件  Scalable Components - Make Your own Luck
定义良好的输入,你能够找到API。有一个紧凑的规范,关于什么的规范呢,规范数据从哪个函数中出来并且怎样去流动(传输)。这个规范帮助你在没有文档的时候去了解一个应用。在一个函数调用后你能知道发生了什么。
定义良好的独立性
在一个团队的一些人不能够去了解整个系统。因此你需要去定义组件。这是视频转码它不同于视频搜索。你需要很好的定义子组件。这才是好的软件设计。有一个好的数据规范是有益处的。做的最错的一件事就是让servlet层和模板层(模板层将会成为一个字典)之间的交互。(来自文宇:要了解问什么是不应该的)。应该有一个额外的WatchPage(查看页面)并且这个页面有一个视频有一些评论和一些相关的视频。这导致了许多问题因为字典具有很多的属性。他们并不总是做出正确的选择。
使用Python事情往往趋向于RPCs。你的代码的结构式基于程序员的自律。因此,建立良好的约定,当一切都失败了,还有一个RPC墙让你知道什么将发生。
局部优化
一个组件可能持续一个月还是六个月,谁知道呢。按照你自己的运气去花一些线。当线向南的时候你能够调整并且做些不同的事情。有些时候在python或者C里面重写一些东西意味着丢弃掉整个。你永远不知道直到你能够意识到。

7)    效率-换取了可扩展性   Efficiency - Traded Off for Scalability
效率和可扩展性不关联。最有效的事情就是用C去写并在一个进程中塞满去运行,但是这并不是可扩展性。
关注于宏观层次,让你的组件去突出重围。你确定做一个RPC或者把这些组件内联处理是有意义的吗?打破它进行封装,总有一天会用到。
关注于算法。用Python实现一个好的算法的成就是很低的。这是个一分为二的模块,在这个模块里你拿到个列表,做一些有意思的事情,然后序列化到磁盘在把他们读出来。比起C来说这是相当容易的。
懂得去衡量,在Python里衡量就像是数茶叶一样。对于Python,有很多事情和你的直觉是相反的,就像是收集垃圾的代价。大多数的APP块需要去序列化。概况的序列化依赖于你放进来什么。序列化in t和序列化bolbs有很大的不同。

8)    Python的效率是懂得什么不要做   Efficiency in Python - Knowing What Not to Do
How dynamic you make things correlates to how expensive it is to run your Python app.
Dummer代码易于grep,且易于维护。更炫的代码很难知道他是如何工作的。
没有做很多的面向对象。用了很多的命名空间,使用类去组织数据,但是很少是面向对象的。
代码管理
你的代码树将会是什么样的呢?Mike用这几个词来形容它,:简单,务实,优雅,正交,可组合。这是一个理想的,现实的情况是有点不同。

抱歉!评论已关闭.