流计算又称实时计算,是以Map-Reduce为代表的批处理之后的另一种重要计算模型。随着互联网业务的发展和数据规模的不断扩大,传统的批量计算很难快速有效地处理数据,并且延迟和返回结果较低。由于数据几乎处于增长状态,及时处理和计算大量数据成为批量计算的一大难题。在此背景下,流量计算应运而生。与传统的批处理计算相比,流计算具有低延迟、高响应和连续处理的特点。在数据生成的同时,我们可以计算并得到结果。更有甚者,Lambda架构可以将即时的流量计算结果和延迟的批量计算结果结合起来,更好地满足低延迟、高精度的业务需求。
Twitter由于自身的业务特点,对实时性有很强的需求。因此,在流计算方面投入了大量的资源。Storm作为第一代流处理系统,自发布以来得到了广泛的关注和应用。根据Storm在实践中遇到的性能、规模、可用性等问题,Twitter开发了第二代流处理系统——Heron[1],并于2016年开放。
重要概念的定义
在开始了解Heron的具体架构和设计之前,我们先定义一些流量计算和Heron设计的基本概念:
元组:流计算任务中处理的最小单位数据的抽象。
流:由无限元组组成的连续序列。
Spout:从外部数据源获取数据并生成Tuple的计算任务。
Bolt:处理上游喷口或Bolt生成Tuple的计算任务。
拓扑:通过流连接喷口和螺栓来处理元组的逻辑计算任务。
分组:流计算中的元组分布策略。在通过流向下游螺栓传递元组的过程中,分组策略决定如何将元组路由到特定的螺栓实例。典型的分组策略有:随机分布、基于元组内容的分布等。
物理计划:基于拓扑定义的逻辑计算任务和拥有的计算资源生成的实际运行时信息的集合。
基于上述流处理的基本概念,我们可以构造流处理的三种不同的处理语义:
顶多一次:尽可能多的处理数据,但是不能保证数据会被处理。吞吐量大,计算速度快,但计算结果存在一定误差。
至少一次:当外部数据源允许重放时,确保数据至少被处理一次。如果出现错误,数据将被重新处理,同一数据可能会被重新处理多次。数据处理得到保证,但延迟会增加。
恰好一次:每个数据保证只处理一次。结果是准确的,但是增加了计算资源并且降低了计算效率。
从上面可以看出,三种不同的处理模式各有优缺点,因此在选择处理模式时,需要综合考虑一个拓扑对吞吐量、延迟、结果误差和计算资源的要求,从而做出最佳选择。目前,Heron已经实现了最多支持一次和至少一次语义,并且正在向只支持一次语义发展。
Heron系统概述
保持与风暴界面(API)的兼容性是鹭的设计目标之一。所以Heron的数据模型和Storm的数据模型基本一致。提交给Heron的每一个拓扑都是一个有向无环图,由喷口和螺栓两种顶点组成,以流为边。其中,Spout节点是Topology的数据源,它从外部读取Topology需要处理的数据,比如kafka-spout,然后发送给后续的Bolt节点进行处理。螺栓节点执行实际数据计算,如过滤器、地图和平面地图。
我们可以把Heron的拓扑学比作数据库的逻辑查询计划。这种逻辑计划只有变成实际的加工计划才能实施。用户在编写拓扑学时指定每个Spout和Bolt任务的并行性以及拓扑中节点间元组的分组策略。用户提供的所有信息都是通过打包来计算的,这些喷口和螺栓任务被分配给一批抽象容器。最后,通过将这些抽象容器映射到真实容器,可以生成物理计划,它是所有逻辑信息(拓扑图、并行性、计算任务)和运行时信息(计算任务和容器之间的对应关系、实际运行地址)的集合。
整体结构
总体来说,Heron的整体架构如图1所示。用户通过命令行工具向海伦调度器提交拓扑。然后,调度程序分配资源并调度提交的拓扑。同时,多个独立拓扑可以在同一资源平台上运行。
图1鹭建筑
与风暴的服务架构不同,赫伦是一个图书馆架构。Storm在架构设计上是基于服务的,所以需要设置一个专门的Storm集群来运行用户提交的Topology。在开发、运维、成本等方面都有很多不足。Heron是基于库的,可以在任何共享资源调度平台上运行。最大限度地降低了运行维护负担和成本。
目前Heron支持Aurora、shate、Mesos和EC2,Kubernetes和Docker目前正在开发中。通过可扩展插件Heron Scheduler,用户可以根据不同的需求和实际情况选择相应的运行平台,从而实现多平台资源管理器的支持[2]。
提交运行的拓扑内部结构如图2所示,不同的计算任务封装在多个容器中运行。由调度程序调度的这些容器可以在同一个物理主机上,也可以分布在多个主机上。每个拓扑的第一个容器(容器0)负责整个拓扑的管理,主要运行一个拓扑主进程;其他容器负责实现用户提交的计算逻辑,每个容器主要运行一个流管理器进程、一个度量管理器进程和多个实例进程。每个实例负责运行喷口或螺栓任务。我们将在本文后面的章节中详细分析拓扑管理器、流管理器和实例进程的结构和重要功能。
图2拓扑结构
状态存储和监控
Heron的State Manager是一个抽象模块,具体实现可以是ZooKeeper,也可以是文件系统。它的主要功能是保存每个拓扑的各种元信息:拓扑的提交者、提交时间、运行时生成的物理规划、拓扑主的地址等。,为拓扑的自恢复提供帮助。
每个容器中的度量管理器负责收集容器的运行时状态度量,并将它们上传到监控系统。在当前的Heron版本中,简化的监控系统集成在拓扑管理器中。将来,该监控模块将成为容器0中的独立进程。苍鹭还提供了两个工具,苍鹭跟踪器和苍鹭用户界面,以查看和监控数据中心运行的所有拓扑。
起动程序
在拓扑中,拓扑主节点是整个拓扑的元信息管理器,它维护拓扑的完整元信息。而流管理器是每个容器的网关,负责实例间的数据通信和实例与拓扑主控器间的控制信令。
用户提交拓扑后,调度程序将开始分配资源并运行容器。每个容器中启动一个Heron执行器进程,它将容器0与其他容器区分开来,并分别启动拓扑主进程或流管理器进程。在普通容器中,当实例进程启动时,它将主动向本地容器的流管理器注册。在收到实例的所有注册请求后,流管理器会将自己负责的实例的注册信息发送给拓扑主机。拓扑主机在收到所有流管理器的注册信息后,将生成每个实例的物理计划和流管理器的实际运行地址,并广播和分发它。每个流管理器收到物理计划后,可以根据物理计划建立相互连接,形成一个完整的图形,然后开始处理数据。
实例执行特定的元组数据计算和处理。流管理器不执行特定的计算和处理任务,只负责中继和转发元组。从数据流网络的角度来看,Stream Manager可以理解为每个容器的路由器。所有实例之间的元组传输通过流管理器进行中继。因此,容器中实例之间的通信是一个星型网络。所有流管理器都连接在一起形成网状网络。容器之间的通信也是由Stream Manager中继的,由两跳中继完成。
核心成分分析
TMaster
TMaster是拓扑主机的缩写。作为主角色,TMaster提供了一个全局接口来了解拓扑的运行状态,这与许多主从分布式系统中的主单点处理控制逻辑具有相同的功能。同时,通过将重要的状态信息(物理计划)记录到ZooKeeper中,确保TMaster在崩溃恢复后可以继续运行。
当实际产品中的TMaster启动时,它会在ZooKeeper的指定目录中创建一个临时节点来存储自己的IP地址和端口,以便流管理器可以发现自己。苍鹭使用短命节点的原因包括:
在一个拓扑中避免多个主器件。这样,该拓扑的所有进程都可以识别同一个TMaster;
同一个拓扑中的进程可以通过ZooKeeper找到TMaster的位置,然后与之建立连接。
TMaster主要有以下三个功能:
建立、分发和维护物理计划;拓扑学;
收集每个流管理器的心跳,确认流管理器的存活;
收集和分发拓扑的重要运行时状态指标。
由于拓扑的物理规划只能在运行时确定,因此TMaster是构建、分发和维护物理规划的最佳选择。在TMaster完成启动并向ZooKeeper注册后,它将等待所有流管理器与它们自己建立连接。在流管理器和主服务器之间的连接建立后,流管理器将报告它自己的实际IP地址和端口,以及它负责的实例地址和端口。天猫可以建立物理计划,并在收到流管理器报告的所有地址信息后进行广播。所有的流管理器将接收到由TMaster构建的物理计划,并根据其中的信息与其他流管理器建立成对的连接。只有当所有的连接都建立后,拓扑才会真正开始运行和处理数据。流管理器丢失并重新连接后,TMaster会检测其运行地址和端口是否发生了变化;如果发生变化,物理计划将及时更新并广播和分发,以便流管理器可以建立正确的连接,从而确保整个拓扑的正确运行。
TMaster将接收流管理器定期发送的心跳信息,并维护每个流管理器的最新心跳时间戳。心跳可以首先帮助TMaster确认流管理器的存在,然后帮助它决定是否更新流管理器连接和更新物理计划。
天猫还接受由指标管理器发送的一些重要指标,并将这些指标提供给海伦追踪器。苍鹭跟踪器可以通过这些度量来确定拓扑的运行状态,并使苍鹭用户界面能够基于这些重要的度量来监控和检测。典型的度量是:分配元组的次数、计算元组的次数以及处于背压状态的时间。
值得注意的是,TMaster本身并不涉及任何实际的数据处理。因此,它不会接受和分发任何元组。有了这种设计,TMaster本身逻辑清晰,重量轻,也为以后的功能扩展留下了巨大的空空间。
流管理器和背压机制
Stmgr是流管理器的缩写。Stmgr管理元组的路由,并负责转发元组。STGR获得物理规划后,可以从信息中知道它与其他STGR连接形成网状网络,从而进行数据中继和背压控制。元组的传输路径可以由图3来说明。在图3中,容器1的实例D(1D)向容器4的实例C(4C)发送元组。这个元组的路径是容器1的1D、容器1的Stmgr、容器4的Stmgr和容器4的4C。例如,元组从3A到3B的路径是容器3的3A、Stmgr和3B。与互联网的路由机制相比,Heron的路由非常简单,这是由于Stmgr成对连接,使得所有实例之间的距离小于2跳。
图3元组发送路径的示例
打包
除了路由中继元组之外,Stmgr还负责打包已处理的元组。Acking的概念在Heron的前身Storm就有了。打包机制的目的是实现至少一次的语义。原则上,在螺栓实例处理元组之后,螺栓实例向螺栓的上游螺栓实例或出口实例发送特殊的打包元组,并向上游节点确认元组已经被处理。在这个过程中,层前进到上游节点,直到喷口节点。实现上,Acking Tuple通过Stmgr时,Tuple用xor运算标记,从xor运算的特性可知处理是否完成。当Spout的一个实例在一定时间内没有收集到打包元组时,它将重新发送相应的数据元组。Heron的Acking机制的实现与其前身Storm是一致的。
背压
Heron引入了一种背压机制,动态调整Tuple的处理速度,避免系统过载。一般来说,解决系统过载问题有三种策略:1。放手;2.丢弃过载数据;3.请求减轻负荷。Heron采用第三种策略,利用背压机制从过载中恢复,以保证系统在过载下不会崩溃。
背压机制的触发过程如下:当一个Bolt实例的处理速度跟不上元组的输入速度时,负责向该实例转发元组的Stmgr缓存会不断累加。当缓存大小超过高水位线时,Stmgr将停止从本地喷口读取元组,并向拓扑中的所有其他Stmgr发送“启动背压”消息。而剩下的Stmgr将在收到这个消息时停止从它们负责的喷口实例读取和转发元组。此时,整个拓扑不再从外部读取元组,而只处理内部累积的未处理元组。处理速度由最慢的实例决定。经过一段时间的处理后,当高速缓存的大小减小到低水位标记时,开始发送“开始背压”的Stmgr将再次发送“停止背压”消息,以便所有Stmgr将再次开始从喷口实例读取分布式数据。由于Spout通常从具有重放权限的消息队列中读取数据,即使它被冻结,也不会导致数据丢失。
背压过程中要注意两个重要的值:高水位线和低水位线。背压仅在缓冲区的大小超过上限时触发,然后持续到缓冲区的大小降低到下限。这种设计有效地避免了拓扑在背压状态和正常状态之间不断振荡的发展,并在一定程度上保证了拓扑的稳定性。
例子
实例是整个Heron处理引擎的核心部分之一。拓扑中的喷口类型节点或螺栓类型节点由实例实现。不同于Storm的Worker设计,当前Heron中的每个Instance都是一个独立的JVM进程,通过Stmgr分发和接受数据,完成用户定义的计算任务。独立进程的设计带来了一系列的优势,如易于调试、调优、资源隔离、容错恢复等。同时,由于数据分发和传输的任务已经由Stmgr处理,实例可以用任何编程语言实现,从而支持各种语言平台。
实例设计有两个线程,如图4所示。实例的进程包括两个线程:网关和任务执行。网关线程主要控制实例与本地Stmgr和Metrics Manager之间的数据交换。通过TCP连接,网关线程:1。接受待定元组;由Stmgr分发;2.将任务执行处理后的元组发送到Stmgr;3.将任务执行线程生成的指标转发给指标管理器。无论是喷口还是螺栓,网关线程执行相同的任务。
任务执行线程负责执行用户定义的计算任务。对于喷口和螺栓,任务执行线程将执行open()和prepare()方法,以相应地初始化它们的状态。如果运行的实例是螺栓实例,任务执行线程将执行execute()方法来处理接收到的元组;;如果是Spout,将重复执行nextTuple()方法,从外部数据源获取数据,生成一个Tuple,并发送给下游的Instance进行处理。处理后的元组将被发送到网关线程进行进一步分发。同时,在执行过程中,任务执行线程会生成各种度量(元组处理量、元组处理延迟等)。)并将它们发送给指标管理器进行状态监控。
图4实例结构
网关线程和任务执行线程通过三个单向队列进行通信,即数据输入队列、数据发送队列和度量发送队列。网关线程通过Tuple通过数据输入队列到任务执行线程;任务执行通过数据发送队列将处理后的元组发送给网关线程;任务执行线程通过度量发送队列将收集的度量发送到网关线程。
总结
本文介绍了流媒体计算的背景和重要概念,详细分析了当前Twitter的流媒体计算引擎Heron的结构和重要组件。希望能为您提供一些设计和构建流媒体计算系统的经验,欢迎您给我们建议和帮助。如果你对Heron的开发和改进感兴趣,可以在Github上查看。
【1】Kulkarni,Sanjeev,Nikunj Bhagat,Maosong Fu,Vikas Kedigehalli,Christopher Kellogg,Sailesh Mittal,Jignesh M. Patel,Karthik Ramasamy,Siddarth Taneja。"推特苍鹭:大规模流处理." alt="Heron 深度揭秘Twitter的新一代流处理引擎Heron">