流数据处理介绍

Apache Flink是一个分布式流计算引擎,开发者可以在其上快速实现流式计算。Apache Flink起源2009年在德国柏林理工大学成立的‘Stratosphere’项目。2014年4月成为Apache软件基金的一个孵化项目,8个月之后就成为Apache软件基金的顶级项目。如今有超过250个体向Flink贡献代码。流计算技术快速的被初创公司、企业所采纳,因为它在软件开发、系统架构、商业分析更有效果。本文主要分析传统数据处理架构和流梳理数据架构之间的差异,从而凸显出流计算的特性。

传统数据分析方法

传统IT设施、业务应用程序运行于不同的操作系统,数据落地于不同的数据库中,当做数据分析的时候无法满足复杂的分析,大表关联查询性能要么不支持、要么性能非常差。

替代传统数据库的分析方案是传统的数据仓库。数据仓库的操作过程我们叫他为ETL(extract-transform-load),这个过程包含数据有效性检验、数值标准化、编码、模式转化、重复值去除。ETL是一个非常复杂的一个过程,通常需要专业的技能才能完成这个工作。致命的一点是数据仓库中的数据是周期性更新的,为何是致命的一点后面将做详细讲解。以下是ETL的架构图:

这种模式在很长一段时间里,都使用分析型数据库作为数据仓库的载体。最近10年,出现了以MapReduce、HDFS、Hbase为框架的数据处理框架。这种形式存在如下缺点。首先,维持系统的平稳运行就是一个较大的挑战,其中需要配置集群、开发ETL任务、任务调度管理,每个步骤都存在较大的挑战。其次,这种框架在数据处理上存在较大的延迟。数据从业务系统产生到分析出结果的延迟一般需要几个小时,有的甚至超过一天。当然,一个批处理平台只能在事件发生后才能处理这些数据,不能在事件发生的时候处理。

数据分析演化

以前,数据分析在几个小时或者一天的延迟内是可以接受的。然而,现在的系统和业务对数据的实效性要求越来越高。例如:商品推荐系统,系统监控。这些都实时收集这些数据并处理,根据处理结果做相应的应对动作。

流计算处理就能够满足上面的要求,数据产生出来后在几秒内就处理完得出分析结果。根据传统ETL结构图,流计算架构图如下:

CDC(change data capture)获取业务系统变化的记录,例如通过采集Binlog日志。常见的消息队列有Kafka,Metaq、TT,其中有保序和不保序的消息队列。流处理统计得出对应的指标,并将结果存在在KV数据库(HBase)上,最终通过dashboard展示结果或者推送个应用系统做出相应的推荐。流处理的第一个优点是延迟小,因为流计算处理不需要数据加载,定时批量处理数据。因为流处理数据摄入和处理在一个框架内处理的,所以流处理系统不需要处理数据摄入、任务调度,相比批处理系统更加稳定。

流数据分析

对于延迟非常低的一些应用,批处理无法满足这样的低延迟,流处理能非常的满足这种场景。这些应用如:

  • 异常检测,例如:检测网络攻击;
  • 实时推荐,例如:根据用户最近几分钟的行为动作,为用户推荐商品;
  • 模式识别或复杂事物处理,例如:信用卡诈骗;
  • 在线ETL,数据产生时连续不断的将数据转移并加载;
  • 在新兴技术中的应用,如:物联网。

然而,解决以上场景的能力并不是寻找分布式流处理的唯一动因。它同样为数据应用提供了一种可扩展的数据架构。系统间通过定义好的接口通信,各系统之间相互独立。架构图如下:

图中,有一个web和日志采集服务实时采集数据并将数据写入消息队列中。带状态的流应用处理将数据摄入,处理,最后将结果写入消息队列或者写入数据库中通过可视化工具展示出来。

这种架构除具有以上优点外,还具备一下优点。通过持久化的消息队列在带状态的应用程序中进行通信具备如下优势:

  • 多个应用可以读和写一个数据流;这个保障了所有应用消费的数据完全一致、并且顺序也是一致的;
  • 应用程序可以重复消费这份持久化在消息队列中的数据。当修复bug的时候用于AB测试非常有用;
  • 有状态流处理程序将状态数据持久化,便于失败的时候恢复;
  • 这种架构将实现了读写分离。数据采集只能追加,有非常好的写性能。下游读应用也有非常好的读性能;
  • 最后,这种框架容易扩展,应为消息队列和流处理都是分布式系统;

上述解决方案,为业务提供了OLTP库类似的解决方案,但又具备上面所列举的特性。

开源流处理演进

数据流处理不是一项新技术。第一个研究原型和商业化产品可以回溯到20世纪90年代。然而,最近的流处理技术主要是基于开源软件发展起来。今天,分布式开源流处理引擎为许多不同领域的企业提供关键业务应用,如:在线零售,社交媒体,电信,游戏,和银行。开源软件是这一趋势的主要推动力,主要是由于以下两个原因。其一,开源软件每个人都可以使用和改进它。其二,由于开源社区的努力,可扩展的流处理技术正在迅速成熟和发展。仅Apache软件基金就有10多个项目于流处理相关。新的流处理项目还在源源不断的进入开源社区,且以新的特性和能力挑战当前的新技术。这些新系统的许多特性正被其他流处理框架采纳和吸收。此外,开软软件的使用者可以请求或贡献缺少的新功能,以支持这些场景。就这样开源社区不断提高项目的处理能力,进一步推动流计算处理。我们将简要回顾一下流处理的发展历程并将展望未来。

