概念

架构

参考链接:

Client,JobManager,TaskManager

Flink 内部处理协调、网络、checkpoint,failover,API,算子,资源管理等功能的代码位于 flink-dist.jar,为了保证 Flink 核心的精简,只在 /lib 目录下存放必要的 jar,而将其他功能性的 jar 放入到 /opt/plugins 目录下。如果用户有需要将 /opt 目录下的 jar 移入 /lib/plugins 目录下即可。

另外连接三方数据源的 connectors 和 formats 不在 /lib/plugins 目录下,这样是为了避免用不到的代码存在 flink 运行环境中,需要用户在 flink 应用中按需添加。connectors 和 formats 相关代码也从 flink 仓库拆分到了独立的代码仓库。

序列化

参考链接:

异步IO

参考链接:

场景:关联维表数据

解决同步 I/O 低吞吐的 4 种解决方案:

  • 提高算子并行度。一般在 map 或者 flatmap 中关联维表数据,可通过增加并行度提高吞吐。缺点:I/O 不是 CPU 密集型工作,提高并行度没有利用好分配的 CPU 资源,存在资源浪费
  • 缓存加速。一般维表数据变化频率较低,可考虑缓存数据。将较慢的存储介质缓存在快速的存储介质中,如将 mysql 中数据缓存在 redis 甚至 state 中,缓存未命中时,查询 mysql,并更新缓存。
  • 异步 I/O。将同步 I/O 变为异步 I/O
  • 攒批处理。类似微服务中合并接口请求,也可以在 flink 中实现每攒够 20 条数据或到达 3s,批量请求维表数据。

异步处理,使用异步 I/O 时,需数据库客户端支持异步请求,如果客户端不支持异步请求,需通过线程池将同步调用转为异步调用。

顺序性。异步 I/O 返回的数据顺序是否和同步 I/O 顺序保持一致?答案是默认是乱序的,Flink 异步 I/O 提供了两种模式:

  • 有序模式。即异步 I/O 返回的数据顺序和数据处理顺序一致
  • 无序模式。

异步 I/O 与事件时间。

在无序模式下,异步 I/O 返回的数据顺序和数据输入顺序不一致,而错误的事件时间会使时间窗口产出错误的结果。那么在异步 I/O 之后应用事件时间窗口是否可行?答案是可以的。虽然是无序模式,异步 I/O 算子依然可以保证事件时间下的时间窗口计算结果正确。异步 I/O 算子通过 watermark 建立数据产出顺序的边界,相邻的两个 watermark 之间的数据可能是无序的,但是同一个 watermark 前后的数据依然是有序的。

时间语义&时间窗口

参考连接:

时间语义:

  • 事件时间。event time
  • 处理时间。process time
  • 摄入时间。ingest time

时间窗口:

  • 滚动窗口。时间计算频率和时间计算长度一致的窗口
  • 滑动窗口。时间计算频率和时间计算长度不一致的窗口,滚动窗口算是滑动窗口的一个特例
  • 会话窗口。
  • 全局窗口。

Watermark

水位线

数据会乱序,针对乱序的数据或延迟的数据,窗口该如何处理:

  • 窗口重新计算数据,修正结果。通过 allowLateNess 实现
  • 将延迟数据收集起来,另行处理。通过 sideOutPut 实现
  • 丢弃延迟数据。默认实现

乱序/延迟解决方案:watermark / allowLateNess / sideOutPut:

  • watermark。防止 数据乱序 / 指定时间内获取不到全部数据
  • allowLateNess。将窗口关闭时间延迟一段时间
  • sideOutPut。兜底操作,当指定窗口已经彻底关闭后,把接收到的延迟数据放到侧输出流,让用户决定如何处理

watermark 实际上是一个 unix ms 时间戳,表示早于该时间的数据已全部抵达,不会再有时间小于水位线的数据输入。watermark 只能增大,不能减小。

watermark 类型:

  • 周期性

状态

参考链接:

如何优化 checkpoint 过大问题,如何用 flink sql 去重