手记

Keystone实时流处理平台

Keystone流处理平台是Netflix的数据骨干,是实现工程数据驱动文化的重要基础架构。 虽然Keystone专注于数据分析,但值得一提的是,还有另一个Netflix自主研发的反应流处理平台Mantis,该平台针对运营用例。 我们将在以后的文章中讨论Mantis及其在Netflix生态系统中的重要作用。

如今,Keystone平台提供两种生产服务:

数据管道:启用了流传输的路由服务和启用了Kafka的消息服务,共同负责几乎实时地生成,收集,处理,聚合和移动所有微服务事件。流处理即服务(SPaaS):使用户能够构建和运行自定义的托管流处理应用程序,从而使他们能够专注于业务应用程序逻辑,而平台则提供了规模缩放,运营和领域专业知识。

在本文中,我们将探讨一些挑战,设计原则,平台思维方式,高级架构,最后是平台为Netflix提供的愿景和核心价值。

单个流作业的剖析:

…并且平台管理以下工作:

挑战

1.规模

Netflix为来自190多个国家的1.3亿订户提供服务。 流平台每天处理数万亿个事件和数PB的数据,以支持日常业务需求。 随着用户的持续增长,该平台希望得到扩展。

2.各种用例

Keystone路由服务:此服务负责根据用户配置将任何事件路由到托管接收器。 每个传递路径都是通过一个令人尴尬的并行流处理作业来实现的。 用户可以定义可选的过滤器和/或投影聚合。 事件最终被传递到存储接收器,以使用至少一次的传递语义进行进一步的批处理/流处理。 用户可以选择不同的延迟和复制的权衡。

流处理即服务:SPaaS平台仅投入生产大约一年,但我们已经看到了巨大的工程意向,以及各种各样的需求。 以下是一些常见要求和折衷。

作业状态:从完整的无状态并行处理到需要10 TB大型本地状态的作业。作业复杂性:从令人尴尬的并行操作(将所有操作员链接在一起)到非常复杂的作业DAG(具有多个改组阶段和复杂的会话化逻辑)。基于时间窗口/会话:窗口大小范围从几秒钟之内(即捕获事务开始/结束事件),到长达数小时的自定义用户行为会话窗口。流量模式:流量模式根据每个用例而有很大不同。 流量可以是突发性的,也可以是GB /秒级别的一致性。故障恢复:某些用例需要几秒钟的低故障恢复延迟,而当作业同时处于较大状态并涉及洗牌时,这将变得更具挑战性。回填和倒带:某些作业需要从批处理源或从先前的检查点倒带重放数据。资源竞争:作业可能会遇到任何物理资源(CPU,网络带宽或内存等)的瓶颈。用户依靠平台来提供见解和指导,以调整应用程序性能。复制与延迟:就复制与延迟而言,应用程序可能会有不同的权衡偏好。事件的顺序:大多数用例并不依赖严格的顺序假设,但是有些情况确实需要。交付/处理语义:某些用例可以避免丢失管道中的某些事件,而其他用例可能需要更高的持久性保证。 一些有状态的流作业还期望精确一次的处理保证,其中计算的状态应始终保持一致。受众:我们的用户范围从技术娴熟的分布式系统工程师到休闲业务分析师。 一些团队可能还会选择在我们的平台产品上构建特定于域的平台服务。

3.多租户

Keystone支持数以千计的流作业,其目标范围广泛,从数据交付,数据分析到实现微服务架构模式的问题空间。 由于流作业的多样性,为了向每个用户提供有意义的服务水平保证,基础架构需要提供运行时和操作隔离,同时将共享平台的开销降至最低。

4.弹性

尽管大多数流具有固定的流量模式,但我们必须设计系统来为突然的变化做准备(即,由于受欢迎的节目进入在线状态或意外故障场景而导致的峰值),并能够以自动方式适应并做出反应 。

5.云原生弹性

Netflix完全在云中运行其微服务。由于云的弹性,恒定变化,较高的故障概率特性。我们需要设计该系统,使其能够监视,检测和容忍从网络故障,实例故障,区域故障,群集故障,服务间拥塞/背压到区域灾难故障等所有方式的故障。

6.运营费用

该平台目前为数千个路由作业和流应用程序提供服务。 依靠平台团队手动管理所有流的成本高昂。 相反,用户应负责声明作业的生命周期详细信息,并且基础架构应尽可能自动化。

