日均万亿事件:Netflix怎么作实时流处理?

在这篇文章中,咱们将讨论流式处理所面临的挑战、Keystone 的设计原则、思惟模式、架构总览、咱们的愿景以及 Keystone 为 Netflix 所带来的核心价值。后端

单个流式做业:网络

图片

经过平台管理这些做业:架构

图片

流式处理的挑战1. 伸缩app

Netflix 为来自 190 多个国家的 1.3 亿用户提供服务。流式处理平台天天处理数万亿个事件和 PB 级别的数据,以支持平常的业务需求。随着用户数量的持续增加,整个平台须要进行伸缩。框架

2. 多样化的用例机器学习

Keystone 路由服务:这个服务负责根据用户的配置将事件路由到托管接收器上。每一个传递线路都经过并行流式处理做业来实现。用户能够定义可选的过滤器或投影聚合。事件最终被传递给存储接收器,便于后续的批处理或流式处理(这些处理实现了至少一次语义)。用户能够在延迟和重复处理之间作出权衡。分布式

流式处理即服务:SPaaS 平台只在生产环境中运行了大约一年时间,但咱们已经遇到了各类各样的需求。如下是一些常见的问题和权衡。ide

  • 做业状态:从彻底无状态并行处理到须要数十 TB 本地状态存储的做业。微服务

  • 做业复杂性:从将全部 operator 连接在一块儿的并行做业,到具备多个 shuffle 阶段和复杂会话逻辑的复杂做业 DAG。工具

  • 窗口 / 会话:窗口大小从几秒钟(即捕获事务的开始 / 结束事件)到数小时的自定义会话窗口。

  • 流量模式:不一样用例的流量模式存在很大差别。它们多是突发的,也可能保持在 GB/ 秒级别不变。

  • 故障恢复:有些用例须要秒级的低故障恢复延迟,看成业持有很大的状态并涉及 shuffle 时,就变得至关具备挑战性。

  • 回填(backfill)和回放(rewind):某些做业须要从批处理数据源重放数据或从先前的检查点回放数据。

  • 资源争用:做业可能会在任何物理资源上产生瓶颈:CPU、网络带宽或内存等。用户依赖平台提供的用于进行性能调整的看法和指导。

  • 重复与延迟:应用程序在重复与延迟方面可能有不一样的权衡偏好。

  • 事件排序:大多数用例不依赖严格的排序,但有些确实会依赖排序。

  • 传递和处理语义:某些用例容许管道中丢失一些事件,而其余用例可能要求更高的持久性保证。某些有状态的流式做业指望具有刚好一次处理保证,计算状态须要始终保持一致。

  • 用户受众:咱们的用户群十分普遍,从技术娴熟的分布式系统工程师到业务分析师,有些团队选择基于咱们的平台产品构建特定领域的平台服务。

3. 多租户

Keystone 支持数千个流式做业,从数据传输、数据分析,一直到支持微服务架构模式。由于流式做业的多样性,为了向每一个用户提供有意义的服务级别保证,基础设施须要提供运行时和运营隔离,同时还要最小化共享平台开销。

4. 弹性

尽管大多数流都具备固定的流量模式,咱们仍然须要让系统可以应对突发状况(流行的节目上线或意外故障引发的流量爆发),并且可以自动适应并对这些状况作出响应。

5. 云原生弹性

Netflix 的微服务彻底是在云端运行的。云具备弹性、持续变化、更高的故障率等特色,所以咱们须要让系统可以监控、检测和容忍故障,包括网络不稳定、实例故障、区域故障、集群故障、服务间拥塞或回压、区域灾难故障等。

6. 运营开销

咱们的平台目前为数千个路由做业和流式应用程序提供服务。若是依靠平台团队手动管理全部流,成本会很高。所以,应该由用户负责声明做业的生命周期,同时基础设施应该尽量自动化。

7. 敏捷性

咱们但愿可以进行快速的开发和部署,天天能够进行屡次部署。咱们也但愿可以保持用户使用平台的敏捷性。

平台思惟与设计原则1. 可实施性

这个平台的主要目标之一是让其余团队可以专一于业务逻辑,让流式处理做业的实验、实现和运营变得更容易。经过平台将“难啃的硬骨头”抽离出来,消除用户的复杂性,这将极大提高团队的敏捷性并促进产品的创新。

咱们努力让用户可以:

  • 快速发现数据和开展试验,经过数据驱动的创新来推进产品的发展;

  • 快速的流式处理解决方案原型设计;

  • 充满信心地进行服务的生产和运营;

  • 深刻了解性能、成本、做业生命周期状态等,以便可以作出明智的决策;

  • 进行自助服务。

2. 构建块

