第一章:状态化流处理概述

系列文章目录

第一章 状态化流处理概述
第二章 流处理基础
第三章 Apache Flink 架构
第四章 设置Apache Flink开发环境
第五章 DataStream API(1.7版本)
第六章 基于时间和窗口的鼻子
第七章 有状态算子和应用
第八章 读写外部系统
第九章 搭建Flink运行流式应用
第十章 Flink和流式应用运维


1 传统数据处理架构

  绝大多数企业所实现的传统架构将数据处理分为两类:事务型(T型数据,Transaction)处理和分析型处理(A型数据,Analysis)。

1.1 事务型处理

  (1)什么是事务型处理?
  企业日常业务运营过程中的各类应用,如:企业资源规划(ERP)系统,客户关系管理(CRM)软件,基于Web的应用等,它们通常会设置独立的数据处理层(应用程序本身)和数据存储层(事务型数据库系统)。这类应用通常会连接外部服务或实际用户,并持续处理诸如订单、邮件、网站点击等传入的数据。期间每处理一条事件,应用都会通过执行远程数据库系统的事务来读取或更新状态。很多时候,多个应用会共享同一个数据库系统,有时还会访问相同的数据库或表。
在这里插入图片描述
  (2)事务型处理有什么弊端?
  事务型处理的设计在应用需要更新或扩容时容易出现问题。一旦多个应用基于相同的数据表示或共享架构,那么更改表模式或对数据库系统进行扩缩容必将劳心费力。
  (3)解决方案——微服务设计模式
  微服务设计模式可以解决应用之间紧耦合的情况。微服务由很多微型、完备、独立的应用组成,通过将多个微服务相互连接可以构建出更加复杂的应用,而微服务间只会通过标准化接口进行通信(如RESTful HTTP)。由于微服务彼此间严格解耦且仅通过定义良好的接口通信,所以在实现微服务的时候可以选用不同的技术栈(编程语言、库和数据存储等)。通常情况下,微服务会和所有必需的软件和服务一起打包部署到独立的容器中。
在这里插入图片描述

1.2 分析型处理

  存储于不同事务型数据库系统中的数据,可以为企业提供业务运营相关的分析见解。
例如:通过分析订单处理系统中的数据来获知销售增长率,或是通过分析运输延迟原因或预测销售量以调整库存。然而用于存储事务性数据的多个数据库系统通常都是相互隔离的,如果能将它们联合分析必然会创造更高的价值。此外,开发人员还经常需要将这些数据转换为某种通用格式。
  对于分析类查询,通常不会直接在事务型数据库上执行,而是将数据复制到一个专门用来处理分析类查询的数据仓库。为了填充数据仓库,需要将事务型数据库系统的数据拷贝过去,这个过程被称为提取-转换-加载(Extract-Transform-Load, ETL)。ETL的基本流程是:从事务型数据库中提取数据,将其转换为通用表示形式(可能包含数据验证、数据归一化、编码、去重、表模式转换等工作),最终加载到分析型数据库中。该流程可能会比较麻烦,通常需要复杂的技术方案来满足性能要求。为了保持数据仓库中的数据同步,ETL过程需要周期性的执行。
  一旦数据导入了数据仓库,便可以对它们做查询分析。通常数据仓库中的查询可以分为两类:定期报告查询、即席查询。定期报告查询可用于计算机业务相关的统计数据,如收入、用户增长、产出等,将这些指标整合成报告,能够帮助管理层评估企业整体健康状况。即席查询主要目的是通过解答特定问题来辅助关键性的商业决策,例如通过查询来整合营收数字和电台广告中的投入,以评估市场营销的有效性。无论哪一类查询,都是在数据仓库中以批处理的方式执行。
在这里插入图片描述

2 状态化流处理

  几乎所有数据都是以连续事件流的形式产生的。状态化流处理是一类面向无限事件流的应用设计模式,适用于企业IT基础设施中的很多应用场景。
  任何一个处理事件流的应用,如果要支持跨多条记录的转换操作,都必须是有状态的,即能够存储和访问中间结果。应用收到事件后可以执行包括读写状态在内的任意计算。原则上,需要在应用中访问的状态有多种可选的存储位置,例如:程序变量、本地文件、嵌入式或外部数据库等。
  Apache Flink会将应用状态存储在本地内存或嵌入式数据库中。由于采用的是分布式架构,Flink需要对本地状态予以保护,以避免因应用或机器故障导致数据丢失。为了实现该特性,Flink会定期将应用状态的一致性检查点写入远程持久化存储。
在这里插入图片描述
  有状态的流处理应用通常会从事件日志中读取事件记录。事件日志负责存储事件并将其分布式化。由于事件只能以追加的形式写入持久化日志中,所以其顺序无法在后期改变。发入事件日志的数据流可以被相同或不同的消费者重复读取。利益于日志的追加特性,无论向消费者发布几次,事件的顺序都能保持一致。
  将运行在Flink之上的有状态的流处理应用和事件日志系统相连会很有意义。在该架构下,事件日志系统可以持久化输入事件并以确定的顺序将其重放。一旦出现故障,Flink会利用之前的检查点恢复状态并重置事件日志的读取位置,以此来使用有状态的流处理应用恢复正常。随后应用会从事件中读取并(快速)重放输入事件,直到追赶上数据流当前的进度。
  三类常见的有状态的流处理应用:事件驱动型应用;数据管道应用;数据分析应用。事实上,大多数真实应用都会同时具有多种类别的特性。