7.敏捷性

我们希望能够每天多次快速开发和部署更改。 我们还希望允许我们的用户以相同的敏捷度放心地使用该服务。

平台思想与设计原则

1.赋能

该平台的主要目标之一是使其他团队能够专注于业务逻辑,从而使流处理作业的实验,实现,操作变得容易。 通过拥有一个抽象"硬东西"的平台,消除用户的复杂性,这将释放更大的团队敏捷性和产品创新能力。

在较高的层次上,我们努力使我们的用户能够:

快速发现数据并进行数据试验,以数据驱动的创新来驱动产品流处理解决方案的快速原型制作充满信心地生产和运营服务深入了解性能,成本,工作生命周期状态等,以便能够做出明智的本地决策提供工具以使用户能够进行自助服务

2.基本单元

为了使用户能够专注于业务逻辑而不必担心分布式系统涉及的复杂性,或某些现有解决方案的细节,我们的目标是提供一组可轻松插入流任务DAG中的可组合运算符。

此外,流作业本身也可以成为其他下游服务的构建模块。 我们与一些合作伙伴团队一起构建"托管数据集"和其他特定于域的平台。

从平台向下,我们还努力通过利用其他构建模块(例如容器运行时服务,平台动态配置,通用注入框架等)与Netflix软件生态系统进行深度集成。这不仅帮助我们基于其他现有基础构建服务, 解决方案,也使我们的用户熟悉开发和运营环境。

3.合理的折衷

任何复杂的分布式系统都固有地具有一定的局限性,因此,这种系统的设计应考虑各种折衷,即等待时间与重复项,一致性与可用性,严格排序与随机排序等。某些用例可能需要这些折衷的不同组合,因此 平台必须暴露配置选项,并允许个人用户自定义和声明对系统的需求,这一点至关重要。

4.故障是头等公民

在任何大型分布式系统中,故障都是正常现象,尤其是在云环境中。 任何设计合理的云原生系统都应将故障视为头等公民。

以下是一些影响我们设计的重要方面:

假设网络不可靠信任底层的运行时基础结构,但设计自动修复功能加强工作级别隔离以支持多租户发生故障时减小爆炸半径如果任何组件偏离所需状态或发生灾难故障,则进行自动调节的设计正确处理和传播背压

5.关注点分离

在用户和平台之间:用户应该能够通过平台UI或API声明"目标状态"。 目标状态存储在单个事实存储库中,从"当前状态"向"目标状态"移动的实际执行由平台工作流处理,而无需与用户进行交互。

在控制平面和数据平面之间:控制平面负责工作流程的编排/协调,而数据平面则进行繁重的工作以确保事情发生并保持在所需的状态。

在不同的子组件之间:每个组件负责各自的工作和状态。 每个组件的生命周期都是独立的。

运行时基础架构:流处理作业部署在开源Netflix Titus Container运行时服务上,此服务提供配置,调度,资源级别隔离(CPU,网络,内存),高级联网等。

我们的方法

考虑到上述挑战和设计原则,我们关闭了声明性对帐体系结构以驱动可自助服务的平台。 在较高的层次上,此体系结构允许用户使用UI来声明所需作业的属性,该平台将协调子服务以确保即使遇到故障也能尽快达到目标状态。

以下部分涵盖了高层架构,并简单及涉及了设计的各个领域。 在以后的后续帖子中,我们将分享更深入的技术细节和用例。

1.声明式对帐

声明性协调协议用于从控制平面到数据平面的整个体系结构栈。 利用此协议的逻辑结论是将用户声明的目标状态的单个副本存储为持久的真实来源,所有其他服务都将在此进行协调。 当由于暂时性故障或正常的用户触发操作而发生状态冲突时,应始终将真理的来源视为权威,将所有其他版本的状态视为当前的世界观。 整个系统有望最终与真相协调。

真相存储源是一种持久性存储,可保存所有所需的状态信息。 我们目前使用AWS RDS。 它是整个系统的唯一事实来源。 例如,如果一个Kafka集群由于ZK状态损坏而崩溃,我们总是可以仅基于事实来源来重新创建整个集群。 相同的原则适用于流处理层,以纠正任何处理层偏离其期望目标状态的当前状态。 这使得连续自我修复和自动化操作成为可能。