为了可以让用户专一于业务逻辑而没必要担忧分布式系统的复杂性或某些预先存在的解决方案的通常性细节,咱们须要为用户提供一组能够轻松接入到流式做业 DAG 的可组合 operator。

此外,流式做业自己也能够成为其余下游服务的构建块。咱们与一些合做伙伴团队合做,构建“托管数据集”和其余特定领域的平台。

咱们还努力经过利用其余构建模块(如容器运行时服务、平台动态配置、通用注入框架等)与 Netflix 软件生态系统深度集成。这不只有助于咱们基于其余现有解决方案构建出新的服务,还让咱们的用户更加熟悉开发和运营环境。

3. 可调整的权衡

任何一个复杂的分布式系统自己都有必定的局限性,所以在设计这种系统时须要考虑到各类权衡,如延迟与重复、一致性与可用性、严格排序与随机排序等。某些用例还可能涉及各类权衡组合,因此平台必须提供调整入口,为我的用户提供定制的可能性,让他们能够声明对系统的需求。

4. 故障是头等公民

在大规模分布式系统中,故障是一种常态,在云环境中就更是如此。任何设计合理的云原生系统都应该将故障视为一等公民。

如下是影响咱们设计的一些重要方面:

  • 假设网络是不可靠的;

  • 信任底层运行时基础设施,但须要自动修复能力;

  • 实现多租户的做业级别隔离;

  • 出现故障时减小影响范围;

  • 出现组件状态漂移或发生灾难故障时可以进行自动调节;

  • 正确处理和传播回压。

5. 关注点分离

在用户和平台之间:用户应该可以经过平台 UI 或 API 声明“目标状态”。目标状态被保存在单个事实源当中,应该由平台做业流程负责处理从“当前状态”到“目标状态”的变化。

在控制平面和数据平面之间:控制平面负责做业流程编排和协调,数据平面负担处理繁重的任务,以确保一切处在目标状态内。

在不一样的子组件之间:每一个组件负责本身的做业和状态。每一个组件的生命周期都是独立的。

运行时基础设施:流式处理做业部署在开源的 Netflix Titus Container 运行时服务上,该服务提供配置、调度、资源级别的隔离(CPU、网络、内存)、高级网络等。

咱们的方法

考虑到上述的挑战和设计原则,咱们几乎完成了一个声明式的调和架构,用以实现自助服务平台。这个架构容许用户经过 UI 声明所需的做业属性,平台将编排和协调子服务,以确保尽快达到目标状态。

如下部分介绍了平台的架构和平台设计的各个方面。

1. 声明式调和

声明式调和协议被用在整个架构栈上,从控制平面到数据平面。从逻辑上讲,利用这个协议的目的是将用户声明的目标状态的单个副本保存为持久的事实来源,其余服务基于这些事实来源进行调和。当出现状态冲突时,无论是临时故障致使仍是正常的用户触发动做,这些事实来源都应该被视为权威,其余全部版本的状态应该被视为当前视图。整个系统最终须要将事实来源做为调和目标。

事实来源存储是一种持久的存储,用于保存全部须要的状态信息。咱们目前使用的是 AWS RDS,它是整个系统的惟一事实来源。例如,若是 Kafka 集群由于 ZooKeeper 状态损坏而出现故障,咱们能够根据事实来源从新建立整个集群。相同的原则也适用于流式处理层,这使得持续自我修复和自动化运营成为可能。

这个协议的另外一个好处是操做的幂等性。这意味着从用户传给控制平面再传给做业集群的控制指令和不可避免的故障条件不会形成长时间的对立面效应。这些服务最终会自行调和,同时也带来了运营的敏捷性。

2. 部署编排

控制平面经过与 Netflix 内部的持续部署引擎 Spinnaker 发生交互来编排做业流程。Spinnaker 对 Titus 容器运行时集成进行了抽象,控制平面能够以不一样的权衡方式来协调部署。

Flink 集群由做业管理器和任务管理器组成。咱们经过为每一个做业建立独立的 Flink 集群来实现完整的做业隔离。惟一的共享服务是用于达成共识协调的 ZooKeeper 和用于保存检查点状态的 S3 后端。

在从新部署期间,无状态应用程序能够在延迟或重复处理之间作出权衡。对于有状态应用程序,用户能够选择从检查点 / 保存点恢复或重新状态从新开始。

3. 自助工具

对于路由做业:用户能够经过自助服务请求生成事件(可声明过滤器或投影聚合),而后将事件路由到托管接收器(如 Elasticsearch、Hive)或者让下游实例进行实时的消费。自助服务 UI 从用户那里获取输入,并将其转换为最终指望的系统状态。咱们所以能够构建一个可以实现目标状态的编排层,还能够抽离出用户可能不关心的某些信息(例如要发送到哪一个 Kafka 集群或某些容器的配置),并在必要的时候提供灵活性。

