1 为什么使用flink?
因为flink是针对实时数据的流式处理计算引擎,能做到实时的,来一条就处理一条数据。
2.flink如何接入一个数据流?
通过flink source 接入,flink本身有内嵌的丰富的connector供使用,也可以通过addSource来自定义接入的数据源
3.flink接入数据流后,如何处理的?
flink可以根据数据流进行流式处理,即dataStream
也可以进行批处理,即将一段流作为一批数据来处理 batchDataStream
也可以将数据抽象为一个 逻辑表 使用sql来处理数据
4.flink处理完数据后,怎么存储数据?
flink 通过sink将数据最终处理,可以打印到终端,也可以存储在外部文件系统,其内置了很多connector来处理,也可以通过addSource来自定义处理
5.flink算子在处理数据时,如果需要接入第三方数据协助处理,怎么做?
flink在处理数据时,尤其是流式数据时,有时需要接入第三方数据来验证或者补全当前的数据,例如根据id向第三方获取对应的数据全文,此时就需要在map算子中传入自定义的,implements RichMapFunction 来处理,类中的方法 open invoke close 来处理整个map算子的声明周期,可以在open中定义初始化外部连接,例如sql数据库,httpclient 等,在invoke中使用连接获取外部数据,用于处理当前的数据。
6.flink算子再做聚合操作时,例如单词计数,它如何处理每次的计算后中间结果给下次处理数据时使用?
算子必定是将中间结果通过缓存暂存起来了,也就是状态 state,一般的算子都是默认自动管理状态,也可以传入自定义类,implements MapFunction RichMapFunction 等来手动处理state,即在open中通过context 传入 stateDescriptor 来获取state和初始化state,在invoke中获取state的值用以协助处理当前数据,以及更新值用以下次使用。
另外state本身还可以设置过期时间ttl。
7.算子的state都可以保存什么类型的数据?
可以保存单值 valueState,可以列表 listState,还有mapState。
state可以存在内存中,也可以通过RocksDB存在磁盘,也可以自定义存在外部文件系统,例如hdfs。
8.flink运行时的架构?
可以单独部署集权 standalone 也可以委托给yarn 或者 k8做管理;flink 提交任务后 由jobManager 管理 由 taskManager 执行具体的任务
9.flink在收到一部分数据后才对这一批的数据进行处理,flink是怎么设计的?
flink设计了一个 window的概念,window中暂存收到的数据,当满足条件时,开始处理window内的数据
10.处理window内数据的条件是什么?
实际情况是数据不断流入,是时间相关的,所以可以在流入持续一段时间的情况下,处理window内的数据,所以条件就是时间,或者是流入的数据个数。
11.window的时间条件具体都有什么场景?
数据流入一段时间后,就处理该段时间,即该window内的数据,流入时间为window的时长接着继续处理下一段时间内的数据,即下一个window内的数据。
可以将window的时长看为固定不动的,window时长是绝对时长,即固定的时间长度,而数据流入是相对的;
最简单的场景为,每次流入固定数量的数据,window就处理一次,此时需要设置window处理数据的个数;
一个简单的场景为,每次流入window时长的数据流,就处理一次,此时只需要设置一个参数,即window的时长;
复杂的场景为,流入的数据时长小于window时长,所以在处理window内的数据时,还会留有上一个window的部分数据,此时需要设置两个参数,即window时长和流入数据的时长,官方叫做滑动时长;
还有一个场景为,一次性处理流入时长的场景,即预设数据只会持续流入一段时间,在之后就只有很少或者没有数据了,相当于和数据源做一了一次会话获取数据,当一段时间内没有数据流入了就会关闭会话,此时会一次性处理会话内的所有数据,即window时长是根据会话时间而确定的。
window之后的数据相当于被分批处理了,所以window之后的配合算子就是聚合类算子,目的就是每个window会将多个数据重新聚合为一个数据。
12.数据流入时间是怎么确定的?
有两种方式确定,第一种即最简单的易懂的,即为输入到flink任务为数据的时间,即为process time;
另一种是数据实际被生产出来的时间,这个时间就需要生产时就把时间戳放入数据之内,在流入flink任务时,用次时间作为流入的时间。
一般情况下,数据本身既没有生产的时间戳,同时实时计算也没有对数据的时间顺序有依赖,则可以使用第一种时间模式,即process time。
另一种情况,即计算的结果对数据生产的顺序有高度依赖的,这种场景是对某个实体的属性反复操作,例如 关注 取关 再关注等,很像多线程对于边界资源的操作的例子。
13.确定数据时间后,怎么根据时间来处理?
即第二个场景,数据本身有时间戳可以确定数据的生产时间,那么数据流等于依据数据本身的生产时间重新排序再进入window处理,所以数据流入顺序和window处理是不相关的,window还是按照它自身的规则处理数据流,而数据流的重排序只是改变了输入window的数据流;
但是数据的重排并不是整个数据流的每个数据的重新排序,因为数据流默认是无限的,只能在局部重排,即将数据流分割为一段一段的数据块,数据块之间是有序的,数据块即为一个时间段,例如 【10:00-10:15) 【10:15-10:20)是两个时间块,注意是左闭右开的区间;
但是从时间角度来说,数据流不是连续的,所以数据块也不能是连续的,只能根据实时数据来确定数据块,例如将某个数据的时间戳设置为数据块的左边,再设置一个数据块时长,后续的数据凡是符合该区间的就可以进入该数据块,而且由于整体来说,数据流是根据时间单增的,所以可以继续简化为,设置一个数据块结束时间点即可,即凡是早于该时间点的,则计入该数据块,向后继续被处理,所以这个时间点在flink中就叫做water mark 水位线,即形象的比喻为,超过水位线的水会被排出去等待被处理掉。
14.水位线是什么确定的?
水位线初始时是Long.MIN_VALUE,然后根据某个后来的数据的时间戳设置为新的wm,代码中还需要 - 1,即处理为开区间;
当第一个时间戳的数据超过大于该wm到达时,就根据该时间戳重新设置为wm,注意还需要 - 1;
15.水位线wm和window放在一起使用具体是什么情况?
其实水位线wm和window关系不大,水位线只是将数据流重排,window只是处理重排之后的数据流;
当重排后的数据流符合window的处理条件,则触发window处理,如果和wm联系在一起,则表现为wm超过window_end时会触发。
16.如果有的数据迟到了怎么处理?
当符合某个数据块的数据在该数据块已经处理后再发到任务中,可以设置wm策略加上时间容忍度例如2秒,即延迟2秒(注意这里是event time)后到的,被在wm之内的数据还是可以被归到之前的window再处理一次;
可以丢弃处理,也可以用侧流保存下来另外处理。
17.如果任务处理中程序出错了等导致任务中止了咋办?
flink进行实时计算相当于一个持续性的任务,类似一个服务,如果宕机了,就需要拉起来继续跑任务,此时就面临一个问题,即以前的计算结果保存在内存中的话,就会被丢掉,相当于这部分的计算要重新开始,这就浪费资源了,所以最好能把中间结果存储在state中,再存第三方存储系统上,例如 hdfs 上;当任务被重新拉起的时候,就从第三方存储系统上拉取数据恢复到之前的计算状态,这就是checkpoint 和 savepoint。
18.当通过chk重新拉起任务,那外部的数据流从哪里开始继续推送?或者说外部如何配合chk重新拉取数据流?
一般类似于kafka source是flink任务主动拉取数据,当flink任务宕机,则kafka的消息没有被消费而是等待中
19.不针对每个数据单次处理,而是想把数据流分组之后再进行处理怎么做?
可以对source 进行 keyBy,即通过指定的数据中的key将数据先分组再进行后续处理,其实分组后的也有需要专门处理对应的state和chk
20.如果map flatmap等算子不能满足计算需要时怎么办?
使用最底层的process,process与其他算子不同的地方在于它提供了声明周期管理,任务上下文引用(RichMapfunction等也是),还提供了定时器等更多的工具
21.在实时计算中,针对flink配合使用的source最多是kafka,为什么?
其实kafka虽然是一个消息中间件,但是可以把他看作一个高吞吐低延迟的数据库,而且写入和读取数据时都可以带上ack来保证数据精确消费一次,并且每次成功消费都会记录消息数据被消费的位置,叫做 offset ,如果消费者停止消费数据后,重新来消费可以根据offset来继续消费消息。
同时kafka提供事务机制,保证写入一批消息时要么全都成功,要么都失败回滚。
这些都配合flink实现 exactly once 的语义。
22.kafka如何实现高吞吐低延迟?
磁盘顺序读写,速度超过内存;topic分区,将数据的存储在分区中,通过索引查找,提高查找效率。
同时生产者和消费者都可以指定分区。
kafka集群还可以将分区备份到其他节点broker上,其实就是集群高可用加选举。
分区只能加不能减,增加后会重新调整存储分布。
kafka支持异步向其发送数据。
23.处理编程使用算子,还有什么更通用易用的方式来实时处理数据么?
有的,SQL语言是一种语义明确更贴近人理解且更通用的语言,flink也整合了sql的使用,类似一种dsl,而此时flink也从 dataStream 数据流更抽象了一层,即Table,将输入的数据抽象为一个动态表,可以对这个动态表使用sql进行数据的查询;
同时动态表的数据也可以通过sql查询之后的结果输出到sink;
24.使用table sql 与其他方式有什么不同吗?
既然是构建table,那么和使用mysql这种关系型数据库一样,需要指定表字段,即Schema,然后将收到的数据映射到字段上;
同时使用sql构建table时,可以方便的指定connector,即数据源,例如 kafka;
构建table时,需要给table命名,在同一个任务中,即session中,可以根据tableName再次获取此table实例;
25.flink table 有临时表吗?
一般创建的flink table可以在某时刻生成一个临时表,即为当前动态表的快照,这个表的数据是不会变的。
26.flink table 与 一般的数据库表有什么区别?
flinktable 实际上是动态表,因为数据是不断的流入的,在具体表现上,是随时间不断的对旧数据进行更新的,所以表现更新的方式有两种,一种是撤回式的,即更新了旧数据(“+”加号),那么旧数据就会表标记撤回(“-” 减号);另一种就是 直接插入新的,覆盖旧的数据;
另外一般的表是与数据库相关的,但是flinktable的层级关系是 table database catalog;
27.flink table创建后只能使用table api么?
flink table 底层是 dataStream,他们可以互相转换的;
28.flink table是否和 dataStream一样,也有很多connector?
是的 flink table 也可以由 文件系统,kafka,jdbc等读写数据,并且可以调用api设置,也可以在sql语句中书写。
29.在mysql中可以使用多种自定义函数,flink table支持么?
支持的,可以自定义针对单个字段值的转换,一进一出 (scalarFunction);
也有聚合函数,即将多条数据聚合为一个结果输出 ,例如计算平均数场景,多进一出(aggregateFunction)
也有多进多出,例如将一行数据拆分多行 (tableFunction)
30.flink table 本质也是数据流,那么是否可以将其每隔一段时间,数量处理,甚至排序?
flink table 也可以结合 window使用,当然,需要定义使用 procee time 还是 event time,window 的定义模式和之前一样,即 窗口时长,滑动时长等;
同时也可以加上 wm 来排序,即指定某个字段为wm;
31.很多业务数据实际上存储在数据库中,可能会实时的变化,主要是insert 和 update,有没有什么便捷的方式实时获取数据库的增量变化数据?
有的,例如阿里开源的 Canal,是一个单独部署的服务,支持直接从数据库中获取实时增量变化数据,并写入到kafka等消息中间件或者tcp端口;
另外,flink 也有CDC (Change Data Capture)的客户端项目,即将数据库端的变化数据直接读取为dataStream进行处理。
32.clickhouse出现和适用的场景?
ch的场景其实是替代flinkSQL sparkSQL的,将数据流抽象为数据表,并根据流的特点,使用时间轴的方式来读写数据,具体使用方式作为 flink的source 或者 sink。
33.为什么ch 需要 cow(copy on write) 和 (merge on read) 两种模式?
因为其希望达到高吞吐量,所以底层将数据分区并建立索引,
将数据存储为小块文件,有利于查询数据;
或将数据存储为一整个文件,有利于写数据;
那么对多个小文件的读写可以分为两种方式,即偏向读性能的,即cow模式,即写时创建属于写会话的copy,不会干扰其他读原数据的操作;
以及更偏向读性能的 mor 模式,即读多个小文件合并为查询结果,但是写的时候需要向一个或者多个小文件写数据。
34.ch作为一个轻量级客户端框架,将数据存储在哪里?以什么形式?
ch有多种底层的存储数据格式和组织方式,在ch中称为engine的概念,简单的有将数据存在内存或者本地文件中,也有存于hdfs或者mysql中的;
也有针对表级别的engine 例如 mergeEngine,既然是mergeEngin 即倾向于 多个小文件的,分区的,索引的存储方式,整个结构有利于查询。
35.flink window
流式转批式处理数据的底层模型,即窗口作为一个批次来计算。
36.exactly once 仅一次语义
指的是数据既不会错过处理,也不会重复处理,而是确定能够被处理一次;
想要实现这样的语义,很像数据库事务,即为二段提交和回滚;
在flink实时处理数据的项目中,分为 source operator sink 三种组件,代表三个操作阶段,每个阶段都会向后输出数据,
且接受上一个阶段的输入,那么其实这三个阶段都需要事务的能力;
外部服务与source:
二段提交:kafka与source的akc机制;
回滚重放:kafka与source之间根据offsetId实现数据重放;
source与operator:
二段提交:operator接受数据时缓存至state然后checkpoint到三方服务;
回滚重放:从三方服务种重新回去checkpoint恢复state;
operator与sink:
二段提交:
sink时数据缓存至state并checkpoint到三方服务,checkpoint前预提交到kafka(kafka事务机制支持);
隔离级别 isolation-level:
read-commited:此时预提交到kafka种的数据对外不可见,checkpoint成功后确认提交到kafka;
read-uncommited:预写入的数据会被实时消费;
MySql的事务提交 或 WAL 写入操作日志后再提交;
回滚重放:从三方服务中重新回去checkpoint恢复state;
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。