我们可以从该协议设计中获得的另一个优势是,鼓励操作是幂等的。 这意味着控制指令从用户传递到控制平面,再传递到作业群,不可避免的故障情况不会导致长期的敌意。 这些服务最终只会自己进行协调。 这也带来了操作敏捷性。

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.连接器,托管运算符和应用程序抽象

为了帮助我们的用户提高开发敏捷性和创新能力,我们提供了全方位的抽象,包括托管连接器,供用户插入处理DAG的操作符,以及与各种平台服务的集成。

我们提供了与Kafka,Elasticsearch,Hive等相关的托管连接器。这些连接器消除了围绕自定义线路格式,序列化(因此我们可以跟踪不同格式的有效负载,以优化存储和传输),批处理/限制行为以及,易于插入处理DAG。 我们还提供动态的源/接收器运算符,使用户可以在运行时在不同的源,或接收器之间进行切换,而无需重建。

其他管理的操作符包括过滤器,投影,易于理解的自定义DSL。 我们将继续与用户合作,为集合提供可靠的操作符,并使更多的团队可以使用它们。

6.配置和不可变部署

多租户配置管理具有挑战性。 我们希望使配置体验动态化(因此用户不必重建/重新发送代码),并且同时易于管理。

默认的托管配置和用户定义的配置都与应用程序属性文件一起存储,我们已经进行了深入的研究,以使这些配置可以被环境变量覆盖,并可以通过自助服务用户界面进一步覆盖。 这种方法与协调架构相吻合,该架构允许用户进入我们的UI来声明预期的配置,并且部署流程将确保最终在运行时保持一致。

7.自我修复

在分布式系统中,故障是不可避免的。 我们完全希望这种情况随时可能发生,因此我们设计了可自我修复的系统,因此不必为了缓解事件而在半夜醒来。

在架构上,平台组件服务是隔离的,以在发生故障时减小爆炸半径。 协调架构还通过持续协调漂移行为来确保系统级的自我恢复。

在单个作业级别,遵循相同的隔离模式以减少故障影响。 但是,为了处理此类故障并从中恢复,每个托管的流作业均附带运行状况监视器。 运行状况监控器是在Flink群集中运行的内部组件,负责检测故障情况并执行自我修复:

集群任务管理器的漂移:如果Flink的容器资源视图,与容器运行时视图始终不匹配。 主动终止受影响的容器将自动纠正漂移。失速作业管理器(Job Manager)领导者:如果无法选举领导者,集群将变得毫无头脑。 纠正措施将在作业管理器上执行。容器资源不稳定:如果某些任务管理器显示不稳定的模式(例如定期重新启动/失败),它将被替换。网络分区:如果任何容器遇到网络连接问题,它将自动终止。

8.回填和倒带

同样,失败是不可避免的,有时可能需要用户回填或倒回处理作业。

对于备份到数据仓库中的源数据,我们在平台中内置了功能,以允许动态切换源,而无需修改和重建代码。 这种方法有一定的局限性,仅建议用于无状态工作。

或者,用户可以选择将处理倒回至先前自动获取的检查点。

9.监控和警报

所有单独的流作业均带有个性化的监视器和警报仪表板。 这有助于平台/基础架构团队和应用程序团队诊断和监视问题。

10.可靠性与测试

随着平台和底层基础设施服务的创新,以提供新功能和改进,快速变更的压力从架构上说,自下而上产生。

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

压力在中间汇合。 为了使我们能够提供并获得信任,我们需要使平台和用户都能够有效地测试整个堆栈。

我们坚信使我们的所有用户都可以使用单元测试,集成测试,操作Canary和数据奇偶校验Canary,并且易于采用其作为流处理范例。 我们正在这方面取得进展,并且仍然看到许多挑战需要解决。

现在和未来

在过去的一年半中,Keystone流处理平台已证明其自身,已经超越了每天数万亿事件的规模。 我们的合作伙伴团队已经建立,并生产了各种分析流用例。 此外,我们开始看到在其之上构建更高级别的平台。

但是,我们的故事并没有到此结束。 为了实现平台愿景,我们还有很长的路要走。 以下是我们正在研究的一些有趣的项目:

架构图服务层可实现更灵活的平台交互提供流式SQL和其他更高级别的抽象,以为不同的受众解锁价值分析与机器学习用例微服务事件采购架构模式

这篇文章介绍了Keystone平台的高级视图。 将来,我们将对用例,组件功能和实现进行更详细的深入研究。 敬请期待。

0人推荐
随时随地看视频
慕课网APP