YouTube网站架构

YouTube的成长速度惊人,目前每天视频访问量已达1亿,但站点维护人员很少。他们是如何管理,以实现如此强大供应能力的?被Google收购后,又在走什么样的发展道路呢?

平台

Apache

l  Python

Linux (SuSe版本)

MySQL

l  psyco(python->C动态编译器)

lighttpd(取代Apache作为视频服务器)

统计数据

l  每天高达1亿的视频访问量。

l  创建于2005年2月。

l  2006年3月,每日视频访问量达到3千万。

l  2006年7月,每日视频访问量达到1亿。

l  2个系统管理员,2个系统扩展架构师。

l  2个产品功能开发人员,2个网络工程师,1个DBA。

性能监控手段

网站维护人员每天多次重复的工作,类似于执行下面这段代码。

while (true)

{

identify_and_fix_bottlenecks();

drink();

sleep();

notice_new_bottleneck();

}

Web服务器

l  NetScalar用于实现负载均衡和对静态内容的缓存。

l  Apache运行于mod_fast_cgi模式。

l  一台Python应用服务器专门负责Web请求的路由。

l  应用服务器与各个数据库和其他类型信息源建立会话,取得所需数据并生成HTML页面。

l  通过增加服务器,一般就可以实现对Web层的扩展。

l  Python代码的效率一般不是瓶颈所在,真正瓶颈在于RPC请求。

l  Python应用的开发和发布快速灵活,这是他们能够应对激烈竞争的重要保证。

l  正常情况下,能将每个页面的响应时间控制在100ms以内。

l  利用psyco(python->C的动态编译器),通过JIT编译方法实现内部循环的优化。

l  在CPU高敏感的活动(如加密)中使用C扩展。

l  预生成某些HTML页面并缓存。

l  在数据库中实现行级缓存。

l  对Python结果对象缓存。

l  预先计算某些数据,并发送至对应应用,以形成本地缓存。这项策略目前还未大规模运用。不需要每个应用服务器都花很多时间将预先计算,并将结果数据发送到所有服务器。有一个代理机专门负责此项工作——监控数据的变化情况,预先计算并发送。

视频服务

l  成本,包括带宽、硬件购置和电力的消耗。

l  每段视频均通过刀片群集(mini-cluster)服务器管理,也就是说由多个机器联合提供视频内容服务。

l  刀片群集管理的优势:

n  多个磁盘提供内容服务,意味着更快的速度。

n  提供了动态余量。一台机器停止服务,其他可以接管。

n  实现了在线备份。

l  使用lighttpd作为视频的Web服务器:

n  Apache的成本太高。

n  使用epoll同时操作多个fds(文件描述符)。

n  从单进程切换到多进程,以处理更多连接。

l  将频繁访问的内容转移到CDN(content delivery network):

n  CDN将内容复制到多个源,因此对用户来说,获取数据时可以选择最优路径。

n  CDN服务器主要依靠内存提供服务,否则因访问频繁,可能引起抖动。

l  低访问量的内容(每天1-20的访问量),YouTube服务器以colo模式管理。

n  长尾效应。单个视频的访问量不高,但大量视频合起来就不一样了。各磁盘块被访问到的概率是随机的。

n  在这种情况下,花费了大量投入的缓存,作用并不大。这个问题是当前研究的一个热点。如果你有一个长尾型的产品,请记住缓存不见得就是解决性能问题的救世主。

n  优化调整RAID控制器,在底层策略上下功夫。

n  调整每台服务器上的内存,不要太大也不要太小。

视频服务中的几个关键点

l  整体方案力求简洁、廉价。

l  网络路径保持最短,不要在内容和终端用户间部署太多设备。路由器、交换机等可能承受不了这么高的负载。

l  尽量采用普通硬件。高档硬件的支撑设备很昂贵,实际中往往发现它们的作用并不大。

l  使用简单、通用的工具。YouTube优先考虑Linux自带的大多数工具。

l  正确处理随机寻道问题(采用SATA、优化调整等)。

视频截图的处理

l  实现视频截图和缩略图的高效访问,有着惊人的难度。

l  如果每视频平均4个缩略图,那么总图量是非常庞大的。

l  缩略图存储在有限几台机器上。

l  大量小型对象服务中存在的难点问题:

n   磁盘寻道频繁,操作系统级inode(译者注:Linux/Unix系统中记录文件信息的对象)缓存和页缓存多。