第一个获得大量使用的开源分布式流计算处理引擎专注于毫米级的时间处理,并保证系统发生故障时事件不丢失。这些系统提供底层API并且不提供对流式应用的准确一致的结果支持,应为结果取决于事件抵达的时间和先后顺序。而且,就算事件不会在失败的时候丢失,同一个事件也会存在重复。

与提供准确和高延迟的批处理相反,第一个开源流处理器倾向于用准确性换地延迟。这样的数据处理系统能够提供低延迟和存在一定误差的结果。这种系统结构叫做Lambda架构,如下图:

Lambda架构利用地延迟的流计算处理支持Speed Layer增强传统批出来系统。数据抵达Lambda架构后由流处理器读取数据,并将数据写入批处理存储上,如:HDFS。流处理器几乎实时的计算出估计结果,并将结果写入Speed Table中。批处理器周期性的将写在批量存储器上的数据处理完。准确的结果将写入Batch Table并删除Speed Table上的估计结果。服务层通过合并来源于Speed Table的估计结果和Batch Table的精确结果为应用程序提供服务。Lambda架构目的时在于改善批处理系统的高延迟。然而,这种方法也存在非常明显的缺点。首先,需要分别实现两套处理系统语义不同的接口。其次,流计算处理器计算的结果是一个估计值,而不是一个准确的结果。再次,Lambda架构难以设置和维护。流处理器、批处理器、速度存储、批存储、数据摄入、批处理任务调度器都需要使用说明手册。

第二代流处理器,在第一代的基础上改善了准确性,实现了一个事件之消费一次的语义(exactly once)。同时提供的API相比第一代更加高级,在吞吐量和失败恢复上都有较大的改善。但是还是没有解决乱序的问题,计算结果还是受数据的消费顺序影响。

在第三代流处理器的计算结果不在依赖数据的消费顺序,能够准确计算出结果。另一个改进是吞吐-延迟衡量。这一代流计算处理器使得Lambda架构被淘汰。说了这么多,接下来我们看一个第三代流处理引擎flink。

Apache Flink是一个分布式流计算引擎,据有第三代引擎的特性。她在大规模数据处理上提供了准确的、高吞吐、地延迟的处理。以下是Flink的特性,详细的特性请参考Flink官网:https://flink.apache.org/。

  • Flink提供三种时间语义:事件事件(event-time),摄入事件(ingestion-time),处理事件(Processing-time);
  • Flink实现了仅处理一次(exactly-once)和至少(At-least-once)处理一次的语义;
  • Flink处理性能非常好。吞吐量在百万量级上处理延迟在毫秒级。同时Flink应用的规模可以扩展到一千多个核;
  • Flink为常见的功能提供了高级API,例如Window操作。同时也提供底层API以便满足用户的个性化需求;
  • Flink生态非常丰富,kafka、JDBC、HDFS等常用的大数据平台;
  • Flink可以7*24小时高可用的运行,同时可以采用YARN和Apache Mesos部署,可以快速恢复和动态扩展任务的规模;
  • Flink可以在不失去应用状态的情况下,动态更新代码或者合并不同版本的任务;
  • 系统对外提供Metrics用于采集系统或者应用的指标,帮助用户识别问题;
  • 最后一点,但是不是最终的一点。Flink已经是一个成熟的处理器;

除了以上功能外,Flink对外提供的API是非常有好的,并且允许Flink应用在IDE里运行于单个JVM上。这对开发者在IDE上调试Flink任务是非常有用的。

以下我们在本地集群上部署并执行第一个Flink程序,以便我们直观的感受这些特性。我们采用随机生成的温度数据聚合为例。运行环境需要Unix, java7。如果你运行在windows上,建议按照Linux虚拟机或者Cygwin。

1、到Apache 官网flink.apache.org下载二进制的Apache Flink 1.1.3(Hadoop 2.7,Scala 2.11)

2、执行一下命令解压压缩文件:

1
tar xvfz flink-1.1.3-bin-hadoop27-scala_2.11.tgz

3、启动Flink的本地模式:

1
2
cd flink-1.1.3
./bin/start-local.sh

4、在浏览器中输入http://localhost:8081打开监控页面。将会看一些统计之宝,表明本地Flink集群已经启动。它将显示单个任务管理器(Flink的工作进程)已连接,并且单个任务槽(由任务管理器提供的资源单元)可用。

5、下载测试用例。
wget https://streaming-with-flink.github.io/examples/download/examples-scala.jar

注:你需要自己通过README打包项目为jar包。

6、在本地集群上提交测试用例

1
./bin/flink run -c io.github.streamingwithflink.AverageSensorReadings examples-scala.jar

7、打开web监控将看到一个运行的job。可以点击job链接查看job的监控信息

8、Apache Flink集群默认数据输出的路径为./out。可以通过如下命令看看输出:

1
tail -f ./log/flink-<user>-jobmanager-<hostname>.out

将在终端看到如下类似信息:

1
2
3
4
SensorReading(sensor_2,1480005737000,18.832819812267438)
SensorReading(sensor_5,1480005737000,52.416477673987856)
SensorReading(sensor_3,1480005737000,50.83979980099426)
SensorReading(sensor_4,1480005737000,-17.783076985394775)

9、至此,已经运行了一个流计算程序。程序需要手动停止,可以在监控页面操作,可以在命令行下操作。

1
./bin/stop-local.sh

到这里已经知道如何按照和运行Flink程序。在这本书中还可以学到更多关于Flink的知识。

为了支持作者,如果您觉得本书可以,请购买书籍。

参考文献:
《Stream Processing with Apache Flink》

坚持原创技术分享,您的支持将鼓励我继续创作!欢迎大家加我微信交流:saixialv
0%