多年来Netflix一直是全球最好的在线订阅式视频服务供应商,其带宽占全球互联网带宽容量的15%以上。2019年,Netflix已经拥有了1.67亿用户,每季度新增用户超过500万,在200多个国家和地区运营。Netflix的用户每天观看视频超过1.65亿小时,每天点播了4000多部电影以及4.7万集剧集。从工程的角度来看,Netflix的技术团队为了服务于全球用户,设计了如此惊人的视频流媒体系统,该具备非常高的可用性和可扩展性。
然而,Netflix的技术团队花了8年多的时间,才打造了现有的系统([1])。实际上,Netflix的基础设施转型始于2008年8月,当时Netflix经历了一次系统宕机(在自己的机房),导致整个DVD租赁服务中断了三天。Netflix意识到,它需要没有单点故障的更可靠的基础设施。因此,它做出了两个重要的决定:将IT基础设施从自己的数据中心迁移到公共云上,用微服务架构取代单体应用程序。这两个决定直接导致了Netflix今天的成功。
Netflix之所以选择AWS云([[4])来迁移其IT基础设施,是因为AWS可以提供高度可靠的数据库、大规模云存储和全球多个数据中心。通过利用AWS构建和维护的云基础设施,Netflix没有做建设数据中心这种无差别化的重活,而是更专注于高质量流媒体的核心业务。尽管它需要重建整个技术栈,让其在AWS云上顺利运行,但同时也收获了系统的可扩展性和可用性的提升。
Netflix也是微服务架构的主要推动者之一。微服务针对单体软件设计中存在的问题,鼓励分离关注([11]),单体程序通过自身的模块化和数据封装被分解成更小的软件组件。微服务还有助于通过横向扩展和工作负载分区来提高可扩展性。通过采用微服务,Netflix的工程师可以轻松地改变任何服务,从而实现更快的部署。更重要的是,他们可以跟踪每个服务的性能,并快速将其与其他运行中的服务隔离开来。
在本文中,我试图阐述Netflix的云架构在不同工作负载和网络限制下的性能。具体来说,我想从可用性、延迟、可扩展性和从网络故障或系统中断的恢复能力等方面分析系统设计。本文的组织方式如下。第2节将描述Netflix系统架构。然后在第3节,将更详细的讨论系统组件。在第4、5、6、7节中,我将根据上述设计目标对系统进行分析。最后,我总结了从这次分析中学习到的东西以及下一步可能需要改进的地方。
Netflix基于亚马逊云计算服务(AWS)和内部CDN Open Connect(Open Connect)运营([1])。这两个系统必须无缝配合,才能在全球范围内提供高质量的视频流媒体服务。从软件架构上看,Netflix主要由三部分组成。客户端、后台和CDN。
客户端是指笔记本电脑或台式机上的任何支持的浏览器,或者智能手机或智能电视上的Netflix应用。Netflix开发自己的iOS和Android应用,为每一个客户端和设备提供最佳的观看体验。通过其SDK控制自己的应用和其他设备,Netflix可以在某些情况下透明地调整流媒体服务,比如网络速度慢或服务器过载等情况下,Netflix可以对其流媒体服务进行调整。
后端包括在AWS云上运行的服务、数据库、存储。Backend基本上可以处理所有不涉及流媒体的工作。Backend的一些组件及其对应的AWS服务如下。
Open Connect CDN是一个名为Open Connect Appliances (OCAs)的服务器网络,用于存储和串流大型视频。这些OCAs服务器分布在位于世界各国的ISP和IXP网络内。OCAs负责将流媒体传输到客户端。
在下面的章节中,笔者将介绍由上述3部分组成的Netflix云架构。在2.1节中,我们将描述播放架构。然后在2.2节中,将描述更详细的Backend的微服务架构,展示Netflix如何处理全球规模下的可用性和可扩展性问题。
当用户在自己的应用程序或设备上点击播放按钮时,客户端将与AWS上的Backend和Netflix CDN上的OCAs进行通信,以流化视频([[7])。) 下图说明了播放过程的工作原理。
在上图中,Playback Apps服务、Steering服务和Cache Control服务完全是在AWS云上运行的微服务。在下一节中,我将介绍Netflix后端微服务架构,它提高了服务的可用性和可扩展性。
正如我在前面的章节中所描述的那样,Backen处理了从注册、登录、计费到视频转码和个性化推荐等复杂任务。为了支持在同一底层基础设施上运行的轻量级和重量级工作负载,Netflix选择了微服务架构。图2中的示意图代表了Netflix的微服务架构,这是笔者从多篇文章中总结而成。
上面所描述的架构让我们大致了解了不同件是如何组织和协同工作的。然而,要分析这些架构的可用性和可扩展性,我们还需要深入到每个重要的组件,看看其在不同工作负载下的表现如何。这将在下一节中介绍。
在本节中,我想深入研究第2节中定义的组件,以分析其可用性和可扩展性。在描述每个组件时,我还会分析它是如何满足这些设计目标的。在后面的章节中会有关于整个系统的更深入的设计分析。
Netflix的技术团队在开发客户端应用上投入了大量精力。即使是在一些智能电视上,虽然Netflix没有构建专门的客户端,但是仍然通过SDK来控制其性能。事实上,任何设备环境都需要安装Netflix Ready Device Platform (NRDP),以实现最佳的Netflix观看体验。典型的客户端架构组件([[11])如图3所示。
客户端应用程序使用两种类型的连接请求后台进行内容发现和播放。客户端使用NTBA协议([[15])进行播放请求,以确保其OCA服务器位置的安全性,并消除SSL/TLS握手导致的新连接延迟。
在播放流媒体视频时,如果网络连接过载或出现错误,Client App会智能地降低视频质量或切换到不同的OCA服务器([[1])。即使所连接的OCA过载或出现故障,Client App也可以轻松地切换到另一个OCA服务器,获得更好的观看体验。Netflix SDK会持续跟踪从Playback Apps服务中获取的最新健康OCA(图1)。
3.2 后端
API 网关服务
API网关服务组件与AWS负载均衡器(ELB)进行通信,服务来自客户端的所有请求。这个组件可以部署到不同区域的多个AWS EC2实例中,以提高Netflix服务的可用性。图4中的图是Netflix团队创建的Zuul API Gateway的开源实现。
应用API在Netflix微服务中扮演着服务编排([[18])的角色。API按照需要组合调用底层微服务的逻辑,并组合其他数据存储的附加数据来构造相应的响应。由于应用API组件与Netflix的核心业务功能相对应,因此Netflix团队在设计应用API组件时花了很多时间。它还需要保证在高并发下的可扩展性和高可用性。目前,应用API被定义为三类。注册API,用于非会员请求,如注册、计费、免费试用等;探索API,用于搜索、推荐请求;播放API,用于流媒体、观看授权请求。应用API的详细结构组件图如图5所示。
由于Application API需要处理海量的请求,其内部处理需要高度并行运行。Netflix团队发现,同步执行和异步I/O的结合([13])是正确的方法。
从Martin Fowler的定义来看,"微服务是一组服务,每个服务在自己的进程中运行,并通过轻量级机制进行通信........."。这些程序是可以独立部署或升级的,并且有自己的封装数据。
图7是Netflix公司的微服务组件的实现([11])。
数据存储
在将基础设施迁移到AWS云上时,Netflix使用了不同的数据存储(图8),包括SQL和NoSQL([6])。
Stream Processing Data Pipeline([14,3])已经成为Netflix业务分析和个性化推荐任务的数据骨干。它负责生产、收集、处理、聚合所有微服务事件,并将所有微服务事件近乎实时地转移到其他数据处理器。图9显示了该平台的各个部分。
2.3 Open Connect
Open Connect是一个全球内容交付网络(CDN),负责存储并向全球范围内的用户交付Netflix电视节目和电影。Netflix通过将人们想看的内容尽可能地推送到用户附近,以保证高效推流。为了将 Netflix 视频的流量本地化,Netflix与世界各地的互联网服务提供商(ISPs)和互联网交换点(IXs或IXPs)合作,在其网络内部部署专门的设备,称为Open Connect Appliances(Open Connect Appliances,简称OCA)([7])。
OCAs是用于从IX或ISP站点直接存储流媒体文件并将其流化的服务器。这些服务器会定期向AWS上的Open Connect控制平面服务报告路线情况,以及他们在SSD磁盘上存储了哪些视频。控制平面服务会根据文件可用性、服务器健康状况和网络接近客户端的情况,将这些数据自动引导客户端设备并计算最优化的OCA。
控制平面服务还可以控制夜间在OCAs上添加新文件或更新文件的填充行为。这些填充行为([[8,9])如图11所示。
在前面的章节中,我已经详细描述了云架构及其支撑 Netflix 视频流媒体的业务组件。在本节和后续章节中,我想深入分析一下该架构。我先从最重要的设计目标开始,具体如下。
在这几个小节中,我将分析流媒体服务的可用性和相应的最佳延迟。第6节将更深入地分析有关弹性机制,如混沌工程等,而第7节将讨论流媒体服务的可扩展性。
根据定义,系统的可用性是指在一定时间内(在不保证包含最新版本信息的情况下)完成请求的次数来衡量的。在我们的系统设计中,流媒体服务的可用性既取决于后端服务的可用性,也取决于保存流媒体视频文件的OCAs服务器。
Backend服务的目标是通过缓存或者通过微服务来获取最健康的OCAs列表。因此,其可用性取决于涉及Playback请求的不同组件:负载均衡器(AWS ELB)、代理服务器(API网关服务)、Play API、相应微服务、缓存存储(EVCache)和数据存储(Cassandra)。
当从Backend接收到OCAs服务器列表时,客户端会探测网络到这些OCA,并选择最好的OCA连接。如果该OCA在流媒体过程中出现过载或失败,那么客户端就会切换到另一个好的OCA。因此它的可用性与其ISP或IXP中所有OCA的可用性高度相关。
Netflix流媒体服务的高可用性是以多区域AWS运维的复杂性和以及OCAs服务器的冗余为代价的。
流媒体服务的延迟主要取决于 Play API 能否快速找到健康 OCA 列表,以及客户端与所选 OCA 服务器的连接情况如何。
正如我在应用API组件部分所描述的那样,Play API不会永远等待微服务的执行,因为它使用Hystrix 来控制相应时间,如果超时就从缓存中获取老数据。这样做可以控制延迟在可接受范围内,同时也可以阻止级联故障。
如果当前选择的OCA服务器出现网络故障或该服务器过载,客户端将立即切换到附近其他可靠 OCA 服务器。如果发现网络连接质量下降,它还可以降低视频质量。
在上面描述的系统设计中,考虑如下的取舍。
低延时高于一致性是内置于后端服务的架构设计中。Play API可以从EVCache存储中获取老数据,也可以从Cassandra等最终一致的数据存储中获取。
同样的,可用性优于一致性,宁愿在可接受的延迟下响应请求,而不需要在像Cassandra这样的数据存储中的最新数据上执行微服务。
在可扩展性和性能之间还有一个并不相关的取舍([21])。在这种取舍中,通过增加实例数量来提高可扩展性,以处理更多的工作负载,可能会导致系统预期性能不断提高。这可能存在工作负载在可用worker之间没有很好地平衡。然而,Netflix已经通过AWS自动扩展解决了该问题。我们将在第7节中更详细地讨论这一解决方法。
设计一个能够从故障或中断中自我恢复的云系统,一直是Netflix长期以来的目标。这套系统常见的一些故障,主要有以下几点。
为了检测和解决这些故障,API网关服务Zuul([[20])内置了自适应重试、限制并发调用Application API等功能。相应的,Application API使用Hystrix 来熔断调用微服务,以防止级联故障,并将故障点与其他故障点隔离。
Netflix的技术团队也以混沌工程实践闻名。其想法是将伪随机错误注入生产环境中,并构建解决方案来自动检测、隔离和恢复此类故障。错误可能会导致延迟增加,终止服务,服务器或实例暂停,甚至拖垮一个区域的整个基础设施([5])。通过有目的地将现实生产故障引入到受监控的环境中,用工具检测和解决这类故障,Netflix 可以在引起更大的问题之前迅速发现并解决这类故障。
在本节中,我将分析Netflix流媒体服务的可扩展性,包括水平扩展、并行执行和数据库分区。其他部分如缓存和负载均衡等也有助于提高可扩展性。
首先,Netflix的EC2实例的水平扩展是由 AWS 自动扩展服务提供的。该AWS服务会在请求量增加时自动增加更多实例,并关闭未使用的实例。更具体地说,在这些成千上万的实例之上,Netflix构建了一个开源的容器管理平台Titus([17]),每周运行约300万个容器。而且,架构图2中的任何组件都可以部署在容器内部。此外,Titus允许容器在全球不同大洲的多区域运行。
其次,在3.2.2节中实现的应用API或微服务,通过在网络事件循环和异步输出事件循环上并行执行任务,增强可扩展性。
最后,像 Cassandra 这样的列存储和像ElasticSearch这样的键值对象存储也提供了高可用性和高可扩展性,没有单点故障。
本文描述了Netflix公司的流媒体服务的云架构。分析了可用性、延迟、可扩展性和对网络故障或系统中断的恢复能力等方面的不同设计目标。简而言之,Netflix的云架构,经过他们的生产系统的验证,可以在数千台服务器上运行,为数百万用户提供服务,在全球范围内,通过与AWS云服务的集成,表现出了高可用性,低延迟、强大的可扩展性,以及对网络故障和系统中断的恢复能力。
参考链接:
Netflix: What Happens When You Press Play? By Todd Hoff on Dec 11, 2017. Link
High Quality Video Encoding at Scale. By Anne Aaron and David Ronca on HighScalability. Dec 9, 2015. Link
Building and Scaling Data Lineage at Netflix to Improve Data Infrastructure Reliability, and Efficiency. By Di Lin, Girish Lingappa, Jitender Aswani on The Netflix Tech Blog. Mar 25, 2019. Link
Ten years on: How Netflix completed a historic cloud migration with AWS. By Tom Macaulay on Computerworld. Sep 10, 2018. Link
The Netflix Simian Army. By Yury Izrailevsky and Ariel Tseitlin on The Netflix Tech Blog. Link
Globally Cloud Distributed Applications at Netflix. By Adrian Cockcroft. Oct 2012. Link
Open Connect Overview. By Netflix. Link
Open Connect Deployment Guide. By Netflix. Link
Netflix and Fill. By Michael Costello and Ellen Livengood. Aug 11, 2016. Link
Automating Operations of a Global CDN. By Robert Fernandes at Strange Loop. Sep 14, 2019. Link
Mastering Chaos — A Netflix Guide to Microservices. By Josh Evans at QCon. Dec 07, 2016. Link
Netflix Revenue and Usage Statistics. By Mansoor Iqbal on BusinessofApps. March 6, 2020. Link
Netflix Play API — Why we build an Evolutionary Architecture. By Suudhan Rangarajan at QCon 2018. Dec 12, 2018. Link
Keystone Real-time Stream Processing Platform. By Zhenzhong Xu on The Netflix Tech Blog. Sep 10, 2018. Link
Netflix Releases Open Source Message Security Layer. By Chris Swan on InfoQ. Nov 24th, 2014. Link
Netflix Open Source. Link
Titus, the Netflix container management platform, is now open source. By Amit Joshi and others. Link
Engineering Trade-Offs and The Netflix API Re-Architecture. By Katharina Probst and Justin Becker on The Netflix Tech Blog. Aug 23, 2016. Link
Kafka Inside Keystone Pipeline. By Real-Time Data Infrastructure Team. April 27, 2016. Link
Open Sourcing Zuul 2. By Arthur Gonigberg and others on The Netflix Tech Blog. May 21, 2018. Link
Performance Vs Scalability. By Beekums. Aug 19, 2017. Link
参考阅读:
本文由高可用架构翻译,技术原创及架构实践文章,欢迎通过公众号菜单「联系我们」进行投稿。
原文:https://blog.51cto.com/14977574/2546131