n  每个目录受到最大文件数限制。Ext3文件系统可管理的目录层级非常多,即便依托2.6内核将大目录处理性能提高100倍左右,在文件系统中存储大量文件情况下,仍然不是一个值得称许的解决策略。

n  平均含60个缩略图的页面的访问量很大。

n  在如此高负载条件下,Apache的性能急剧下降。

n  使用squid(反向代理)作为Apache的前端,能起到一定作用。但随着负载的上升,性能最终会呈下降趋势——处理能力由原来的300个/s降为20个/s。

n  尝试使用lighttpd。这是一个单进程且单线程的应用,每个进程拥有独立缓存。为了提高性能,需要运行多个进程实例。如此一来,造成了资源浪费和性能限制等问题。

n  大量图片需要处理的情况下,向系统新增一台机器,需要24个小时。

n  重启机器后,系统需要花费6-10小时,来将内容从磁盘载入缓存。

l  为了解决这些问题,他们使用了Google的分布式数据存储策略——BigTable

n  将文件拢在一起,避免了小文件问题。

n  速度快;即使运行在不可靠网络上,其错误率也是可以容忍的。

n  未知风险小,因为它使用了分布式的多级缓存。缓存工作于colo结构上。

数据库[DSJ2]

l  早期:

n  使用MySQL存储用户、标签和详细描述等原数据。

n  数据存储在挂10磁盘、10卷的单片RAID上。

n  租借硬件。负载上升,添加新设备时他们需要数天时间。

n  和其他很多系统一样,他们走过了这样一段历史:单服务器,主从服务器(单台主服务器,依靠多台从服务器实现读数据的负载均衡),数据库分割(逐渐稳定于分割模式)。

n  存在数据复制延迟的问题。主服务器是多线程的,硬件条件好,性能高;而从服务器运行于单线程模式,且硬件条件差一些。数据从主服务器到从服务器的复制是异步的,因此从服务器上的数据往往严重滞后于主服务器。

n  数据更新后,缓存将被清除,需从I/O更慢的磁盘读取,从而造成复制更为缓慢。

n  在这种以数据复制为中心的架构下,稍微提升写性能,都必须付出巨大成本。

n  他们的解决办法之一是将数据分割到两个不同群集,从而分解访问压力:一个视频池和一个普通群集。这个解决方案的出发点是:访问者最想看到的是视频,因此应该为这些功能分配最多资源;而YouTube社交功能是次重要的,因此做次优配置。

l  后来:

n  继续执行数据库分割策略。

n  按用户划分数据。

n  数据的读、写操作分离。

n  改进了缓存数据定位策略,减少I/O。

n  所需硬件减少了30%。

n  数据复制延迟降为0。

n  现在几乎能做到对数据库任意扩展。

数据中心策略

l  开始的时候使用托管机房。除非事先签订了协议,不能自行扩展硬件和网络系统。因此,他们后来选择了colo,可以完全按照自己的设计要求部署系统。

l  使用5/6个数据中心,外加CDN。视频的来源可以是任何一个数据中心,而非就近选择等模式。若访问频度很高,则移至CDN。

l  视频的访问性能依赖于带宽,而不是其他因素。对于图片,其他因素的影响就很大(例如页面平均图片数)。

l  利用BigTable将图片复制到各个数据中心。

经验教训

l  敢于坚持。 局部创新和一些有一定风险的策略,能够解决短期问题。如果一直坚持下去,就一定能找到长期解决方案。

l  确定事情的优先级。找出服务中的关键部分,优先为其配置资源、投入力量。

l  学会选择与合作。不要害怕将项目的关键部分外包。YouTube使用CDN向广大用户提供内容。如果完全依靠自己建设这样一个网络,需要花费的成本和时间都是惊人的。在你的系统中,应该可以存在这类同样的部件。

l  一切从简! 简单,将保证系统具有良好的可重构性以及对问题的快速响应。没有人真正知道怎么样才算是简单,如果在需要做出改变时,相关人员没有产生畏难情绪,就说明达到了简单的目标。

数据分割。数据分割策略将实现对磁盘、CPU、内存和IO实体和指标的优化配置,改善的不仅仅是写数据的性能。

l  对瓶颈资源做持续改善:

n  软件层:数据库、缓存

n  操作系统层:磁盘I/O

n  硬件层:内存、RAID

l  团队是成功的基础。在一个有良好纪律的团队中,所有成员都能够准确把握整个系统,了解深层问题。拥有一个好的团队,将无往而不胜。

你可能感兴趣的:(YouTube网站架构)