对于自定义 SPaaS 做业,咱们提供了命令行工具用于生成 Flink 代码模板存储库和 CI 集成等。

图片

在用户签入代码后,CI 自动化流程将开始构建 Docker 镜像,并经过平台后端注册镜像,用户能够执行部署和其余操做。

图片

4. 流式处理引擎

咱们目前正在基于 Apache Flink 为 Keystone 的分析用例构建一个生态系统。咱们计划集成和扩展 Mantis 流式处理引擎。

5. 链接器、托管 operator 和应用程序抽象

为了帮助咱们的用户提升开发敏捷性和创新,咱们提供了全方位的抽象,包括托管链接器、让用户能够接入处理 DAG 的 operator,以及与各类平台服务的集成。

咱们为 Kafka、Elasticsearch、Hive 等提供了托管链接器。这些链接器抽象出了自定义连线格式、序列化、批处理 / 限定行为以及接入处理 DAG 的便利性。咱们还提供动态数据源 / 接收器 operator,用户能够在不一样的数据源或接收器之间切换,而无需从新构建。

图片

其余托管的 operator 还包括过滤器、投影聚合和易于理解的数据卫生自定义 DSL。咱们将继续与用户合做开发更多的 operator,并让更多团队可使用这些 operator。

6. 配置和不可变部署

多租户配置管理有必定的挑战性。咱们但愿提供动态且易于管理的配置体验(用户无需从新提交和构建代码)。

托管的配置和用户定义配置都保存在应用程序的属性文件中,这些配置能够被环境变量覆盖,也能够经过自助 UI 覆盖这些属性。这种方法适用于咱们的调和架构,用户经过 UI 声明想要的配置并部署编排,确保运行时的最终一致性。

7. 自我恢复

在分布式系统中,故障是不可避免的。咱们彻底相信故障会在任什么时候候发生,因此咱们的系统被设计成具备自我恢复能力,这样就没必要在半夜醒来处理事故。

从架构上看,平台组件服务被隔离出来,以便在发生故障时减小影响范围。调和架构还经过持续调和来确保系统级别的自我恢复能力。

单个做业遵循相同的隔离模式,以减小故障影响。可是,为了处理故障并从故障中恢复,每一个托管流式做业都配有健康监视器。健康监视器是运行在 Flink 集群中的内部组件,负责检测故障状况并执行自我修复:

  • 集群任务管理器漂移:当 Flink 容器资源视图与容器运行时视图不匹配时就会出现漂移,经过主动终止受影响的容器,能够自动纠正漂移。

  • 暂停做业管理器首领:若是未能选举出首领,集群就会进入无脑状态,此时须要对做业管理器执行纠正措施。

  • 不稳定的容器资源:若是某个任务管理器出现不稳定的模式(如按期重启 / 故障),它将被替换。

  • 网络分区:若是容器遇到网络链接问题,它将自动终止。

8. 回填和回放

由于故障是不可避免的,因此有时候用户可能须要回填或回放处理做业。

对于备份到数据仓库中的源数据,咱们在平台中构建了相应的功能,用来动态切换数据源而无需修改和从新构建代码。这种方法有必定的局限性,建议将它应用在无状态做业上。

或者,用户能够选择回到以前自动保存的检查点开始从新处理。

9. 监控和警报

全部单个的流式做业都配有个性化的监控和警报仪表盘。这有助于平台 / 基础设施团队和应用程序团队监控和诊断问题。

10. 可靠性和测试

随着平台和底层基础设施服务不断创新,提供愈来愈多的新功能和改进,快速采用这些变化的压力是自下而上的(架构层面)。

随着应用程序的开发和发布,可靠性的压力是自上而下的。

因而,压力在中间相遇了。为了得到信任,咱们须要让平台和用户可以有效地测试整个技术栈。

咱们坚持为全部用户进行单元测试、集成测试、金丝雀运营。咱们正在这方面取得进展,但仍然有不少问题须要解决。

如今和将来

在过去的一年半中,Keystone 流式处理平台天天能够处理万亿个事件。咱们的合做伙伴团队已经用它构建各类流式分析应用。此外,咱们也看到了一些创建在 Keystone 之上的更高级别的平台。

可是,咱们的故事并未就此结束。要实现咱们的平台愿景,还有很长的路要走。如下是咱们正在研究的一些有趣的事项:

  • 模式(schema)

  • 让平台交互变得更灵活的服务层

  • 提供流式 SQL 和其余更高级别的抽象,为不一样的用户提供价值

  • 分析和机器学习用例

  • 微服务事件溯源架构模式

相关文章
相关标签/搜索