大数据架构
【大数据】75个每个人都应该知道的大数据术语
在第一篇文章中介绍了以下术语:算法,分析,描述性分析,规定分析,预测分析,批处理,Cassandra,云计算,集群计算,黑暗数据,数据湖,数据挖掘,数据科学家,分布式文件系统,ETL,Hadoop,内存计算,IOT,机器学习,Mapreduce,NoSQL,R,Spark,流处理,结构化。非结构化数据。
现在我们来看看还有50个更大的数据条款。
Apache软件基金会(ASF)提供了许多Big Data开源项目,目前有350多个项目。我可以花一整天的时间来解释这些项目,而不是选择几个热门词汇。
Apache Kafka:以着名的捷克作家命名的卡夫卡用于构建实时数据流水线和流媒体应用。为什么这么受欢迎?因为它能够以容错的方式存储,管理和处理数据流,并据称“快速”。鉴于社交网络环境处理数据流,卡夫卡目前非常受欢迎。
Apache Mahout:Mahout提供了一个用于机器学习和数据挖掘的预制算法库,也是创建更多算法的环境。换句话说,机器学习天堂的天堂环境。机器学习和数据挖掘在我之前提到的文章中有介绍。
Apache Oozie:在任何编程环境中,您需要一些工作流系统来以预定义的方式和定义的依赖关系来安排和运行作业。 Oozie提供了用于编写猪,MapReduce和Hive等语言的大数据工作。
Apache Drill,Apache Impala,Apache Spark SQL
所有这些都提供快速和交互式的SQL,如与Apache Hadoop数据的交互。如果您已经知道SQL并处理以大数据格式存储的数据(即HBase或HDFS),这些功能非常有用。对不起,在这里好奇怪
Apache Hive:知道SQL?那么你和Hive在很好的手中。 Huve有助于使用SQL读取,写入和管理驻留在分布式存储中的大型数据集。
Apache Pig:Pig是在大型分布式数据集上创建查询执行例程的平台。所使用的脚本语言叫做Pig Latin(不,我没有做,相信我)。据说猪很容易理解和学习。但是我的问题是有多少人可以学习?
Apache Sqoop:用于将数据从Hadoop移动到非Hadoop数据存储(如数据仓库和关系数据库)的工具。
Apache Storm:一个免费的开源实时分布式计算系统。它使得使用Hadoop进行批处理的瞬时处理可以更容易地处理非结构化数据。
人工智能(AI) - 为什么AI在这里?这不是一个单独的领域,你可能会问。所有这些趋势技术是如此相关,以便我们更好地保持安静,继续学习,好吗? AI关于开发智能机器和软件,使硬件和软件的这种组合能够感知环境,并在需要时采取必要的措施,并继续学习这些操作。听起来类似于机器学习?加入我的“困惑”俱乐部
行为分析:曾经想过谷歌如何为您看来需要的产品/服务提供广告?行为分析侧重于了解消费者和应用程序的作用以及它们以某种方式行事的方式和原因。这是关于我们的网络冲浪模式,社交媒体互动,我们的电子商务行动(购物车等)的理解,并连接这些无关的数据点,并尝试预测结果。在一个例子中,我在寻找一家酒店后放弃了一个购物车,接到一个度假村假期线路的电话。需要我说更多吗?
Brontobytes-1,其次是27个零,这是明天数字宇宙的大小。当我们在这里的时候,让我谈谈太字节,太字节,Exabyte,Zetabyte,Yottabyte和Brontobyte。您必须阅读本文以了解有关所有这些术语的更多信息。
商业智能(BI):我将重用Gartner对BI的定义,因为它做得很好。商业智能(BI)是一个总括术语,包括应用程序,基础设施和工具以及最佳实践,可以访问和分析信息,以改善和优化决策和绩效。
生物识别技术:这就是James Bondish技术与分析技术相结合,通过一种或多种身体特征来识别人,如面部识别,虹膜识别,指纹识别等。
点击流分析:用于分析用户在网络上浏览的在线点击。曾经想过,为什么某些Google广告还会继续关注您,即使是切换网站等?大哥知道你在点击什么
聚类分析是一个探索性分析,试图识别数据中的结构。聚类分析也称为分割分析或分类分析。更具体地说,它试图确定同一组案例,即观察,参与者,受访者。如果分组以前未知,则使用聚类分析来识别病例组。因为它是探索性的,它确实取决于和独立变量之间的区别。 SPSS提供的不同的聚类分析方法可以处理二进制,标称,序数和比例(间隔或比率)数据。
比较分析:在这篇文章中,我将分析更深入的分析,因为大数据的圣杯是分析数据。顾名思义,比较分析是使用诸如模式分析,过滤和决策树分析等统计技术来比较多个进程,数据集或其他对象。我知道它的技术变得越来越少,但我不能完全避免行话。比较分析可用于医疗保健,以比较大量的医疗记录,文件,图像等,以更有效和希望准确的医疗诊断。
连接分析:您必须已经看到这些蜘蛛网络像图表连接主题等,以识别某些主题的影响者。连接分析是帮助您发现网络中人员,产品和系统之间的这些相互关联的连接和影响,甚至组合来自多个网络的数据的分析。
数据分析师:数据分析师是一个非常重要和受欢迎的工作,除了准备报告之外,它还负责收集,操纵和分析数据。我会提出一个关于数据分析师的更详尽的文章。
数据清理:这有点自我解释,它涉及检测和纠正或从数据库中删除不准确的数据或记录。记住“脏数据”?那么,使用手动和自动化工具和算法的组合,数据分析师可以更正和丰富数据来提高其质量。记住,脏数据导致错误的分析和不良决策。
DaaS:您有SaaS,PaaS和现在的DaaS,代表数据即服务。通过向客户提供按需访问云托管数据,DaaS提供商可以帮助快速获得高质量的数据。
数据虚拟化 - 这是数据管理的一种方法,允许应用程序检索和操作数据,而不需要其存储位置及其格式等的技术细节。例如,这是社交网络将我们的照片存储在他们的网络。
脏数据:现在,大数据变得性感,人们只是开始向数据添加形容词来提出新的术语,如暗数据,脏数据,小数据和现在的智能数据。来吧,给我一个休息,脏的数据是不干净的数据,或换句话说,数据不准确,重复和不一致的数据。显然,你不想与脏数据相关联。
模糊逻辑:我们多么确定100%的权利?很稀少。我们的大脑将数据聚合成部分真理,再次被抽象为某种阈值,这将决定我们的反应。模糊逻辑是一种计算,旨在通过消除部分真理来模仿人类的大脑,而不是像“0”和“1”这样的绝对真理,就像布尔代数的其余部分一样。重用于自然语言处理,模糊逻辑也已进入其他数据相关学科。
游戏:在一个典型的游戏中,你有像点数,与他人竞争的元素,以及某些游戏规则等元素。大数据中的游戏化是使用这些概念来收集数据或分析数据或通常激励用户。
图形数据库:图形数据库使用诸如节点和边缘之类的概念代表人物/企业及其相互关系,从社交媒体挖掘数据。曾经想过,亚马逊如何告诉你在购买产品时还会买到什么其他产品? Yup,Graph数据库!
Hadoop用户体验(Hue):Hue是一个开源的界面,使Apache Hadoop变得更加容易。它是一个基于Web的应用程序,并且具有用于HDFS的文件浏览器,MapReduce的作业设计器,用于制作协调器和工作流程的Oozie应用程序,Shell,Impala和Hive UI以及一组Hadoop API。
HANA:高性能分析应用程序 - SAP的软件/硬件内存中平台,专为大量数据交易和分析而设计。
HBase:分布式,面向列的数据库。它使用HDFS作为其底层存储,并且使用MapReduce和事务交互来支持批量风格的计算
负载平衡:跨多台计算机或服务器分配工作负载,以实现系统的最佳结果和利用
元数据:“元数据是描述其他数据的数据。元数据汇总了有关数据的基本信息,可以使查找和处理特定数据实例更容易。例如,作者,创建日期和日期修改以及文件大小是非常基本的文档元数据。除文档文件外,元数据也用于图像,视频,电子表格和网页。“来源:TechTarget
MongoDB:MongoDB是一个跨平台的开源数据库,它使用面向文档的数据模型,而不是传统的基于表的关系数据库结构。这种类型的数据库结构旨在使结构化和非结构化数据在某些类型的应用程序中的集成更加容易和快速。
混搭:幸运的是,这个术语对我们在日常生活中了解混搭的定义类似。基本上,mashup是将不同数据集合并为单个应用程序的一种方法(示例:将房地产列表与人口统计数据或地理数据相结合)。这是非常酷的可视化。
多维数据库:针对数据在线分析处理(OLAP)应用程序和数据仓库进行了优化的数据库。如果您想知道数据仓库,它只不过是数据多个数据源的核心存储库。
MultiValue数据库:它们是一种直接了解3维数据的NoSQL和多维数据库。他们很好地直接操作HTML和XML字符串。
自然语言处理:软件算法旨在使计算机能够更准确地了解每天的人类语言,使我们能够更自然和更有效地与他们进行交互。
神经网络:根据http://neuralnetworksanddeeplearning.com/,神经网络是一个美丽的生物学启发的编程范例,使计算机能够从观测数据中学习。有人称之为编程范例“美丽”已经很久了。实质上,人造神经网络是由大脑的现实生物学启发的模型。与神经网络密切相关的是深度学习。深度学习,一套强大的神经网络学习技术。
模式识别:当算法在大数据集或不同的数据集中定位复现或规则时,就会发生模式识别。它紧密相连,甚至被认为是机器学习和数据挖掘的代名词。这种可见性可以帮助研究人员发现洞察力或达成否则将被模糊的结论。
RFID:射频识别;一种使用无线非接触式射频电磁场传输数据的传感器。随着物联网革命,RFID标签可以嵌入到每一个可能的“事物”中,以产生需要分析的巨大数据量。欢迎来到数据世界:-)
SaaS:软件即服务使供应商能够托管应用程序并通过互联网使其可用。 SaaS提供商通过云提供服务。
半结构化数据:半结构化数据是指以常规方式未被捕获或格式化的数据,例如与传统数据库字段或常用数据模型相关联的数据。它也不是原始的或完全非结构化的,并且可能包含一些数据表,标签或其他结构元素。图形和表格,XML文档和电子邮件是半结构化数据的示例,它在万维网上非常流行,通常在面向对象的数据库中。
情绪分析:情绪分析涉及捕捉和跟踪消费者在各种交互或文件(包括社交媒体,客户服务代表呼叫,调查等)中表达的意见,情绪或感受。文本分析和自然语言处理是情绪分析过程中的典型活动。目标是确定或评估对公司,产品,服务,人员或事件表达的情绪或态度。
空间分析是指分析空间数据,如地理数据或拓扑数据,以识别和理解分布在地理空间的数据内的模式和规律。
流处理旨在通过“连续”查询对实时和流数据进行操作。随着从社交网络不断流式传输的数据,对流处理和流分析有着明确的需求,可以在这些流中不间断地计算数学或统计分析,以实时处理大量的数据。
智能数据据称是经过算法完成的一些过滤后有用和可操作的数据。
太字节:数字数据相对较大的单位,一兆比特(TB)等于千兆字节。据估计,10太字节可以容纳美国国会图书馆的整个印刷品,而单个结核病可以容纳1,000份百科全书Brittanica。您必须阅读本文以了解有关所有这些术语的更多信息。
可视化 - 通过正确的可视化,原始数据可以投入使用。当然,可视化并不意味着普通的图形或饼图。它们是指可以包含许多数据变量的复杂图形,同时仍然可以理解和可读
大约1000字节,或者是250万亿的DVD。今天的整个数字宇宙是1兆塔,这将每18个月翻一番。您必须阅读本文以了解有关所有这些术语的更多信息。
千兆字节 - 大约1000字节或10亿兆字节。
- 67 次浏览
【数据架构】Netflix 万亿级实时数据基础架构的四个创新阶段
我叫徐振中。我于 2015 年加入 Netflix,担任实时数据基础架构团队的创始工程师,后来领导了流处理引擎团队。我在 2010 年代初对实时数据产生了兴趣,从那时起我就相信还有很多价值有待发掘。
Netflix 是一个很棒的地方,周围有许多了不起的同事。我为参与将共同信念变为现实的旅程中的每个人感到无比自豪。我想花点时间分享一下团队的主要成就:
- 我们在 Netflix 的所有组织中将流数据用例从 0 增加到 2000 多个。
- 我们构建和发展了成功的产品,例如 Keystone、托管 Flink 平台、Mantis 和托管 Kafka 平台。这些产品在数据生态系统的许多方面提供解决方案:包括数据摄取、移动、分析和操作处理以及机器学习用例。
- 我们是业内率先扩展开源 Kafka 和 Flink 部署以在 2017 年左右,每天处理 1 万亿个事件的公司之一,后来到 2021 年又扩展了 20 倍!
几个月前,我离开了 Netflix,在实时 ML 领域追求类似但扩展的愿景。我认为现在是总结我在 Netflix 构建实时数据基础架构的经验的最佳时机。我希望这篇文章能帮助平台工程师开发他们的云原生、自助式流数据平台,并在许多业务功能中扩展用例(不一定来自我们的成功,也许更多来自我们的失败)。我还相信,了解数据平台的构建方式可以帮助平台用户(例如数据科学家和机器学习工程师)充分利用他们的平台。
帖子里有什么
我将分享实时数据基础架构在 Netflix(2015-2021 年)的迭代之旅的四个阶段。
第 1 阶段:从失败的批处理管道中拯救 Netflix 日志 (2015)
在 Netflix 的全球高速增长期间,业务和运营决策比以往任何时候都更依赖于更快的记录数据。 2015 年,基于 Chukwa/Hadoop/Hive 的批处理管道难以扩展。在这个阶段,我们从头开始构建了一个流优先平台来替换失败的管道。
第 2 阶段:Scale 100s 数据移动用例 (2016)
在最初的产品发布后,内部对数据移动的需求稳步上升。我们必须专注于常见的用例。在这个阶段,我们通过构建一个具有简单而强大的构建块设计的自助服务、完全托管的平台来扩展以支持 100 多个用例。
第 3 阶段:支持定制需求并扩展超过 1000 个用例(2017-2019)
随着流处理在 Netflix 中的发展势头,许多团队要求在数据工程、可观察性和机器学习领域具有更低的延迟和更高的处理灵活性。在此阶段,我们构建了新的流处理开发体验以支持自定义用例,并且我们还应对了新的工程和运营挑战。
第 4 阶段:扩展流处理职责——未来的挑战和机遇(2020 年至今)
随着行业数据平台技术的快速演进,出现了许多新的挑战:协调困难、学习曲线陡峭、流到批边界分裂等。在这个阶段,我们探索了流处理发挥更突出的作用在连接技术和提高抽象以使数据平台更易于使用方面。我们面前还有更多的机会。
对于每个阶段,我将回顾不断发展的业务动机、团队的独特挑战、战略赌注以及我们在此过程中发现的用例模式。
致谢
许多人帮助我审阅了这篇文章,如果没有他们的反馈,我永远不会深入研究许多公正的细节。特别感谢 Chip Huyen、Steven Wu、Prashanth Ramdas、Guanhua Jiang、Scott Shi、Goku Mohandas、David Sun、Astasia Myers 和 Matt Willian!
Netflix 实时数据基础架构的四个阶段
第 1 阶段:从失败的批处理管道中拯救 Netflix 日志 (2015)
语境
2015 年,Netflix 已经拥有约 60MM 的订户,并正在积极扩大其国际影响力。我们都知道,迅速扩大平台杠杆将是维持快速增长的用户增长的关键。
旁注:对于那些不熟悉的人,平台团队通过集中管理基础设施来提供杠杆作用,因此产品团队可以专注于业务逻辑。
我们的团队必须弄清楚如何帮助 Netflix 扩展日志记录实践。当时,Netflix 拥有约 500 个微服务,每天在生态系统中产生超过 10PB 的数据。
收集这些数据对 Netflix 有两个主要目的:
- 获得业务分析见解(例如,用户保留、平均会话时长、趋势等)。
- 获得运营洞察力(例如,测量每秒流媒体播放次数以快速轻松地了解 Netflix 系统的运行状况),以便开发人员可以发出警报或执行缓解措施。
您可能会问,为什么我们首先需要将日志从边缘移动到数据仓库?由于数量庞大,对在线事务数据库进行大规模按需分析是不可行的。原因是在线事务处理 (OLTP) 和在线分析处理 (OLAP) 是在不同的假设下构建的——OLTP 是为面向行的访问模式而构建的,而 OLAP 是为面向列的访问模式而构建的。在底层,他们使用不同的数据结构进行优化。
例如,假设我们想知道数亿 Netflix 用户的平均会话长度。假设我们将此按需分析查询放在面向行的 OLTP 系统上。它将导致行级粒度的全表扫描并可能锁定数据库,并且应用程序可能会变得无响应,从而导致不愉快的用户体验。这种类型的分析/报告工作负载在 OLAP 系统上完成要好得多,因此需要以低延迟方式可靠地移动日志。
(Figure: Move data from Edge to Data Warehouse)
到 2015 年,日志记录量已从 2011 年的 450 亿事件/天增加到每天 5000 亿个事件(1PB 的数据摄取)。现有的日志记录基础设施(一个使用 Chukwa、Hadoop 和 Hive 构建的简单批处理管道平台)正在失败 与每周惊人增长的订户数量相比。 据估计,我们有大约六个月的时间来发展流媒体优先的解决方案。 下图显示了从失败的批处理架构到新的基于流的架构的演变。
(Figure: the failing batch pipeline architecture, before migration)
我们决定用 Keystone 替换这个失败的基础设施。
(Figure: the Keystone streaming architecture, after migration)
您可能有的另一个问题是为什么要考虑流优先架构?当时,正确使用流式架构的价值超过了潜在的风险。 Netflix 是一家数据驱动型公司,流媒体架构的直接重要性在于:
- 减少开发者和运营反馈回路。开发人员严重依赖查看日志来做出运营决策。访问更新的按需日志使开发人员能够更早地检测问题,从而提高生产力。
- 更好的产品体验。许多产品功能,例如个性化推荐、搜索等,都可以从更新鲜的数据中受益,从而改善用户体验,从而提高用户留存率、参与度等。
挑战
在构建流媒体平台时,我们必须考虑许多挑战。
- 挑战一:规模大,资源有限。我们有六个月的时间来构建 Keystone 以每天处理 500B 事件,并且我们必须与六个团队成员一起完成它。
- 挑战 2:不成熟的流媒体生态系统。 2015 年,当传输(Apache Kafka)和处理技术(Apache Samza、Apache Flink)都相对新生时,开发和运营流媒体优先的基础设施很困难。很少有科技公司能够以我们需要的规模证明成功的流媒体优先部署,因此我们必须评估技术选项并进行试验。鉴于我们的资源有限,我们无法自己构建所有东西,必须决定构建什么以及押注哪些新生工具。
- 挑战 3:分析和运营关注点不同。
- 分析流处理侧重于正确性和可预测性。例如,将所有用户点击流移入数据仓库需要数据一致性(最少重复或丢失)和延迟的可预测性,延迟通常在分钟范围内。 (Keystone 擅长这个)
- 操作流处理更多地关注成本效益、延迟和可用性。例如,了解整个 Netflix 设备生态系统的健康状态可以从亚秒级到秒级的延迟中受益,并且可以从源头对数据进行采样或分析以节省成本。 (螳螂擅长这个)
- 挑战 4:有状态数据平台的云原生弹性很难。 Netflix 已经在 AWS 云上运行了几年。然而,我们是第一个在容器化云基础设施上安装有状态数据平台的人。引擎盖下的每个数据中心都有数十万台物理机器为云提供动力。在这种规模下,硬件故障是不可避免的。当这些故障意外出现时,系统可能很难跟上可用性和一致性预期。在无限制的低延迟流处理环境中更具挑战性,任何故障恢复都可能导致背压累积。流优先架构的云原生弹性将意味着重大的工程挑战。
(Figure: How does stream processing help with operational and analytical data)
第 1 阶段的流处理模式总结
我包括了一些观察到的用例及其每个创新阶段各自的流处理模式。 因此,您可以了解随着时间的推移而发生的演变。
+-----------------------------------------------------------------+ | Pattern | Product | Example Use Cases | |-----------------------|----------|------------------------------| | Data Routing | Keystone | Logging, Data Movement (MVP) | |-----------------------|----------|------------------------------| | RT Alerts / Dashboard | Mantis | SPS Alert | +-----------------------------------------------------------------+
策略投注
- 赌注 1:在构建 MVP 产品时,为最初的几个客户构建它。在探索最初的产品市场契合度时,很容易分心。我们决定只帮助少数高优先级的大容量内部客户,并担心以后扩大客户群。这一决定不仅使我们能够专注于产品的核心。它还让我们意识到不应该投资什么(例如,我们使用电子表格而不是成熟的控制平面来保存每个管道的客户姓名、电子邮件地址和元数据信息,以促进 MVP 阶段的客户部署)。
- 赌注 2:与技术合作伙伴共同发展,即使不是处于理想的成熟状态,而不是自己重新发明轮子。这样,我们可以共同发展生态系统。我们很早就选择了合作。
- 流媒体合作伙伴:在外部,我们与领导行业流处理工作的合作伙伴合作,例如 LinkedIn(Kafka 和 Samza 团队)、Confluent、Data Artisan(Apache Flink 背后的构建者,后来更名为 Veverica)。这样做使我们能够在利用社区工作的同时为 OSS 做出贡献以满足我们的需求。
- 容器化合作伙伴:2015年,还是容器虚拟化技术的初期。我们需要一个快速部署的策略。在内部,我们与新创建的容器基础设施 Titus 团队合作。 Titus 建立在 Apache Mesos 之上,并通过抽象 API 提供计算资源管理、调度和隔离部署。 Titus 后来在 2020 年初演变为利用 K8S,他们的团队设法透明地迁移了所有工作负载。由于这种合作关系,我们在构建数据平台时不必担心低级计算基础设施。
- 在合作过程中,我们一直保持沟通,分享经验并提供反馈。我们与密切的合作伙伴每两周举行一次同步会议,以调整目标并讨论问题和解决方案。当出现阻塞问题时,合适的人会立即参与进来。
- 赌注 3:将关注点解耦而不是忽略它们。
- 运营和分析用例之间的分离问题。我们分别发展了 Mantis(专注于运营)和 Keystone(专注于分析),但创造了空间来连接这两个系统。
- (Figure: separation of concerns for different stream processing scenarios)
- 生产者和消费者的关注点分开。我们引入了配备标准化有线协议和简单模式管理的生产者/消费者客户端,以帮助解耦生产者和消费者的开发工作流程。后来证明它是数据治理和数据质量控制的一个重要方面。
- 分离的组件职责。我们从面向微服务的单一职责原则开始,将整个基础设施划分为 Messaging(流传输)、Processing(流处理)和控制平面(控制平面在这个阶段只是一个脚本,后来演变成一个成熟的系统)。组件职责的分离使团队能够尽早在界面上保持一致,同时通过同时关注不同的部分来释放团队的生产力。
- 赌注 4:投资于构建一个预期故障并监控所有操作的系统,而不是延迟投资。由于云的弹性、不断变化、故障概率较高的特性,我们需要设计系统来监控、检测和容忍各种故障。故障范围包括网络故障、实例故障、区域故障、集群故障、服务间拥塞和背压、区域灾难故障等。我们在假设故障是恒定的情况下投资构建系统。我们很早就采用了 DevOps 实践:例如针对故障场景的设计、严格的自动化、持续部署、影子测试、自动化监控、警报等。这个 DevOps 基础使我们能够实现一天多次交付的终极工程敏捷性。
(reference: What is Chaos Money in DevOps on Quora)
学习
拥有一个心理安全的失败环境对于任何团队领导变革都是必不可少的。
我们犯了很多错误。我们在产品发布当天惨遭失败,并发生了全公司范围内的事件,导致大量数据丢失。经过调查,事实证明,尽管正确估计了流量增长,但我们构建的庞大的 Kafka 集群(拥有超过 200 个代理)太大并最终达到了其扩展极限。当一个代理死亡时,由于 Kafka(当时)对代理和分区数量的限制,集群无法自行恢复。它最终退化到无法恢复的地步。
以这种规模失败是一次可怕的经历,但由于心理安全的团队环境,我们与所有利益相关者进行了透明的沟通,并将快速的学习转化为永久的解决方案。对于这种特殊情况,我们开发了更细粒度的集群隔离功能(更小的 Kafka 集群 + 隔离的 Zookeeper)来控制爆炸半径。
还有很多其他的失败。当我们挖掘根本原因时,我们意识到我们无法完全预测所有边缘场景,尤其是当我们在托管云上构建时,其中的变化经常超出我们的控制范围,例如实例终止或租户托管,等等。同时,我们的产品被很多人使用,太重要了,不能失败。始终为最坏的情况做好准备已成为一项操作原则。
事件发生后,我们采用了每周一次的 Kafka 集群故障转移演习。每周值班人员都会模拟 Kafka 集群故障。该团队将确保故障转移自动化能够将所有流量迁移到对用户影响最小的健康集群。如果您有兴趣了解有关此练习的更多信息,此视频有更多详细信息。
第 2 阶段:Scale 100s 数据移动用例 (2016)
语境
在交付了最初的 Keystone MVP 并迁移了一些内部客户之后,我们逐渐获得了一些信任,并且消息传到了其他工程团队。流媒体在 Netflix 中获得了发展势头,因为现在可以轻松移动日志以进行分析处理并获得按需运营洞察力。
现在是我们为普通客户扩展的时候了。
(Figure: evolving Keystone architecture diagram, circa 2016. Keystone includes Kafka and Flink engines as its core components. For more technical design details, please refer to blog posts focused on Kafka and Flink)
挑战
- 挑战一:增加运营负担。我们最初为新客户提供白手套协助。然而,随着需求的增长,它很快变得不可持续。我们需要开始发展 MVP 以支持十几个客户。因此,我们需要重新构建一些组件(例如,是时候将电子表格变成适当的数据库支持的控制平面了)。
- 挑战 2:出现多样化的需求。随着我们收到更多客户要求,我们开始看到非常多样化的需求。有两大类:
- 一组更喜欢易于使用的完全托管服务。
- 另一组更喜欢灵活性,需要复杂的计算能力来解决更高级的业务问题,他们可以使用寻呼机,甚至管理一些基础设施。
- 我们不能同时做好这两件事。
- 挑战 3:我们破坏了我们接触到的一切。不开玩笑,由于规模的原因,我们在某些时候破坏了几乎所有的依赖服务。我们曾经破坏过 aws S3。我们在 Kafka 和 Flink 中发现了很多 bug。我们多次破坏了 Titus(托管容器基础设施)并发现了奇怪的 CPU 隔离和网络问题。当我们开始以编程方式管理数百个客户部署时,我们打破了 Spinnaker(持续部署平台)。
- 幸运的是,这些团队也是最好的。他们与我们一起解决了这些问题。这些努力对于成熟整个流媒体生态系统至关重要。
第 2 阶段的流处理模式总结
+-----------------------------------------------------------------+ | Pattern | Product | Example Use Cases | |-----------------------|----------|------------------------------| | Data Routing | Keystone | Logging, Data Movement | | | | (+ At scale) | |-----------------------|----------|------------------------------| | RT Data Sampling/ | Mantis | Cost-effective RT Insights | | Discovery | | | |-----------------------------------------------------------------| | RT Alerts / Dashboard | Mantis, | SPS Alert, | | | Kafka | + Infrastructure Health | | | | Monitoring (Cassandra & | | | | Elasticsearch), | | | | +RT QoE monitoring | +-----------------------------------------------------------------+
策略投注
- 赌注 1:首先关注简单性,而不是向用户暴露基础设施的复杂性。 我们决定首先将重点放在针对一般流用例的高度抽象、完全托管的服务上,原因有二。
- 它使我们能够处理大多数数据移动和简单的流式 ETL(例如,投影、过滤)用例。 为数据路由提供如此简单、高级别的抽象将使所有 Netflix 组织的工程师能够将数据路由用作与其他平台服务结合的“乐高”构建块。
- 它将使我们的用户能够专注于业务逻辑。
- 我们将在以后处理更高级的用例。
- 赌注 2:投资于完全托管的多租户自助服务,而不是继续使用手动白手套支持。 我们必须专注于自动化控制平面和工作负载部署。 客户工作负载需要完全隔离。 我们决定一个客户的工作量不应该以任何方式干扰另一个客户的工作量。
(Figure: Keystone UI. showing a self-serve drag-n-drop experience powered by a fully managed multi-tenant streaming infrastructure)
- 赌注 3:继续投资 DevOps,而不是拖延。我们希望根据需要每天多次发布平台更改。我们还认为,有必要让我们的客户能够随时发送更改。部署应在客户启动几分钟后自动完成并安全地投入生产。
学习
- 学习 1:决定不做什么是困难的,但却是必要的。虽然满足客户要求很重要,但有些可能会分散注意力。优先级是第一步,但有意识地决定和沟通要削减的内容更为关键。说不很难。但请注意,说不是暂时的,说是是永久的。
- 学习 2:注意缩放速度。在最初的产品与市场契合得到验证之后,这是一个激动人心的时刻。然而,过快扩展可能会使团队分心于多个方向,留下大量技术债务,并破坏客户信任。扩展太慢会使团队失去动力,客户需求无法满足太久,也会破坏他们的信任。这是一个微妙的平衡,但这里有一些你可以注意的信号:
- 软件质量。部署回滚频率是否改变?合作伙伴团队多久阻止一次团队?现在测试失败的频率更高了吗?由于任何系统瓶颈,事件多久发生一次?
- 客户情绪。客户支持请求的增加是否与用例数量成线性关系? SLO 违规趋势。客户是否在新功能公告中表现出兴奋?当客户提出“紧急”问题时,他们考虑了哪些替代方案?
- 运营开销。团队的运营与开发时间比例是否发生变化? RCA 与事故的比率会改变吗?团队是否因运营劳累而筋疲力尽?团队的创新频率是否发生变化(例如,博客文章、会议演讲)?
- 学习 3:教育您的用户并耐心纠正误解。围绕数据质量(如事件丢失或重复)或处理语义(如故障场景下的正确性保证)存在许多流处理误解。许多这些误解来自流处理不成熟的旧时代,但已经发展了很多。对你的用户要有耐心,用数据和故事教育他们!
第 3 阶段:支持定制需求并扩展超过 1000 个用例(2017-2019)
语境
在最初推出 Keystone 产品一年后,所有组织的用例数量从 2015 年的不到十几个迅速增加到 2017 年的几百个。此时我们已经建立了坚实的运营基础:客户在待命期间很少收到通知,所有基础设施问题都由平台团队密切监控和处理。我们建立了一个强大的交付平台,帮助我们的客户在几分钟后将变更引入生产。
Keystone 产品非常擅长它最初的设计目标:一个易于使用且几乎可以无限扩展的流数据路由平台。然而,很明显,流处理的全部潜力远未实现。为了满足自定义用例,我们不断发现对复杂处理能力进行更精细控制的新需求,例如流连接、窗口化等。
同时,Netflix 拥有独特的自由和责任文化,每个团队都有权做出自己的技术决策。这种文化使每个团队甚至可以投资定制解决方案。作为一个中央平台团队,我们注意到了这种增长。如果我们没有办法提供保险,这将意味着公司的长期成本很高。
是时候让团队扩大其范围了。我们再次面临一些新的挑战。
挑战
- 挑战 1:自定义用例需要不同的开发人员和运营经验。
- 我先举两个自定义流处理用例的例子。
- 计算推荐的流式基本事实。为了让 Netflix 推荐算法提供最佳体验,有必要使用最新数据训练模型。训练模型的输入之一是标签数据集。标签是先前的个性化预测是否准确的直接真实指标。如果用户决定观看一部电影以获得推荐,我们就有了一个肯定的标签。你可以猜到,我们越快得到这个标签数据集,整个 ML 反馈循环就越快。要计算标签,我们需要将展示流和用户点击流连接在一起。但是,用户点击活动通常会延迟到达。例如,用户有时会花几分钟来决定,或者干脆让他们的设备开机而不看几个小时。该用例要求流管道在所有相关信息到达后立即发出标签,但仍能容忍迟到的信息。
- 计算推荐的比例。 Netflix 提供个性化推荐以优化用户体验。其中之一是选择最佳个性化艺术作品(以及展示它们的最佳位置)的算法,以优化用户参与度。在底层,流处理管道通过在某个自定义窗口上将播放数据流与印象流连接起来,以近乎实时的方式计算该提取分数指标。由于 Netflix 数亿用户群的规模,流媒体作业需要不断检查 1-10 TB 之间的内部状态。
-
- (Figure: A/B test to select the best artwork to personalize to the user,
- 参考:通过 A/B 测试为视频选择最佳艺术品 |由 Netflix 提供)
- 这些用例涉及更高级的流处理功能,例如复杂的事件/处理时间和窗口语义、允许的延迟、大状态检查点管理。他们还需要围绕可观察性、故障排除和恢复提供更多运营支持。全新的开发人员体验是必要的,包括更灵活的编程接口和操作能力,例如自定义可观察性堆栈、回填能力以及管理 10 TB 本地状态的适当基础架构。我们在 Keystone 中没有这些,我们需要建立一个新的产品入口点,但要尽量减少多余的投资。
- 挑战 2:在灵活性和简单性之间取得平衡。对于所有新的自定义用例,我们必须找出适当的控制暴露水平。我们可以在更具有挑战性的操作的权衡下一路公开最低级别的 API(因为我们永远无法完全预测用户将如何使用引擎)。或者我们可以选择中途(例如,暴露有限的功能),冒着客户不满意的风险。
- 挑战 3:操作复杂性增加。支持自定义用例需要我们增加平台的自由度。因此,我们需要在许多复杂场景中提高操作可观察性。同时,随着平台与许多其他数据产品的集成,我们系统的接触点增加,需要与其他团队进行运营协调,以更好地为我们的集体客户服务。
- 挑战 4:中央平台与本地平台。我们团队的职责是提供一个集中的流处理平台。但是由于之前专注于简单性的策略,一些团队已经使用不受支持的技术在本地流处理平台上进行了投资,例如火花流。我们必须说服他们回到铺好的道路上,因为他们可能会失去平台的影响力,并在多余的投资上浪费资源。现在是我们扩展到自定义用例的正确时机。
第 3 阶段的流处理模式总结
+-----------------------------------------------------------------+ | Pattern | Product | Example Use Cases | |-----------------------|----------|------------------------------| | Stream-to-stream Joins| Flink | Take-fraction computation, | | (ETL) | | Recsys label computation | |-----------------------|----------|------------------------------| | Stream-to-table joins | Flink | Side input: join streams with| | (ETL) | | slow-moving Iceberg table | |-----------------------|----------|------------------------------| | Streaming Sessionizat-| Flink | Personalization Sessionizat- | | ion (ETL) | | ion, Metrics sessionization | |-----------------------|----------|------------------------------| | RT Observability | Mantis | Distributed tracing, | | | | Chaos EXPER monitoring, | | | | Application monitoring | |-----------------------|----------|------------------------------| | RT Anomaly / Fraud | Mantis, | Contextual alert, | | Detection | Flink | PII detection, | | | | Fraudulent login prevention | |-----------------------|----------|------------------------------| | RT DevOps Decision | Mantis | Autoscaling, | | Tool | | Streaming ACA & A/B tests, | | | | CDN placement optimization | |-----------------------|----------|------------------------------| | Event Sourced | Flink | Content Delivery Network | | Materialized View | | snapshotting | +-----------------------+----------+------------------------------+
策略投注
- 赌注 1:构建新产品入口点但重构现有架构,而不是孤立地构建新产品。 在分析处理方面,我们决定从原始架构中衍生出一个新平台,以利用 Apache Flink 展示流处理的全部功能。 我们将从头开始创建一个新的内部客户群,但我们也认为现在是重构架构以最小化冗余投资(在 Keystone 和 Flink 平台之间)的正确时机。 在这个新架构中,较低的 Flink 平台同时支持 Keystone 和自定义用例。
- (Figure: Architecture splitting Flink Platform as a separate product entry point)
- 赌注 2:从流式 ETL 和可观察性用例开始,而不是一次性处理所有自定义用例。有很多机会,但我们决定专注于分析方面的流式 ETL 用例和操作方面的实时可观察性用例。由于其复杂性和规模,这些用例最具挑战性。为了展示流处理的全部力量,我们首先解决最困难的问题并从中学习是有意义的。
- 赌注3:最初与客户分担运营责任,随着时间的推移逐渐共同创新以减轻负担。我们很幸运,我们的早期采用者能够自给自足,而且每当客户遇到困难时,我们也会提供白手套支持模式。我们逐渐扩大了运营投资,例如自动扩展、托管部署、智能警报、回填解决方案等。
学习
- 学习 1:支持新的自定义用例的新产品入口点是必要的演进步骤。这也是一个重新架构/重构并融入现有产品生态系统的机会。不要被引诱去孤立地构建一个新系统。避免第二系统效应。
- 学习 2:简单性吸引了 80% 的用例。灵活性有助于更大的用例。回顾过去,这些是过去几年对实际客户群的观察。我想在这里向读者传达的一点是,在支持大多数用例或影响更大的用例之间进行优先级排序,都取决于具体情况。这个论点可以双向进行,但您应该阐明适合您的业务场景的推理。
- 简单性和灵活性不是光谱的两个极端。这是一个封闭的创新反馈循环。灵活性的力量将推动与一小部分客户进行新的联合创新。一开始,这些创新可能会更昂贵,但在被证明之后,价值最终可能会变成商品并回到简化的体验。由于这些新价值有助于不断增长的客户,一小部分新用户将再次要求灵活性的力量。
- 学习 3:善待你的早期采用者。他们是最忠实的客户,会免费为您做营销。感谢我们早期采用者的认可,我们的用例在此阶段激增至数千个。
- 学习 4:当事情破裂时,不要惊慌。相信你周围的所有人。如果您已经有一个支持该产品的社区,则可以加分。我记得有一次我们经历了整个平台的缓慢退化。每天,我们都会收到大量的页面,而我们在两周内都无法找出根本原因。这太可怕了,团队很痛苦,客户也很痛苦。但是该团队能够跨越团队边界一起工作,让具有正确专业知识的人参与进来,使用数据对症状进行逻辑推理。最终,我们在 Linux 内核中发现了一个错误,该错误导致特定于流式工作负载的缓慢内存泄漏。我们必须信任所有相关人员,有时即使我们并不具备所有专业知识!
第 4 阶段:扩展流处理职责——未来的挑战和机遇(2020 年至今)
(Figure: how stream processing fits in Netflix — 2021)
语境
随着流处理用例扩展到 Netflix 中的所有组织,我们发现了新模式,并享受了早期的成功。但现在不是自满的时候。
作为一家企业,Netflix 继续探索新领域,并在内容制作工作室以及最近在游戏方面进行了大量投资。出现了一系列新挑战,我们开始着手解决这些有趣的问题空间。
挑战
- 挑战一:多样化的数据技术使协调变得困难。由于团队被授权,Netflix 的许多团队都在使用各种数据技术。比如事务端:有Cassandra、MySQL、Postgres、CockroachDB、分布式缓存等;分析端:有Hive、Iceberg、Presto、Spark、Pig、Druid、Elasticsearch等。相同的数据通常存储在 Netflix 数据生态系统内的不同数据存储中。
- 有很多选择可供选择,将技术放在不同的桶中是人类的天性。批处理与流式处理。事务性存储与分析性存储。在线处理与离线处理。这些都是数据世界中经常争论的话题。重叠的划分边界通常会给最终用户增加更多的困惑。
- 如今,跨技术边界协调和处理数据极具挑战性。边界难以通过划分边界来推动。
- 挑战 2:更陡峭的学习曲线。随着可用数据工具数量的不断增加和专业化程度的不断加深,用户学习和决定哪些技术适合特定用例是一项挑战。
- 挑战 3:ML 实践没有利用数据平台的全部功能。前面提到的所有挑战都会对 ML 实践造成影响。数据科学家的反馈循环很长,数据工程师的生产力受到影响,产品工程师在共享有价值的数据时面临挑战。最终,许多企业失去了适应瞬息万变的市场的机会。
- 挑战 4:中央平台模型的规模限制。由于中央数据平台以超线性的速度扩展用例,单点联系支持是不可持续的。现在是评估中央平台支持本地中央平台以增加杠杆作用的模型的正确时机(这意味着我们将优先支持构建在我们平台之上的本地平台)。
机会
我将在这部分相对简短,并在以后的博客文章中扩展细节。
- 使用流连接世界。对于流处理而言,除了低延迟处理的优势外,它在现代数据平台中越来越显示出更为关键的优势:连接各种技术并实现流畅的数据交换。变更数据捕获 (CDC)、流式物化视图和数据网格概念等技术越来越受欢迎。最后,Martin Kleppmann 在 2015 年提出的“彻底颠覆数据库”的愿景开始实现其价值。
- 通过结合最好的简单性和灵活性来提高抽象性。了解各种数据技术的深层内部原理很有价值,但并不是每个人都需要这样做。随着云优先的数据基础设施正在成为商品,这种思路尤其正确。适当提升数据基础设施抽象化成为让更广泛的受众轻松访问所有高级功能的直接机会。流式 SQL 等技术将降低准入门槛,但这仅仅是开始。数据平台还应提高对最终用户不可见的划分边界(例如,流式与批处理)的抽象。
(Figure: the sweet spot between simplicity and flexibility)
- 机器学习需要来自现代数据平台的更多爱。 在所有开发人员角色中,ML 人员可以说是对业务影响最大和服务最不足的群体。 所有 ML 平台都依赖于数据存储和处理。 因此,Data Platform 有很多机会向 ML 世界伸出援助之手:例如数据质量、可靠性和可扩展性、开发到产品的反馈循环、实时可观察性、整体效率等。
第 4 阶段的流处理模式总结
+-----------------------------------------------------------------+ | Pattern | Product | Example Use Cases | |-----------------------|----------|------------------------------| | Streaming Backfill / | Flink | Pipeline Failure mitigation, | | Restatement | | Avoid cold start | |-----------------------|----------|------------------------------| | Data Quality Control | Keystone,| Schema evolution management, | | | Flink | Data Quality SLA, | | | | Cost reduction via Avro | | | | compression | |-----------------------|----------|------------------------------| | Source/Sink Agnostic | Keystone,| Delta, Data Mesh, | | Data Synchronization | Flink | Operational reporting, | | | | Notification, | | | | Search Indexing Pipeline | |-----------------------|----------|------------------------------| | Near-real-time (NRT) | Flink | Customer service recommend- | | Inference | | ation, Intent-based in- | | | | session adaptations | |-----------------------|----------|------------------------------| | Streaming SQL | Flink | Dynamic feature Engineering | |-----------------------|----------|------------------------------| | Intelligent Operation | 4 | Auto-diagnosis & remediation | +-----------------------+----------+------------------------------+
下一个前沿是什么
谢谢你走到这一步。这篇博文描述了在 Netflix 构建流处理基础设施的高级迭代之旅。我很想听听您对有趣之处的反馈,以便我可以跟进未来的博客文章。
根据设计,我在这篇文章中省略了许多技术细节。但如果您有兴趣了解更多信息,请参阅附录部分,了解 Netflix 中所有流处理创新的完整时间线视图。
我对数据基础设施的未来感到非常兴奋,尤其是支持更好的机器学习体验。我相信这是我们要大胆前行的下一个前沿!如果你感兴趣,我强烈推荐我的好朋友兼同事 Chip 的优秀读物“实时机器学习:挑战和解决方案”。
我也很高兴地宣布,我将与 Chip Huyen 一起开始新的旅程,在流媒体优先的机器学习平台上工作。我们还很早,我们正在寻找一位创始基础设施工程师,共同塑造未来!如果您有兴趣,我们很乐意收到您的来信!
如果这篇博文引起您的共鸣,请联系我们。我想连接!
附录
Netflix 中的流处理模式
+-----------------------------------------------------------------+ | Pattern | Phase | Example Use Cases | |-----------------------|----------|------------------------------| | Data Routing | 1 | Logging, Data Movement | |-----------------------|----------|------------------------------| | RT Alerts / Dashboard | 1, 2 | SPS Alert, | | | | Infrastructure Health | | | | Monitoring (Cassandra & | | | | Elasticsearch), | | | | RT QoE monitoring | +-----------------------------------------------------------------+ | RT Data Sampling/ | 2 | Cost-effective RT Insights | | Discovery | | | |-----------------------------------------------------------------| | Stream-to-stream Joins| 3 | Take-fraction computation, | | (ETL) | | Recsys label computation | |-----------------------|----------|------------------------------| | Stream-to-table joins | 3 | Side input: join stream with | | (ETL) | | slow-moving Iceberg table | |-----------------------|----------|------------------------------| | Streaming Sessionizat-| 3 | Personalization Sessionizat- | | ion (ETL) | | ion, Metrics sessionization | |-----------------------|----------|------------------------------| | RT Observability | 3 | Distributed tracing, | | | | Chaos EXPER monitoring, | | | | Application monitoring | |-----------------------|----------|------------------------------| | RT Anomaly / Fraud | 3 | Contextual alert, | | Detection | | PII detection, | | | | Fraudulent login prevention | |-----------------------|----------|------------------------------| | RT DevOps Decision | 3 | Autoscaling, | | Tool | | Streaming ACA & A/B tests, | | | | CDN placement optimization | |-----------------------|----------|------------------------------| | Event Sourced | 3 | Content Delivery Network | | Materialized View | | snapshotting | | Streaming Backfill / | | Pipeline Failure mitigation, | | Restatement | | Avoid cold start | |-----------------------|----------|------------------------------| | Data Quality Control | 4 | Schema evolution management, | | | | Data Quality SLA, | | | | Cost reduction via Avro | | | | compression | |-----------------------|----------|------------------------------| | Source/Sink Agnostic | 4 | Delta, Data Mesh, | | Data Synchronization | | Operational reporting, | | | | Notification, | | | | Search Indexing Pipeline | |-----------------------|----------|------------------------------| | Near-real-time (NRT) | 4 | Customer service recommend- | | Inference | | ation, Intent-based in- | | | | session adaptations | |-----------------------|----------|------------------------------| | Streaming SQL | 4 | Dynamic feature Engineering | |-----------------------|----------|------------------------------| | Intelligent Operation | 4 | Auto-diagnosis & remediation | +-----------------------+----------+------------------------------+
References
Indexed in chronological order …
- [2015|Use Case] What’s trending on Netflix? improving our recommender systems
- [2015|Use Case] SPS: the Pulse of Netflix Streaming | by Netflix
- [2016|Platform] Evolution of the Netflix Data Pipeline | by Netflix
- [2016|Platform] Kafka Inside Keystone Pipeline
- [2016|Platform] Stream-processing with Mantis… | by Netflix
- [2017|Platform] Running a Massively Parallel Self serve Distributed Data System At Scale — Zhenzhong Xu
- [2017|Platform] FlinkForward: Stream Processing with Flink at Netflix — Monal Daxini
- [2017| Platform] Custom, Complex Windows at Scale using Apache Flink — Matt Zimmer (Netflix)
- [2017|Use Case] Streaming for Personalization Datasets at Netflix
- [2017|Use Case] ChAP: Chaos Automation Platform | by Netflix
- [2018|Platform] Keystone Real-time Stream Processing Platform | by Netflix
- [2018|Use Case] “Scalable Anomaly Detection (with Zero Machine Learning)” by Arthur Gonigberg
- [2018|Use Case] Migrating Batch ETL to Stream Processing: A Netflix Case Study with Kafka and Flink
- [2018|Platform] Building Stream Processing as a Service (SPaaS) — Steven Wu
- [2018|Platform] Cloud-Native and Scalable Kafka Architecture
- [2019|Platform] Scaling Flink in Cloud — Steven Wu
- [2019|Use Case] Massive Scale Data Processing at Netflix using Flink — Snehal Nagmote & Pallavi Phadnis
- [2019|Use Case] Cost-Effective, Realtime Operational Insights Into Production Systems
- [2019|Use Case] Real-time Processing with Flink for Machine Learning at Netflix — Elliot Chow
- [2019|Platform] Open Sourcing Mantis: A Platform For Building Cost-Effective, Realtime, Operations-Focused Applications | by Netflix
- [2019|Platform] Netflix Data Mesh: Composable Data Processing — Justin Cunningham
- [2019|Platform] Netflix: Evolving Keystone to an Open Collaborative Real-time ETL Platform — Alibaba Cloud Community
- [2019|Use Case] Delta: A Data Synchronization and Enrichment Platform | by Netflix
- [2019|Use Case] DBLog: A Generic Change-Data-Capture Framework | by Netflix
- [2020|Platform] Autoscaling Flink at Netflix — Timothy Farkas
- [2020|Use Case] How Netflix Uses Kafka for Distributed Streaming — by Confluent
- [2020|Use Case] Building metric platform using Flink for massive scale at Netflix — Abhay Amin
- [2020|Use Case] Taming Large State: Lessons from Building Stream Processing Joins for Datasets for Personalization
- [2020|Use Case] Building Netflix’s Distributed Tracing Infrastructure | by Netflix
- [2020|Use Case] Telltale: Netflix Application Monitoring Simplified | by Netflix
- [2020|Use Case] How Netflix uses Druid for Real-time Insights to Ensure a High-Quality Experience
- [2021|Platform] Data Movement in Netflix Studio via Data Mesh | by Netflix
- [2021|Platform] Backfill Flink Data Pipelines with Iceberg Connector
- [2022|Platform] Auto-Diagnosis and Remediation in Netflix Data Platform | by Netflix
原文:https://zhenzhongxu.com/the-four-innovation-phases-of-netflixs-trillion…
- 167 次浏览