Flink 基本原理与生产实践分享【入门必读,概念清晰】
https://zh.wikipedia.org/zh-hans/Apache_Flink
Apache Flink是由Apache软件基金会开发的开源流处理框架,其核心是用Java和Scala编写的分布式流数据流引擎。Flink以数据并行和流水线方式执行任意流数据程序,Flink的流水线运行时系统可以执行批处理和流处理程序。此外,Flink的运行时本身也支持迭代算法的执行。
Flink提供高吞吐量、低延迟的流数据引擎以及对事件-时间处理和状态管理的支持。Flink应用程序在发生机器故障时具有容错能力,并且支持exactly-once语义。程序可以用Java、Scala、Python和SQL等语言编写,并自动编译和优化到在集群或云环境中运行的数据流程序。
Flink并不提供自己的数据存储系统,但为Amazon Kinesis、Apache Kafka、HDFS、Apache Cassandra和ElasticSearch等系统提供了数据源和接收器。
概述
Apache Flink的数据流编程模型在有限和无限数据集上提供单次事件(event-at-a-time)处理。在基础层面,Flink程序由流和转换组成。 “从概念上讲,流是一种(可能永无止境的)数据流记录,转换是一种将一个或多个流作为输入并因此产生一个或多个输出流的操作”。
Apache Flink包括两个核心API:用于有界或无界数据流的数据流API和用于有界数据集的数据集API。Flink还提供了一个表API,它是一种类似SQL的表达式语言,用于关系流和批处理,可以很容易地嵌入到Flink的数据流和数据集API中。Flink支持的最高级语言是SQL,它在语义上类似于表API,并将程序表示为SQL查询表达式。
编程模型和分布式运行时
Flink程序在执行后被映射到流数据流,每个Flink数据流以一个或多个源(数据输入,例如消息队列或文件系统)开始,并以一个或多个接收器(数据输出,如消息队列、文件系统或数据库等)结束。Flink可以对流执行任意数量的变换,这些流可以被编排为有向无环数据流图,允许应用程序分支和合并数据流。
Flink提供现成的源和接收连接器,包括Apache Kafka、Amazon Kinesis、HDFS和Apache Cassandra等。
Flink程序可以作为集群内的分布式系统运行,也可以以独立模式或在YARN、Mesos、基于Docker的环境和其他资源管理框架下进行部署。
状态:检查点、保存点和容错
Apache Flink具有一种基于分布式检查点的轻量级容错机制。检查点是应用程序状态和源流中位置的自动异步快照。在发生故障的情况下,启用了检查点的Flink程序将在恢复时从上一个完成的检查点恢复处理,确保Flink在应用程序中保持一次性(exactly-once)状态语义。检查点机制暴露应用程序代码的接口,以便将外部系统包括在检查点机制中(如打开和提交数据库系统的事务)。
Flink还包括一种名为保存点的机制,它是一种手动触发的检查点。用户可以生成保存点,停止正在运行的Flink程序,然后从流中的相同应用程序状态和位置恢复程序。 保存点可以在不丢失应用程序状态的情况下对Flink程序或Flink群集进行更新。从Flink 1.2开始,保存点还允许以不同的并行性重新启动应用程序,这使得用户可以适应不断变化的工作负载。
-------------------------------------------
下面是小象学院的公开课,原始地址在:http://www.chinahadoop.cn/course/1102
下面是我以前的听课笔记,花了很多时间自己一个字一个字敲出来的,想想还是分享给大家看看,这样其他人就不用按暂停来写听课笔记了。
原讲座时间:2018.1.29 作者:罗江宇
实时计算的一些基本概念
有界数据:在离线层面很常见,读文件最终会结束就是有界。
实时计算用有界数据计算无界数据,比如几分钟的。实时计算就是处理无界数据的。
事件时间:事件产生的时间,一条日志产生的时间
处理时间:实时计算处理时候的时间。
窗口:最近一分钟或者几分钟的数据进行切割聚合,窗口就是切分有界数据。
水位线:水位线以下的事件已经到齐就是一个标准。
触发器:很多情况就是和窗口结合,触发窗口里的数据计算
转换:也称算子。
at-most-once:数据计算至多一次,会丢数据,很少用。
at-lease-once:最少处理一次,数据传输计算肯能会重复计算,有数据重复的情况
at-exactly-once:整一次,会有性能损失。
blink:SQL 方面做了很多改进,还有就是onyarn做了很多改进。
自己公司是Flink千万级每秒
其他引擎是用微批 ,10秒或者1秒一批,就会影响延迟。
用系统时间计算窗口会丢失一些时间,用eventtime就不会丢。
状态:机器宕机,可以恢复。一个有状态的算。
storm:因为进程挂掉,导致状态丢失。storm已经没人用了,jstorm只是在其上做一些优化。
支持者at-least-once.
从kafka消费一个数据,再写到kafka。管理应用有很多为问题,稳定性也有问题,比如进程挂了。
一进来数据就是微批做了切割。低延迟很难达到。ss2.2做了一个融合离线和实时写法一样。也会支持全流式。
部署:local IDE底下做一些测试;
cluster:standalone:利用率比较低。
onyarn:提高机器利用率。
datastreamAPI:流式处理的API
datasetAPI:批量处理,是通过流式处理做批处理。
用flink还是流失的多。
CEP:复杂事件处理。有做用户行为分析,实时分控,提高分控吞吐量,业界有些吞吐量不行。
SQL+CEP和动态CEP,因为用户写代码很复杂。
要先有数据构建一个数据流,一开始上面代码还少了一块要构建流失环境变量。选择是dataset还是datastream.
source:数据源,从kafka读。读完后做一些转化。这里Map这个算子就是1对1的概念。
10秒聚合统计这个id的次数。
整体是来一条数据就流下去,象工厂的流水线一样。
并行度:多少个线程去跑。
数据切割,一个算子
timewindow:按时间切割,等时间的。这个实际用的最多。
Count :按事件的个数。
滚动window:时间是对齐的。适合做BI类似的东西。
固定长度:两个窗口之间无交集数据。一个数据不会同时属于2个window..可以有时间的也可可以有count的。
移动窗口,适合求比如最近5分钟的。也可以做一些监控这些事情。
不支持countWindow,只支持timewindow。
<sesion gap的就可以聚合在一起,认为是一个seeeion,适合线上行为分析。在这个session时间内做了哪些事情。
sesion gap设置太大就不合理,因为都聚合在一起了。
3种时间,
eventtime:事件产生的时间,这个一般用的比较多。
ingestion:进入flink的时间(进入souce的时间),
processingtime:某个算子开始处理的时间(window)
window和eventtime结合起来做事情。
水印:数据处理到那个位置了。水印到了说明之前的数据已经到齐了。
数据没有到齐,都存起来先。一些中间状态。
不要做持久化,只要做配置就会被Flink托管。机器挂了,进程结束都可以根据这些状态恢复。
operatorstate:算子的状态
keyedstate:存hash的key
checkpoint:把状态做一些容错。以前的流式计算为了计算一个state,所有的算子都要停止,获取一个快照,记录下状态。相当于全局同步。Flink是全局异步,只有某个标志到了,会把这个状态做一个快照。
exavtly-once:假如需要依赖外部的东西需要三方都保证。不光是flink保证,还要souce好sink都要保证。
原理是数据源加一个标志barriers,以这个算子为例所有的barriers都到齐了就会做一个快照。数据源会定时发送barriers进来,就是一个要做快照的标志。
checkpoint主要做内部失败,从最近的一个成功的checkpoint恢复。
生成t1就会删除t0,会fork一个版本出来。从t3时刻做了一次恢复从这个点进行一次回溯的计算。
主要是作为外部恢复,原来需要的资源不够,需要把资源改大一点,需要重启。
目前官方的需要通过命令去做还没有一套好的API让用户直接调用java代码或者scala代码,目前的savepoint还不是很好用。
运行时架构分为三个角色:client,jobmanager,taskmanager.
先生成一个图,通过AKKA把“”图“”发给jobmanager(看成一个master,做协调和分发的概念)
jobmanager两个比较重要的功能:一个是调度,这个节点分配到那个taskmanager.
二是checkpoint的协调器,checkpoint官方也说了是定时注入到source数据源。
taskmanager:真正干事情的,它有task槽的概念。
task槽实际上就是对taskmanager资源的分割。task是跑在task槽上真正在执行任务。
taskmanager也会汇报心跳做一些统计。
taskmanager可以看做一个进程。把内存和CPU分割为3部分。虚线表示一个task,可以看成一个线程。
做一个chain:source和map 这2个算子泡在一个subtask上,这2个是可以串一起。这种是可以做一些优化。
具体组成operatorChain有7个条件。
operator:一些算子
task:真正运行的,就是几个operator组成一个chain运行在一个task上。
ETL:数据清洗。
数据埋点agent。怎么清洗任务下发给flinkETL。
大应用好管理,也有风险大的topic,某一台机器一挂影响所有ETL。
小应用每个ETL是隔离不影响,管理成本又增大了,要做监控,只会影响某一个ETL。
实际经验还是用小应用。
计算规则中心下发给Flink,Flink做一个聚合到es或者druid。druid做一个OLAP引擎,做一些预聚合。再落到dashboard做一个实时的BI和告警。ES:日志检索的。
这里有个问题就是数据是先在flink聚合再到druid还是只是flink做个ETL,聚合在druid里做,因为他有预聚合。
实际生产下要做个权衡,如果flink不够强大的话,那么只做个ETL。因为window聚合有些状态管理比较消耗资源。
或者可以在flink做1分钟的基本单元的聚合然后再到druid做10分钟的很大的聚合进行累加也是比较常见的,相当于只做一个基本单元的聚合。因为流式处理window比较大是不可以的,会有内存过大导致各自问题。
CEP只能静态不能动态加载CEP实时生效。可以做一些匹配告警这种。
实时机器学习做一些推荐,相对CEP还不是很成熟。
source扩大并行度能不能起到作用,有些扩大了没用。
遇到很多自己写一些状态,不符合flink托管的状态,实际开发中要考虑状态问题。
异常一捕获就会丢失数据。不捕获又不好。需要权衡。
在一定延迟范围业务方可以接受多少延迟,用多少并行度去处理。
追数据能力:机器宕机,从上一个checkpoint去恢复数据。官方说追数据能力3-5倍(正常数据量的3-5倍)以上。数据完整性和数据延迟。否则如果数据很大需要去掉checkpoint,直接从kafka消费数据开始计算。所以追数据能力不行要做一个权衡。
从运维角度。
如果用户说丢数据,需要有可以反驳用户。也可能是发送方延迟,构筑一个简单的数据质量体系告诉用户。
flinkUI上的度量比较简单,需要自己构建收集flink的度量。
flink的日志在大规模生产有问题,日志比较多会把flinkUI 搞挂,需要构建flink日志的滚动。还有用户会去看。
要做一些flink平台服务化,应用监控的质量体系。
稳定性保证:纯流式的,还有很多问题,很多都是某一个组件抖动,为了保证一致性会有一些问题。
构建SQL平台:SQL给用户直接写SQL。
学习流式计算作为一个函数式编程语言需要scala,面试必须。
Flink核心的通讯是AKKA也就是scala写的。
paper:论文。
源码上的接口上有注释,官方文档毕竟不完善。