本文最初发布于Medium博客,经原作者授权由InfoQ中文站翻译并分享。
多年来,Netflix一直是全球最出色的在线订阅制视频流媒体服务,其流量占全球互联网带宽容量的15%以上。截至2019年,Netflix已拥有1.67亿订阅用户,每个季度新增500万订户,服务覆盖全球200多个国家/地区。Netflix用户每天在4000多部电影和47000集电视剧上花费超过1.65亿小时的时间。从工程角度看,这些令人印象深刻的统计数据向我们展示了Netflix的技术团队设计出了多么优秀的视频流系统;这套系统具有很高的可用性和可扩展性,能为全球客户提供服务。
但是,该公司的技术团队花了超过8年时间才打造出今天这样强大的IT系统。实际上,Netflix的基础架构转型始于2008年8月,当时他们的数据中心遇到了服务中断的故障,导致整个DVD租赁服务关闭三天。Netflix意识到,它需要一个没有单点故障的更可靠的基础架构。因此它做出两个重要决定:将IT基础架构从自己的数据中心迁移到公共云上,并通过微服务架构,用较小的易管理软件组件替换单体程序。这两个决定为今天Netflix的成功打下了坚实基础。
Netflix之所以选择AWS云来迁移其IT基础架构,是因为AWS可以在全球范围内提供高度可靠的数据库、大规模云存储和众多数据中心。Netflix利用了由AWS构建和维护的云基础架构,从而免去自建数据中心的繁重重复劳动,并将更多精力放在提供高质量视频流体验的核心业务上。尽管Netflix必须重建整个技术体系,以使其能在AWS云上平稳运行,但作为回报,系统的可扩展性和服务可用性得到显著提高。
Netflix还是微服务架构背后的首批主要推动者之一。微服务鼓励关注点分离来解决单体软件设计存在的问题。在这种架构中,大型程序通过模块化和独立的数据封装被分解为许多较小的软件组件。微服务还通过水平扩展和工作负载分区来提升可扩展性。采用微服务后,Netflix工程师可以轻松更改任何服务,从而加快部署速度。更重要的是,他们能跟踪每个服务的性能水平,并在其出现问题时与其他正在运行的服务快速隔离开来。
Netflix基于亚马逊云计算服务(AWS),及公司内部的内容交付网络Open Connect运营。两套系统必须无缝协作才能在全球范围内提供高质量的视频流服务。从软件架构的角度来看,Netflix包括三大部分:客户端、后端和内容交付网络(CDN)。
客户端是用户笔记本电脑或台式机上所有受支持的浏览器,或者智能手机/智能电视上的Netflix应用。Netflix开发了自己的iOS和Android应用,试图为每个客户端和每台设备都能提供最佳的观看体验。Netflix可以通过其SDK控制自己的应用和其他设备,从而在某些场景下(例如网络速度缓慢或服务器超载)透明地调整流服务。
后端包括完全在AWS云上运行的服务、数据库和存储。后端基本上可以处理不涉及流视频的所有内容。后端的某些组件及其对应的AWS服务列举如下:
Open Connect CDN是称为Open Connect Appliances(OCAs)的服务器网络,已针对存储和流传输大尺寸视频进行了优化。这些OCA服务器放置在世界各地的互联网服务提供商(ISP)和互联网交换位置(IXP)网络内。OCA负责将视频直接流传输到客户端。
当订阅者单击应用或设备上的播放按钮时,客户端将与AWS上的后端和Netflix CDN上的OCA对话以流传输视频。下图说明了playback流程的工作机制:
用于流视频的playback架构
在上图中,Playback应用服务、引导服务和缓存控制服务完全在基于微服务架构的AWS云中运行。在下一节中我将介绍Netflix后端微服务架构,该架构可提高当前服务的可用性和可扩展性。
如前所述,后端要处理几乎所有内容,从注册、登录、计费到更复杂的处理任务,如视频转码和个性化推荐等无所不包。为同时支持在同一底层基础架构上运行的轻量与重量级负载,Netflix为其基于云的系统选择了微服务架构。图2展示了Netflix可能使用的微服务架构,我从一些在线资源中总结出了这些架构形态:
基于多种来源分析得出的后端架构参考
上述架构可以帮助我们概括了解系统的各个部分如何组织和协同工作以流传输视频。但要分析这一架构的可用性和可扩展性,我们需要深入研究每个重要组件,以了解其在不同负载下的性能表现。下一节将具体介绍这部分内容。
本节会深入研究第2节中定义的组件,以分析其可用性和可扩展性。在介绍每个组件时,我还将说明它们是如何满足这些设计目标的。在后面的章节中将对整个系统进行更深入的设计分析。
Netflix技术团队投入了大量精力来开发能在笔记本、台式机或移动设备上运行得更快、更智能的客户端应用。即使在某些没有专用Netflix客户端的智能电视上,Netflix仍然可以通过自己提供的SDK来控制设备的性能表现。实际上,任何设备环境都需要安装Netflix Ready Device Platform(NRDP),以实现最佳的观看体验。图3展示了一个典型的客户端结构组件。
客户端应用组件
API网关服务(API Gateway Service)组件与AWS负载均衡器(Load Balancer)通信以解析来自客户端的所有请求。该组件可以部署到位于不同区域的多个AWS EC2实例上,以提高Netflix服务的可用性。图4展示了开源的Zuul,这是Netflix团队创建的API网关的实现。
Zuul网关服务组件
应用程序API充当Netflix微服务的业务流程层(也称编排层)。这种API提供了一种逻辑,按所需顺序组装对底层微服务的调用,并带有来自其他数据存储的额外数据以构造适当的响应。Netflix团队花了很多时间设计应用程序API组件,因为它对应Netflix的核心业务功能。它还需要在高请求量下具有可扩展和高可用性。当前,应用程序API分为三类:用于非会员请求(例如注册、下单和免费试用等)的注册(Signup)API,用于搜索和发现请求的发现(Discovery)API,以及用于流视频和查看许可请求的播放API。图5提供了应用程序API的详细结构组件图。
播放和发现应用程序API的分离
由于应用程序API必须处理大量请求并构造适当的响应,因此其内部处理工作需要高度并行运行。Netflix团队发现正确的方法是同步执行和异步I/O相结合应用。
应用程序API的同步执行和异步I/O
按照Martin Fowler的定义,“微服务是一组小型服务,每个小服务都在自己的进程中运行,并使用轻量机制通信……”。这些小型程序可以独立部署或升级,并具有自己的封装数据。
Netflix上的微服务组件实现如图7所示。
微服务的结构化组件
Netflix将其基础架构迁移到AWS云时,针对不同的用途使用了不同的数据存储(图8),包括SQL和NoSQL。
部署在AWS上的Netflix数据存储
流处理数据管道(Stream Processing Data Pipeline)已成为Netflix业务分析和个性化推荐任务的数据骨干。它负责实时生成、收集、处理和汇总所有微服务事件,并将其移动到其他数据处理器上。图9展示了该平台的各个部分。
Netflix的Keystone流处理平台
Open Connect是一个全球内容交付网络(CDN),负责存储Netflix电视节目和电影并将其交付给全世界的订户。Netflix为了让人们想要观看的内容尽可能靠近他们想要观看的位置,而构建和运营了Open Connect这一高效率的网络。为了将观看Netflix视频的流量导向到客户的当地网络中,Netflix已与世界各地的互联网服务提供商(ISP)和互联网交换点(IX或IXP)合作,以在这些合作伙伴的网络内部部署称为Open Connect Appliances(OCA)的专用设备。
将OCA部署到IX或ISP站点
OCA是经过优化的服务器,用于存储来自IX或ISP站点的大型视频文件,并直接流式传输到订户的家中。这些服务器会定期向AWS上的Open Connect控制平面(Control Plane)服务报告自己的运行状况指标,包括它们从IXP/ISP网络学到的最佳路径,以及自己的SSD上都存储了哪些视频等信息。反过来,控制平面服务将根据这些数据中反映的文件可用性、服务器健康状况以及与客户端的网络距离等指标,自动引导客户端设备到最佳的OCA上。
控制平面服务还控制每晚在OCA上添加新文件或更新文件的填充(filling)行为。填充行为如图11所示。
OCA之间的填充模式
在前面的章节中,我详细介绍了为Netflix视频流业务提供支持的云架构及其组件。在本节和后续章节中,我想更深入地分析这种设计架构。我会从最重要的设计目标列表开始,如下所示:
在下面的小节中,我将分析流服务的可用性及其对应的最佳延迟。第6节是关于弹性机制(例如混沌工程)的更深入分析,而第7节介绍了流服务的可扩展性。
根据定义,系统的可用性是用一段时间内对请求的响应有多少次来衡量的,但不能保证响应包含了信息的最新版本。在我们的系统设计中,流服务的可用性是由后端服务和保存流视频文件的OCA服务器的可用性共同决定的。
后端服务的目标是通过缓存或某些微服务的执行来获取最接近特定客户端的健康OCA列表。因此,其可用性取决于涉及播放请求的众多组件:负载均衡器(AWS ELB)_代理服务器(API网关服务)、播放API、微服务的执行、缓存存储(EVCache)和数据存储(Cassandra):
当客户端从后端接收到OCA服务器列表时会在网络上探测这些OCA,并选择最佳的OCA进行连接。如果该OCA在流处理过程中超载或失败,则客户端将切换到另一个状态良好的OCA上,否则Platform SDK将请求其他OCA。因此,其可用性与ISP或IXP中所有可用OCA的可用性高度相关。
Netflix流服务的高可用性是以复杂的多区域AWS运维和服务,以及OCA服务器的冗余为代价的。
流服务的等待时间主要取决于播放API能多快地解析健康的OCA列表,以及客户端与所选OCA服务器的连接健康水平。
正如我在应用程序API组件部分中所述,播放API不会永远等待微服务的执行,因为它使用Hystrix命令来控制获取到结果之前要等待的时间,一旦超时就会从缓存获取非最新数据。这样做可以将延迟控制在可接受的水平上,还能避免级联故障影响更多服务。
如果当前选定的OCA服务器出现网络故障或超载,则客户端将立即切换到其他具有最可靠网络连接的OCA服务器上。如果发现网络连接质量下降,它也可以降低视频质量以使其与网络质量相匹配。
经过认真考虑,在上述系统设计中已经做出了两个重要的权衡:
该系统后端服务的架构设计选择了用一致性来换取低延迟。播放API可以从EVCache存储或最终一致的数据存储(如Cassandra)中获取过时的数据。
类似地,所谓用一致性换取高可用性的权衡是说,系统希望以可接受的延迟发起响应,而不会对像Cassandra这样的数据存储中的最新数据执行微服务。
在可扩展性和性能之间还存在不完全相关的权衡。在这种权衡下,通过增加实例数量来处理更多负载来提高可扩展性,可能会导致系统达不到预期的性能提升水平。对于那些无法在可用worker之间很好地平衡负载的设计架构来说,这可能是个问题。但是,Netflix通过AWS自动扩展解决了这一矛盾。我们将在第7节中具体讨论这个解决方案。
从迁移到AWS云的那一天起,设计一套能够从故障或停机中自我恢复的云系统就一直是Netflix的长期目标。该系统已解决的一些常见故障如下:
解析服务依赖项时失败。 执行微服务时的失败,导致级联失败影响其他服务。 由于过载导致无法连接到某个API上。 连接到实例或服务器(如OCA)时失败。
为了检测并解决这些故障,API网关服务Zuul提供了一些内置功能,如自适应重试和限制对应用程序API的并发调用等。反过来说,应用程序API使用Hystrix命令来使对微服务的调用超时,以停止级联故障并将故障点与其他服务隔离开来。
Netflix技术团队也以其在混沌工程上的实践而闻名。这个想法是将伪随机错误注入生产环境,并构建解决方案以自动检测、隔离这类故障,并从中恢复。这些错误可能会增加执行微服务的响应的延迟、杀死服务、停止服务器或实例,甚至可能导致整个区域的基础架构瘫痪。通过有目的地使用检测和解决此类故障的工具,将现实的生产故障引入受监控的环境,Netflix可以在这类缺陷造成较大问题之前提早发现它们。
在本节中,我将介绍水平扩展、并行执行和数据库分区这些Netflix的流服务可扩展性要素。缓存和负载均衡等要素也有助于提高可扩展性,它们已在第4节中提到了。
首先,AWS自动扩展(Auto Scaling)服务提供了Netflix上EC2实例的水平扩展能力。当请求量增加时,这个AWS服务将自动启动更多弹性实例,并关闭未使用的实例。更具体地说,在成千上万个此类实例的基础上,Netflix构建了一个开源容器管理平台Titus,其每周可运行约300万个容器。同样,图2架构中的任何组件都可以部署在容器内。此外,Titus允许容器运行在全球各大洲的多个区域内。
其次,第3.2.2节中应用程序API或微服务的实现还允许在网络事件循环和异步传出事件循环上并行执行任务,从而提高了可扩展性。
最后,宽列存储(如Cassandra)和键值对象存储(如ElasticSearch)还提供了高可用性和高可扩展性,同时没有单点故障。
这篇研究描绘了Netflix流服务的整体云架构图景。本文还从可用性、延迟、可扩展性和对网络故障或系统中断的适应性方面分析了相应的设计目标。
总的来说,Netflix的云架构已经过了其生产系统的验证,可以为在数千个虚拟服务器上运行的数百万个订户提供服务;该架构还通过与AWS云服务的集成在全球范围内提供了高可用性、最佳延迟、强大的可扩展性以及对网络故障和系统故障的恢复能力。本文提到的大多数架构和组件都是通过互联网上的可信在线资源学习总结出来的。尽管网上没有太多资源能直接介绍这些微服务的内部实现,以及监视其性能表现的工具和系统,但本文的研究成果可以作为构建典型生产系统的参考实现。
英文原文:
A Design Analysis of Cloud-based Microservices Architecture at Netflix
领取专属 10元无门槛券
私享最新 技术干货