2.1 事件驱动型应用

  事件驱动型应用是一类通过接收事件流触发特定应用业务逻辑的有状态的流式应用。根据业务逻辑的不同,此类应用可支持触发报警或发送电子邮件之类的操作,也可支持将事件写入输出流以供其他同类应用消费使用。
  事件驱动型应用的典型应用场景有:实时推荐、模式识别或复杂事件处理、异常检测。
  事件驱动型应用本质上是微服务的演变。微服务通过REST调用进行通信,利用事务型数据库或键值存储外部系统存储数据;事件驱动型应用利用事件日志进行通信,其数据则会以本地状态形式存储。
  事件驱动型应用有很多优势:①访问本地状态的性能要比读写远程数据存储系统更好;②伸缩和容错由流处理引擎完成;③以事件日志作为应用的输入,不但完整可靠,而且还支持精准的数据重放;④Flink可以将应用状态重置到之前的某个检查点,从而允许应用在不丢失状态的前提下更新或扩缩容。
  API的表达能力,以及对状态处理和事件时间的支持水平等诸多因素决定了我们可以执行的业务逻辑,这取决于流处理引擎的API、提供的状态原语,以及对事件时间的处理能力。系统要提供精确一次的状态一致性和针对应用的可伸缩能力。

2.2 数据管道

  目前架构中数据可能在不同的数据库中存在多个整本,如关系型或专用数据库系统、事件日志系统、分布式文件系统、内存缓存及搜索索引等,这些存储系统之间需要保持同步。
  不同存储系统间同步数据的方式有两种:其一,定期执行ETL作业,但这对很多应用场景而言根本无法满足延迟方面的需求。其二,使用事件日志系统来分发更新,将更新写入事件日志系统,并由它进行分发:日志的消费方会将这些更新整合到相关数据存储系统中,根据用例的不同,转存的数据可能需要归一化,利用外部输入丰富数据或在写入目标存储之前进行数据聚合。
  另一个日常用例是以低延迟的方式获取、转换并插入数据,此类应用称为数据管道。它需要在短时间内处理大批量数量,执行数据管道应用的流处理引擎为了支持不同外部系统的数据读写,还需要提供多样化的数据源、数据汇连接器

2.3 流式分析

  ELT作业周期性数据导入是批处理,会给分析流程带来相当大的延迟。数据管道虽然在某种程度上可以降低延迟,并且当今的应用对这种延迟是不能接受的。
  流式分析应用不再需要等待周期性地触发,它会持续获取事件流,以极低的延迟整合最新结果。通常情况下,流式应用会把它们的结果保存在某种支持高效更新的外部数据存储中,例如数据库或键值存储。
  流式分析应用的优势有:①将事件整合到分析结果的用时更短;②流处理引擎会全面负责事件的获取、维护状态的持续计算以及更新结果等所有处理步骤,还不需要很多独立组件;③能以精确一次的状态一致性进行故障恢复,调节应用计算资源。
  Flink还支持事件时间的处理,从而可以生成精准、确定的结果,并具备在短时间内处理大量数据的能力。
  流式分析应用常用于:

  • 手机网络质量监控
  • 移动应用中的用户行为分析
  • 消费者技术中的实时数据即席分析

3 开源流处理的演变

  开源分布式流处理引擎已经支撑起包括(在线)零售、社交媒体、移动通信、游戏、银行等很多不同行业的核心业务应用。
  第一代开源分布式流处理引擎(2011年)①专注于以毫秒级延迟处理数据并保证系统故障时事件不会丢失;②API非常底层,而且并未针对流式应用结果的准确性和一致性提供内置保障,其结果完全取决于事件到达的时间和顺序;③虽然数据在出错时不会丢失,但可能会被处理很多次。④和批处理引擎相比,它通过牺牲结果的准确度来换取低延迟,毕竟当时任务计算快速和结果准确二者不可兼得。
  第二代引擎(2013年)①提供了更加完善的故障处理机制,即便出现故障,它们也能保证每条记录仅参与一次结果运算;编程API从底层基于算子的接口进化为拥有更多内置操作原语的高层API;它的部分改进(如更高的吞吐和更完善的故障处理保障)是以增加处理延迟(从毫秒到秒级)为代价的,处理结果仍然依赖于事件到来的时间和顺序。
  第三代分布式流处理引擎(2015年)①解决了结果对事件到来时间及顺序依赖问题;②具有精确一次的故障恢复主义,是第一批能够计算精确一致结果的开源处理引擎;③只需要依靠实际数据计算结果,可以将历史数据当作“实时”数据进行处理;④可以兼顾延迟和吞吐。
  以上讨论的只是容错、性能及结果精确性等系统属性。新的操作功能还有:高可用设置,和资源管理框架的紧密集成,支持流式应用动态扩缩容,支持应用代码更新,在不丢失当前状态的前提下将作业迁移至一个新的集群或新版本的流处理引擎等。

Guess you like

Origin blog.csdn.net/PAN_Andy/article/details/110884802