有状态流处理简介 (一)
写在前面:
大家好,我是强哥,一个热爱分享的技术狂。目前已有 12 年大数据与 AI 相关项目经验, 10 年推荐系统研究及实践经验。平时喜欢读书、暴走和写作。
业余时间专注于输出大数据、AI 等相关文章,目前已经输出了 40 万字的推荐系统系列精品文章,强哥的畅销书「构建企业级推荐系统:算法、工程实现与案例分析」已经出版,需要提升可以私信我呀。如果这些文章能够帮助你快速入门,实现职场升职加薪,我将不胜欢喜。
想要获得更多免费学习资料或内推信息,一定要看到文章最后喔。
内推信息
如果你正在看相关的招聘信息,请加我微信:liuq4360,我这里有很多内推资源等着你,欢迎投递简历。
免费学习资料
如果你想获得更多免费的学习资料,请关注同名公众号【数据与智能】,输入“资料”即可!
学习交流群
如果你想找到组织,和大家一起学习成长,交流经验,也可以加入我们的学习成长群。群里有老司机带你飞,另有小哥哥、小姐姐等你来勾搭!加小姐姐微信:epsila,她会带你入群。
Apache Flink 是一个开源的分布式流处理引擎,为有状态数据流处理应用程序提供了丰富的 api 接口,以实现各种简单或复杂的计算功能。不仅如此,它能够高效地支持大规模有状态流应用程序运行,并保证了程序的容错性,在这一点上会比其他的流式计算引擎凸显更多优势。那么这样的 Flink 是从什么时候开始进入业界的视野的呢?2014 年 4 月,Flink 作为一个孵化器项目正式加入了 Apache 软件基金会组织,并于 2015 年 1 月份成为 Apache 的顶级项目,发展可谓非常迅速,从 Flink 加入 Apache 之后,就拥有一个非常活跃且用户和代码贡献者持续增长的社区,时至今日,已经有超过 500 多人为 Flink 贡献了代码,随着 Flink 的快速发展并得到广泛的应用,Flink 得到了业界的认可,慢慢地成为了当下最流行的开源流式计算处理计算引擎,因为 Flink 可以支持大规模商业核心业务应用场景,因此在全球不同的国家和地区受到很多企业的青睐。
随着信息时代的到来,物联网和 5G 得到广泛的使用,带来的是海量的数据,用户和企业对数据处理的实时性要求越来越高,流式处理技术变得越来越重要,可以为企业赋能,为大大小小的企业很多成型的业务场景提供了高效可行的解决方案,比如数据分析、ELT 数据处理和一些事务性应用程序,同时为企业的应用和软件架构提供新的解决思路,获得更多的商机。最后,我们简易讨论一下开源流式计算处理器的演进,并帮助你了解如何在本地运行 Flink 流式应用实例。
传统的数据基础架构
在过去的几十年,数据以及数据处理在企业和商业应用显得无处不在,随着时间的推进,多年以来,数据的收集和使用一直保持着持续增长的趋势,数据如何有效地管理成为每个公司的大事,为了更好的管理源源不断产生的用户数据,很多公司着力于设计和构建数据基础架构,通常情况下主要分为两种类型的架构:一是事务型数据处理,二是分析型数据处理,基于以上两种类型,下面我们讨论这两种类型的基础架构是如何管理和处理数据的。
事务型数据处理架构
很多公司在日常的业务场景中使用了五花八门的应用程序,比如说企业资源管理系统(ERP),客户关系管理系统(CRM)以及基于 Web 端的系统。这些系统通常在设计的时候会区分不同的数据处理层(即应用程序本身)和数据存储(事务型关系数据库),每个系统自成一套流程,如下图 1-1 所示:
以上这些应用程序通常用于连接系统外部服务或者为使用者处理业务需求,比如获取订单信息、接收或者发送邮件以及网站点击行为等等,当我们在处理事件时,应用程序会读取事件的状态或者通过远程数据库系统更新事件的状态,一般来说,一个数据库系统会同时为多个应用程序服务,可能出现共用同一个数据库甚至同一张表的情况。
基于事务型数据处理的架构设计存在不少的弊端,举个例子,当运行的应用程序需要进行扩展时会出现很多的问题,为什么这么说呢?从图中可以看到,由于多个应用程序可能会处理相同的数据或者共享同一个数据存储系统,耦合性很强,这种情况下会涉及到数据库表结构或者数据库的变更,需要花费很多精力去重新设计和规划,会导致生产成本大大提升且系统不稳定性大大增强,如果数据库挂了,会导致所有的应用程序无法对外提供服务,造成的损失可想而知。
问题的出现必然会推动技术的变更来解决问题,微服务的出现很好的解决了应用程序捆绑的问题,微服务的定义是什么呢?顾名思义,微服务的设计原则就是拆分功能模块,使其尽可能小且各自独立,划分单一职责与功能模块;微服务遵循 UNIX 的哲学思想,只做一件事,并且做好它。越来越多的复杂应用程序通过连接少量的微服务标准接口进行通信,比如 RESTful HTTP 连接,为什么要这样做呢?因为微服务彼此之间是严格解耦的,通过定义好的接口进行通信,每个微服务的编程语言也不受限,可以使用不同的技术栈去实现,不局限于编程语言、库和数据存储。通常情况下,微服务和所必需的软件包以及服务会被打包并部署在独立的容器中,图 1-2 描述的就是微服务的架构:
数据分析型处理架构
对于一个公司来说,存储在各种事务型数据库系统中的数据,通常能为公司的运营决策提供有价值的参考依据,比如说,通过对订单处理系统的数据进行分析,可以掌握商品在一段时间内销售的增长率,以此来确定商品延期出货的根源,也可以用来预测未来的销售趋势,及时调整商品库存。然而,事务型数据通常分布在几个互不相连的数据库系统中,在需要进行联合分析时才显得更有价值,此外,不同数据库系统的数据在分析时通常需要转化为通用的处理格式。
与直接在事务型数据库执行分析查询有所不同,在数据分析型处理架构中,数据通常会被统一复制到数据仓库中,即专门用于数据分析查询的数据存储仓库,为了填充数据仓库,需要将事务型数据库系统管理的数据库的数据全部复制到数据仓库中,这个迁移数据的过程我们通常称为“提取-转换-加载”,也就是我们常说的 ETL。ETL 流程负责从事务型数据库(OLTP)抽取数据,根据一定的规范对数据进行验证、编码、去重以及数据结构等一系列操作进行转换,最终把处理好的数据加载到分析型数据库(OLAP)中,当 ETL 处理过程非常复杂的时候,这时候就需要考虑采用高性能的技术解决方案来满足需求,ETL 通常被设置为一个定期运行的任务,目的是为了及时将事务型数据仓库的数据同步到数据仓库中,尽可能保证数据的完整性。
数据一旦被导入到数据仓库中,就可以用来做查询和分析,常见的有两类查询,第一种类型是定期报表查询统计,用于计算与业务相关的统计数据,如收入、用户增长或生产输出。把这些指标组合汇总到报告中,可以帮助管理层评估业务的总体健康状况。第二种类型是即席查询,旨在支撑特定问题的答案用来作为企业关键性决策的依据,例如,通过查询公司营收和投放广告支出,以评估营销活动方案的有效性,本质上,这两类查询说到底都是通过在数据仓库中执行批处理任务,从而得到计算结果,如图 FIgure1-3 所示:
现如今,Apache Hadoop 生态系统的组件已经成为很多企业不可或缺的 IT 基础架构,而不再是将所有数据都插入到关系数据库系统中,而是将大量数据(如日志文件、社交媒体或 web 点击日志)写入 Hadoop 的分布式文件系统(HDFS)、S3 或其他大容量数据存储系统,如 Apache HBase,这些数据存储系统花费很小的成本就可以提供巨大的存储容量。存储系统中的数据可以通过 SQL-on-Hadoop 引擎进行查询和处理,例如 Apache Hive、Apache Drill 或 Apache Impala。不可否认的是,这些基础架构设施基本上仍然与传统的数据仓库体系结构相同。
有状态流处理
实际上,所有数据的产生都可以看做连续的事件流,试想一下,用户与网站或手机 APP 应用产生的互动,订单的信息,服务器产生的日志或者传感器测量等等,统统都可以算是事件流。事实上,很难找到一个一次性生成有限并且完整的数据集的例子。有状态流处理是用于处理无界事件流的应用程序设计模式,适用于公司 IT 基础结构中的许多不同用例,在我们讨论这些用例之前,我们先简单解释一下有状态数据流处理的工作原理。
任何处理事件流的应用程序都应该是有状态的、能够被存储并且支持中间数据访问,而不仅仅是简单做实时数据记录的转换,当一个应用程序接收到一个事件时,能够通过从事件状态中读取或写入的数据进行任意的计算,对于状态来说,其本身可以存储并访问不同的介质,包括程序变量、内存、本地文件、嵌入式数据库或者外部数据库系统等。
Apache Flink 通常将应用程序状态存储在本地内存中,或者嵌入式数据库中,比如 Redis、RocksDB,由于 Flink 是一个分布式系统,因此需要保障本地状态的安全性,避免当应用程序失败或者机器故障引起数据丢失的情况发生。为了防止这种情况的出现,Flink 通过定期对应用程序的状态做一致性 checkpoint(检查点),类似于快照,并持久化到远程的数据库中,在下一章中,我们会对状态以及状态一致性和 Flink checkpoint 机制进行详细的讨论,本章节不做展开,图 1-4 展示的是一个有状态的 Flink 流式处理程序。
有状态流处理程序可以接收来自很多不同渠道和形式的数据,通常从事件流的日志提取事件注入流程序中进行计算,将事件日志存储并分发到事件流中,在这个过程中,事件会以追加的形式有序地持久化到日志中,这是一个有序的过程,一旦事件写入就无法修改顺序。写入事件日志的流可以被相同或不同的消费者多次读取,基于日志只能被追加的属性,所有的事件始终以完全相同的顺序发布给下游的消费者。在实际的使用中,有几个基于事件日志的开源软件可以作为我们的选择,比如 Kafka、RabbitMQ、ActiveMQ,其中以 Apache Kafka 最受欢迎,Kafka 作为时下最火热的消息中间件,可以集成到很多不同场景的系统架构中,受到很多云计算服务厂商的青睐。
出于很多不同的原因,将 Flink 上的有状态流应用程序和事件日志系统搭配使用是非常合适的,在这种体系结构中,事件日志可以用来持久化不断输入的事件,并可以按确定性顺序进行重放。在出现故障的情况下,Flink 可以通过先前保存的检查点恢复状态并且重置事件日志上的读取位置来恢复有状态的流应用程序,然后流应用程序会根据检查点重放(快速转发)来自事件日志的输入事件,在流中重新进行有效回放,这项技术用于程序故障恢复,同时也可以用于更新应用程序、修复缺陷以及修复先前得出的结果、支持将应用程序迁移到不同的集群中运行或者用于区分程序版本进行 A/B 测试。
正如上面所说,有状态的流处理是一种通用且灵活性高的架构设计,可以用来处理不同应用场景下的用例,接下来,我们会介绍三种比较有代表性的应用:
a. 事件驱动型应用
b. 数据管道型应用
c. 数据分析型应用
虽然我们区分了有状态流处理的应用类型,目的是为了说明有状态流处理的通用性,实际上在真实的应用场景中,通常不会使用单独一种应用类型,一般会结合起来使用。
事件驱动型应用
事件驱动型应用是一类具有状态的应用,它从一个或多个事件流提取数据,并根据接收到的事件进行数据计算、状态更新或其他外部动作。根据不同的业务逻辑,事件驱动的应用程序可以触发不同的操作,例如发送报警信息或分析电子邮件信息或将事件写入输出流作为新的事件流给其他的事件驱动程序使用。
事件驱动型应用程序有以下几种典型的用例:
1. 实时推荐(比如用户在浏览电商网站时推荐产品)
2. 模式检查或复杂事件处理(例如用于信用卡交易中的欺诈检测)
3. 异常检测(比如试图侵入计算机网络检测)
事件驱动型应用是微服务的演进,微服务通过 REST 调用进行通信,基于事务型数据库或 K-V 数据库写入或读取数据;而事件驱动型应用则是利用事件日志进行通信,应用数据会以本地状态形式存储,图 1-5 显示了由事件驱动的流应用程序组成的服务体系结构。
图 1-5 中的应用程序通过事件日志进行关联, 一个应用程序将其输出发送到下游事件日志,上游程序的输出结果可以作为输入事件给另一个应用程序进行消费,事件日志可以将发送器和接收器之间的关联关系实现解耦,并提供异步、非阻塞事件传输。 每个应用程序都可以是有状态的,并且可以在本地管理自己的状态,而不需要访问外部数据存储,不仅如此,每个 应用程序也可以单独或者关联起来运行。
相对于传统的事务型应用和微服务来说,事件型驱动应用有几个比较明显的优势,事件驱动型应用无须查询远程数据库,本地数据访问使得它具有更高的吞吐和更低的延迟。而由于定期向远程持久化存储的 checkpoint 工作可以异步、增量式完成,因此对于正常事件处理的影响甚微。事件驱动型应用的优势不仅限于本地数据访问。传统分层架构下,通常多个应用会共享同一个数据库,因而任何对数据库自身的更改(例如:由应用更新或服务扩容导致数据布局发生改变)都需要谨慎协调。反观事件驱动型应用,由于只需考虑自身数据,因此在更改数据表示或服务扩容时所需的协调工作将大大减少。
另外,事件驱动型应用程序对运行它们的流处理器有相当高的要求,不是所有的流处理器都适合运行事件驱动型应用程序。事件驱动型应用会受制于底层流处理系统对时间和状态的把控能力,Flink 诸多优秀特质都是围绕这些方面来设计的。它提供了一系列丰富的状态操作原语,允许以精确一次的一致性语义合并海量规模(TB 级别)的状态数据。此外,Flink 还支持事件时间和丰富的窗口逻辑操作,而且它内置的 ProcessFunction 支持细粒度时间控制,方便实现一些高级业务逻辑。同时,Flink 还拥有一个复杂事件处理(CEP)类库,可以用来匹配数据流中的模式,Apache Flink 符合以上所有的要求,是事件驱动型应用非常好的选择。Flink 中针对事件驱动应用有一个天然的特性—— savepoint。savepoint 是一个一致性的状态快照,它可以用来初始化任意状态兼容的应用。在完成一次 savepoint 后,即可放心对应用进行升级或扩容,还可以启动多个版本的应用来执行 A/B 测试。
数据管道型应用
现如今的 IT 体系结构包括许多不同的数据存储媒介,如关系数据库和非关系型数据库系统、事件日志、分布式文件系统、内存缓存数据库和检索系统等等,以上所有的系统都能以不同的数据格式和数据结构存储数据,这样可以为不同数据库特定访问模式提供最佳的性能。通常,公司会将相同的数据存储在多个不同的系统中,目的是为了提高数据访问的性能,降低单一数据库的压力,例如,Webshop 中提供的产品信息可以存储在事务数据库、Web 缓存和全文检索引擎中;由于数据的复制,意味着不同数据存储系统之间的数据必须保持同步。
周期性 ETL 作业是解决不同数据存储系统直接数据同步问题的常用手段,但是通常延迟非常高,随着企业对实时性要求越来越高,周期性 ETL 无法满足很多要求低延迟的业务场景,这时候可以考虑使用事件日志进行动态分发,将变更的记录写入事件并进行快速分发,及时同步数据更新,这样一来,日志的消费者就会将这个更新过的数据记录同步到不同的数据存储介质中,根据不同的用例,数据在进入目标数据库之前需要先进行标准化和聚合处理。和周期性 ETL 作业相比,持续数据管道可以明显降低将数据移动到目的端的延迟。此外,由于它能够持续消费和发送数据,因此用途更广,支持的应用场景更多。
数据管道和 ETL 作业的用途相似,都可以转换、提取数据,并将其从某个存储系统移动到另一个。但数据管道是以持续流的模式运行,而非周期性触发,因此它支持从一个不断生成数据的源头读取记录,并将它们以低延迟移动到终点,要求在短时间内处理大量的数据,例如:数据管道可以用来监控文件系统目录中的新文件,并将其数据写入事件日志;另一个应用可能会将事件流物化到数据库或增量构建和优化查询索引。数据管道流处理器还支持各种 source connector 和 sink connector,通过不同的连接器可以实现不同数据管道数据的关联和处理,Flink 完全满足数据管道型应用需要的所有特性。
数据分析型应用
数据分析型应用根据实时性大致可以分为批处理和流处理两种类型。
批处理分析
其中最典型的处理方式就是 ETL,ETL 作业定期将数据导入到数据存储中,用于临时查询或生成报表,批处理的一个好处是,不需要关心数据存储的架构是基于数据仓库还是 Hadoop 生态系统的组件, 虽然 ETL 技术在不断地改进,但是仍然存在一个很明显的缺点,对于数据分析还是存在着相当大的延迟。根据作业调度时间间隔和数据量的不同,有些任务需要运行几个小时甚至几天才能生成报表,意味着要得到分析结果需要等待相当长的时间,有时候会很大程度上影响企业的运营决策,错失商业机会,付出不小的代价。通过数据管道型应用导入数据到数据存储介质可以在一定程度上降低时间延迟,尽管如此,就算是连续的 ETL 作业,在执行查询事件之前还是会存在延迟,这种情况放在以前是能够被企业所接受的,但是呢,放在今天的话,人们更多的是希望可以做到实时采集数据并即刻响应数据的变化和快速得到查询分析结果,比如说,根据系统订单的状态,实时修改处理商品库存的变化。
流式处理分析
与批处理分析型应用不同的是,流式处理不需要周期性去触发作业,而是实时地处理不断输入的事件流,通过及时计算并合并最新的结果,达到低延迟的效果,类似数据库用于更新物化视图技术。通常来说,流应用程序将其计算结果存储在支持高效更新的外部数据存储中,例如数据库或 K-V 类型的存储系统中,另外,流分析应用的实时更新结果可应用到仪表盘,如图 1-6 所示。
流分析应用程序除了能用更短的时间合并事件的分析结果之外,还有一个相对不太明显的优势,传统的数据分析管道由几个独立的组件组成,比如 ETL 作业、存储系统,以及基于 hadoop 生态的数据处理引擎和调度器触发作业或查询,通常需要将这些组件进行编排,当程序出现故障时需要花费比较多的时间去排查错误。与之相反的是,有状态流应用程序的流处理器会负责处理所有这些数据处理步骤,包括事件摄入、连续计算(中间状态维护)和结果更新。不但如此,Flink 提供 exactly-once(状态一致性)机制,可以保证程序出现异常时进行正确的恢复并调整集群计算资源,诸如 Flink 这样的流计算引擎拥有事件时间机制、高吞吐量的特性,可以很短的时间内处理海量数据,输出正确的结果。
流分析型应用有下面几种较典型的场景:
1. 实时监控移动设备的网络和流量
2. 基于移动设备的用户行为分析
3. 实时分析消费者数据
值得一提的是,虽然以上内容没有提到 Flink 的另一个功能特性,其实 Flink 也支持在流上执行 SQL 查询,通过执行 SQL 语句就可以得到与开发流处理应用程序一样的效果,在使用上更加简单,市场上已经有很多企业应用到实际的场景中了。
开源流处理的演进
其实流处理技术并非完全是新生技术,早在 20 世纪 90 年代末就已经出现有人研究这方面的模型,并且出现了商业化的产品,近些年来随着流处理技术被广泛使用,很大程度上驱动着开源流处理技术变得愈加成熟。在今天,开源的分布式流处理引擎在很多方面为不同的企业赋能,如零售行业、社交领域、移动通信、游戏行业和金融领域等方面,为什么开源技术能得到大量的使用呢?主要有两方面的原因:
1. 开源意味着免费和开放,门槛低,容易被大众接受和使用。
2. 由于开源社区的努力,很多开放者贡献了自己的代码,使得开源技术往更好、易用、高性能等好的方向快速发展,促进开源技术变得越来越成熟。
Apache 软件基金会拥有超过 12 个与流处理相关的项目,不断催生新的孵化项目成为新的开源分布式流处理引擎,以新的功能特性和自身优势向其他流处理引擎发起挑战,试图引起人们的关注,与其他流处理引擎形成良性竞争。同时,开源社区持续不断增加开源项目的功能特性和核心能力,不局限于解决单一的业务场景,逐步扩大流处理的边界,大有流批一体化的趋势,在这里我们简要回顾一下流处理技术发展的历史以及当前的形势。
历史回顾
第一代开源分布式流处理引擎出现在 2011 年,主要用于解决低延迟事件处理,达到毫秒级,并提供了容灾机制,避免在程序发生故障时出现数据丢失的情况。初期,这些系统只提供了低级 API,没有内置保证结果一致性和正确性的语义,最终的结果往往取决于事件到达的时间和顺序,而且,就算事件没有被丢失,也会出现重复计算的情况。与批处理引擎相比,第一代开源的流处理引擎牺牲了结果的精确度,换来了低延迟响应计算结果,弥补了批处理的不足,有个折中的办法就是同时进行批处理和流处理作业,既保证了结果正确性又降低了时间延迟,这也是 lambda 架构设计出现的根本原因,如图 1-7 所示:
从图中可以看到,lambda 架构的底层使用了 Speed Layer 层来解决传统周期性批处理延迟高的问题,事件日志进去 lambda 架构之后,会被同时写入批处理程序和流处理程序,此时,流处理程序可以快速计算结果并写入速度表(Speed Table)中,用于快速查询分析,而批处理程序则负责周期性处理数据得到准确的结果并存入表中,与流处理程序得到的结果进行校对,移除速度表中不准确的计算结果,最终程序对两张表的结果进行合并,这样既保证了数据的准确性又实现了低延迟。
lambda 架构虽然不是最好的架构,因为其本身的架构设计,存在着很明显的缺陷,首先需要维护两套计算逻辑,开发的时候需要用不同的 API,其次,流处理程序计算的结果会出现不准确型,相对来说,lambda 体系本身比较复杂,所以很多人不选择使用它,尽管如此,还是存在不少的应用场景使用到了 lambda 架构。
基于第一代开源分布式流处理引擎存在的问题,2013 年,第二代开源分布式流处理引擎出现了,并在第一代的基础上提供了更优秀的容错机制,更好地保证结果一致性,另外,相对于第一代提供的低级 API,第二代封装了很多高级的 API,大大丰富了 API 的类别,虽然第二代流处理引擎很多方面得到了提升,但是在时间延迟方面不升反降,时间延迟由毫秒级变为秒级,而且最终的结果还是取决于事件到达的顺序和时间。
直至 2015 年,第三代开源分布式流处理引擎才解决了计算结果取决于事件到达的顺序和时间这个问题,并成为第一个同时解决一致性计算且保证计算结果正确性的流处理引擎,不仅可以用于实时处理数据,还可以用于离线数据的计算,快速得到计算结果。不仅如此,这一代的流处理器同时满足了低延迟、高吞吐量的特性,解决了 lambda 架构的严重缺陷,lambda 架构被在逐渐被新的流处理引擎所取代。除此之外,在计算资源管理方面,第三代流处理引擎支持集成 YARN、Mesos 或者 Kubernetes 等资源管理器,可以更好的控制资源合理分配,降低资源粒度,而且还支持升级应用程序代码或将作业迁移到不同的集群以及流处理器的版本向下兼容等特性,并保证不会丢失应用程序的当前状态。
Flink 速览
Apache Flink 就是第三代流式处理引擎中的典型代表,具备很多卓越的特性,如低延迟、高吞吐量等,在这里列举 Flink 的部分优势:
1. 丰富的时间语义,支持三种时间语义,processing-time、ingest-time、event-time,其中 event-time 语义提供了一致性结算结果支持,可以处理乱序数据,而 process-time 语义适用于实时性要求非常严格的应用程序。
2. 状态一致性保证。
3. Flink 实现了毫秒级别延迟,并且能够每秒处理数百万个事件,Flink 应用程序可以扩展到在数千个 cpu core 上运行。
4. Flink 具有层次分明的 API,提供了三种不同的 API,每一种 API 在简洁性和表达力上有着不同的侧重,并且针对不同的应用场景。本书涵盖了 DataStream API 和底层 ProcessFunction,常用于流处理操作(如窗口处理和异步通信),还提供了精确控制状态和时间的接口。包括了 SQL&Table API,本书不做展开说明。
5. Flink 提供了丰富的 connector 连接器与外部存储系统连接,如 Apache Kafka、Apache Cassandra、Elasticsearch、JDBC、Kinesis、HDFS 和 S3 等存储媒介。
6. 保证 7x24 小时全天候服务,提供高可用方案并将程序托管在 YARN、Mesos 和 Kubernetes 等高效的资源管理器上,动态调控资源,提升资源利用率。
7. 能够更新应用程序代码并将作业迁移到不同的 Flink 集群中,而不会丢失应用程序的状态。
8. 细粒度监控集群各项指标,以提前做好预警处理工作。
9. 支持流批一体化。
除了以上的特性,Flink 封装了很多易用的 API 接口,这对开发人员来说是一个非常友好的框架,在开发和测试的过程中,还可以在单核 JVM 处理器中通过 IDE 工具进行调试。
运行首个 Flink 应用
接下来,我们指导你在本地集群运行你的第一个 Flink 应用程序,对随机生成的温度传感器数据进行转换和聚合操作,让你对 Flink 应用有个大概的了解。首先准备 Flink 集群运行的环境,JDK 1.8,Unix 或 Centos 系统,实在不行也可以在 window 是系统上安装虚拟机环境。
1. 下载安装包,具体可以到 Apache Flink 官网下载不同的版本,这里以 flink-1.7.1-bin-scala_2.12.tgz 为例。
2. 解压安装包
tar xvfz flink-1.7.1-bin-scala_2.12.tgz
3. 启动集群
$ cd flink-1.7.1
$ ./bin/start-cluster.sh
Starting cluster.
Starting standalonesession daemon on host xxx.
Starting taskexecutor daemon on host xxx.
4. 在浏览器输入 http:// localhost:8081,进入 flink webUI 页面,默认只有一个 slot,如图 1-8 所示
5. 下载本书示例的 JAR 文件
$ wget https://streaming-with-flink.github.io/\
examples/download/examples-scala.jar
6. 在本地集群运行样例程序
$ ./bin/flink run \
-c
io.github.streamingwithflink.chapter1.AverageSensorReadings \
examples-scala.jar
提供任务之后会出现以下提示信息:
Starting execution of program
Job has been submitted with JobID
cfde9dbe315ce162444c475a08cf93d9
7. 在 Flink webUI 点击 Running Job 可以看到提交运行的任务,点击对应的任务可以看到更多详细的指标,如图 1-9 所示。
8. 计算结果会被标准输出到默认的文件中,可以在安装目录的 log 文件夹下看到,执行下面的指令即可。
$ tail -f ./log/flink-<user>-taskexecutor-<n>-<hostname>.out
执行命令之后,就会看到下面的输出信息,包括了 SensorReading 对象的 id,时间戳,和平均温度
SensorReading(sensor_1,1547718199000,35.80018327300259)
SensorReading(sensor_6,1547718199000,15.402984393403084)
SensorReading(sensor_7,1547718199000,6.720945201171228)
SensorReading(sensor_10,1547718199000,38.101067604893444)
9. 一旦提交任务,程序就会一直运行直到任务完成,不管最后是执行成功还是执行失败,也可以通过命令或者在界面上点击 cancel 按钮取消任务。
10. 关闭集群
$ ./bin/stop-cluster.sh
以上我们完成了 Apache Flink 本地集群的安装部署,并且试着运行了第一个流应用程序,当然啦,目前为止,我们只是简单认识了 Flink,对于 Flink 来说,可能勉强算得上刚入门,关于 Apache Flink 这个框架还有非常多的内容需要我们不断去学习,这也是本书的价值所在。
总结
本章节我们介绍了 Apache Flink 的有状态流处理的架构思想和常见的应用类型,讨论了很多不同的用例;对比了传统的数据基础架构,了解现阶段很多企业在数据采集、分析场景下的技术架构选型,企业对实时性有了更高的要求,从 ETL 到微服务再到流处理引擎这样一个演变的过程;回顾流处理引擎发展的历史,明白了流处理引擎是如何一步步提升优化,最后发展为如今炙手可热的技术,为企业提供了可靠可行的解决方案,得到市场的青睐,文章最后介绍了 Apache Flink 一些突出的特性并演示了单机部署 Flink 集群和运行第一个流应用程序。
批注:Flink 支持批处理 API 和流处理 API,即 DataSet API 和 DataStream API,分别对应不同的应用场景,目前 Flink 社区正致力于实现真正的流批一体化,原理是将批处理看成流处理的一种特殊状态,把离线的数据看作有界的数据流,这样一来的话,流处理 API 同样适用于批处理。
版权声明: 本文为 InfoQ 作者【数据与智能】的原创文章。
原文链接:【http://xie.infoq.cn/article/d7dcf445e2593f3f1bad71513】。文章转载请联系作者。
评论