2.2 实时数据平台的架构、技术和设计
离线数据平台产出数据的周期一般是天,也就是说,今天看到的是昨天的数据,对于大部分的分析和“看”数据的场景来说,这种T+1的离线数据可以满足业务分析的需求,但是随着业务运营日渐精细化,对数据的时效性要求越来越高,越来越多的业务场景需要马上看到业务效果,尤其是在业务促销活动等(典型的如双11大促、618大促等)场景下。
更重要的是,随着人工智能浪潮的兴起,实时的数据已经不是最好,而是必须。数据也不仅仅在分析和“看”,而是和算法一起成为生产业务系统的一部分。
大数据和人工智能是天然的一对最佳搭档,尤其是在实时数据方面。对于很多场景来说,实时数据训练的算法效果和离线数据训练的算法效果有着天壤之别,实时数据训练得到的算法用到的数据就是算法正式上线后输入的数据,因此准确性有保障,是算法工程师和业务的首选。
而所有这些都必须借助于实时数据平台。
实时数据平台近两年越来越得到重视,尽管某些方面还不够成熟,但是技术发展非常迅速。实时数据平台和相关技术未来有可能颠覆离线的数据平台和技术,尤其是在数据处理方面,当然这一切还需时间来校验。
2.2.1 实时数据平台的整体架构
和离线数据平台一样,这里也首先给出实时数据平台的整体架构大图(见图2-6),使读者对实时数据平台有全局性的认识和了解。
图2-6 实时数据平台的整体架构大图
实时数据平台的支撑技术主要包含四个方面:实时数据采集(如Flume),消息中间件(如Kafka)、流计算框架(如Strom、Spark、Flink和Beam等),以及实时数据存储(如列族存储的HBase)。目前主流的实时数据平台也都是基于这四个方面相关的技术搭建的。
实时数据平台首先要保证数据来源的实时性。数据来源通常可以分为两类:数据库和日志文件。对于前者,业界的最佳实践并不是直接访问数据库抽取数据,而是会直接采集数据库变更日志。
数据采集工具(如Flume)采集的binlog事件,其产生速度和频率通常取决于源头系统。它和下游的实时数据处理工具(比如Storm、Spark、Flink等流计算框架和平台)处理数据的速度通常是不匹配的。另外,实时数据处理通常还会有从某历史时间点重启以及多个实时任务都要使用同一源头数据的需求,因此通常还会引入消息中间件来作为缓冲,从而达到实时数据采集和处理的适配。
实时数据处理通常采用某种流计算处理框架,目前使用最为广泛的是Storm(不仅指原生Storm,还包含其他类Storm框架如JStorm、Storm Trident等)、Spark和Flink等。
实时数据存储根据下游数据使用的不同方式通常放在不同的数据存储内。对于数据在线服务(即数据使用方传入某个业务ID,然后获取到所有此ID的相关字段),通常放在HBase内。对于实时数据大屏,通常放在某种关系数据库(如MySQL)内,有时为了提高性能并减轻对底层数据库的压力,还会使用缓存数据库(如Redis)等。
实时数据平台最为核心的技术是流计算,因此下面重点介绍流计算的概念和技术。
2.2.2 流计算技术
流计算的开始流行和被大家所接受始于2011年左右诞生的Storm。Storm作为“实时的Hadoop”迅速被大家所知并接受。
那么,什么是流计算呢?它和离线批量处理又有哪些区别呢?
不同于离线批处理(如Hadoop MapReduce),流计算有着下面典型的特征。
❏ 无边界:流计算的数据源头是源源不断的,就像河水一样不停地流过来,相应地,流计算任务也需要始终运行。
❏ 触发:不同于Hadoop离线任务是定时调度触发,流计算任务的每次计算是由源头数据触发的。触发是流计算一个非常重要的概念,在某些业务场景下,触发消息的逻辑比较复杂,对流计算挑战很大。
❏ 延迟:很显然,流计算必须能够高效地、迅速地处理数据。不同于离线Hadoop任务至少以分钟甚至小时计的处理延迟,流计算的延迟通常在秒甚至毫秒级,分钟级别的延迟只在有些特殊情况下才被接受。
❏ 历史数据:Hadoop离线任务如果发现历史某天的数据有问题,通常很容易修复问题而且重运行任务,但是对于流计算任务来说基本不可能或者代价非常大,因为首先实时流消息通常不会保存很久(一般几天),而且保存历史的完全现场基本不可能,所以实时流计算一般只能从问题发现的时刻修复数据,历史数据是无法通过流式方式来补的。
从根源上讲,流计算的实现机制目前有两种处理方式:一种是模仿离线的批处理方式,也就是采用微批处理(即mini batch)。微批处理带来了吞吐量的提升,但是相应的数据延迟也会增大,基本在秒级和分钟级,典型的技术是Spark Streaming。另一种是原生的消息数据,即处理单位是单条数据,早期原生的流计算技术延迟低(一般在几十毫秒),但是数据吞吐量有限,典型的是原生的Storm框架,但是随着Flink等技术的产生和发展,吞吐量也不再是问题。
2.2.3 主要流计算开源框架
Storm是最早的流计算技术和框架,也是目前最广为所知的实时数据处理技术,但是实际上还有其他的开源流计算技术,如Storm Trident、Spark Streaming、Samza、Flink、Beam等,商业性的技术还有Google MillWheel和亚马逊的Kinesis等。
除了这些五花八门的技术,流计算的另一个趋势是开发语言不停向声明式语言尤其是流计算SQL的发展。
本章将不会深入上述具体的流计算技术,这些任务将在后续各章节中完成,但是这里将尝试介绍这些技术的发展脉络及其各自的特点。很多时候,技术平台和框架都已经选定,也就是说,一个数据开发人员,其实际工作的实时流计算技术可能已被选定,可能是上述技术其中的一种,但是作为一个合格的数据开发人员,还需要了解其他流计算技术及其优缺点和适用场景等,做到心中有数。
假设一个公司要选择某种流计算技术,那么需要考虑哪些方面呢?从实际的项目实践来看,需要考虑如下几个方面。
❏ 技术成熟度:即该流计算框架在工业界的实际应用情况;该技术有没有在生产环境和大数据量、大集群环境下得到验证;有无现成经验和解决方案可供参考;一旦出现问题,能否快速利用别人的经验快速解决。
❏ 性能:该技术是否能够抗住现有的业务数据量,预留空间是多少,实时延迟是否能够满足现有的业务要求。比如,基于微批处理的框架延迟至少在秒级,而原生的流处理框架可以到几十毫秒。
❏ 开发难度和速度:该技术是否提供高级的API,还是必须都从底层API构建业务逻辑;底层API处理灵活,但是对开发人员的技能要求比较高,而且通常耗时较长,高级API(比如流计算SQL)的开发效率非常高,而且门槛低,但某些场景下SQL无法表述,实际项目中需要综合考虑。
❏ 可维护性:具体在流计算框架下,主要体现在状态管理和容错性方面,比如任务失败了、需要调优或者业务逻辑更改升级了,需要暂停和重启任务,流计算框架应该支持从上一个状态中恢复。
❏ 可靠性:流计算的可靠性主要体现在流计算框架对at least once和exactly once的支持。at least once意味着每条消息会进行多次传输尝试,至少一次成功,即消息传输可能重复但不会丢失;exactly once的消息传输机制是每条消息有且只有一次,即消息传输既不会丢失也不会重复。
下面从上述这些方面分别对主流的流计算框架进行介绍。
1.Storm
Apache Storm是大批量流式数据处理的先锋,在Storm初期的宣传中被称为“实时的Hadoop”。Storm或者类Storm的流计算框架也是目前应用最为广泛和最流行的,目前国内主要的互联网公司最初基本都基于Storm搭建了自己的实时数据平台。
Storm是原生的流计算框架,数据一条一条被处理,所以其数据延迟可以非常低,基本在100ms之内,调优的情况下甚至可以到10ms。但是相应地,代价就是处理性能,原生Storm的数据吞吐量一般,而且它不提供高级API,也不支持状态的管理。数据可靠性方面,Storm不支持exactly once的处理,只支持实时消息的at least once处理。
2.Storm Trident
正是由于原生Storm的上述缺点,导致了Trident的出现。Trident是对原生Storm的一个更高层次的抽象,其最大的特点是以mini batch的形式进行流处理。同时,Trident简化topology构建过程,增加了窗口操作、聚合操作或者状态管理等高级操作API。对应于Storm提供的at most once可靠性,Trident还支持exactly once可靠性。
但是微批处理引入、状态管理等的支持也带来了Trident数据延迟的增加,目前基于微批处理的流计算框架的延迟至少是在秒级,有些情况下甚至要到分钟级。
3.Spark Streaming
Spark也是目前业界比较受欢迎也比较流行的实时数据处理方案,尤其对于采用Spark生态作为数据平台解决方案的公司或者组织来说。
从本质上讲,Spark Streaming也是基于微批处理的流计算框架,即它将源头数据分成很小的批并以类似于离线batch的方式来处理这小部分数据。不同于Storm Trident的是,Spark Streaming微批处理框架底层依赖于Spark Core的RDD实现。
如果实时数据架构已经在使用Spark,那么Spark Streaming是非常值得考虑的方案,但是需要记住其基于微批处理的局限性以及数据延迟的问题(一般至少是在秒级甚至分钟级)。
此外,Spark也有高级API,也支持流计算任务的状态管理和exactly once可靠性机制。
4.Flink
Flink项目开始得非常早,大概是在2008年,但是直到2016年才日渐受到重视并变成Apache的顶级项目。
Flink是原生的流计算处理框架,提供高级API、状态管理、exactly once可靠性等,同时数据处理吞吐量也很不错,从目前社区的发展来看,Flink也非常有活力。
此外,Apache Flink是一个同时面向流处理和批处理的开源计算平台,它能够基于同一个Flink引擎,提供流处理和批处理两种类型应用的功能。在Flink中,批处理被当作一种特殊的流处理,只是它的输入数据流被定义为有界的而已。
综上所述,Flink的流处理理念和设计非常不错,能满足绝大多数的流计算应用场景,因此目前很多人认为它将成为未来主流的流计算框架。
但是,目前Flink在工业界和生产系统中还采用得不够非常广泛,据公开资料,国内的Alibaba,国外的Uber、Netflix、爱立信等已经有在生产系统中大规模使用Flink的案例。
以上对各个流计算框架的介绍,可以简化为图2-7所示的内容。
图2-7 主流流计算技术对比