问题导读:
1、用哪些衡量指标Flink性能?
2、有哪些实时数据库查找关联
3、有哪些预加载维表关联?
4、如何进行维表变更日志关联?
上篇博客提到 Flink SQL 如何 Join 两个数据流,有读者反馈说如果不打算用 SQL 或者想自己实现底层操作,那么如何基于 DataStream API 来关联维表呢?实际上由于 Flink DataStream API 的灵活性,实现这个需求的方式是非常多样的,但是大部分用户很难在设计架构时就考虑得很全面,可能会走不少弯路。
针对于此,笔者根据工作经验以及社区资源整理了用 DataStream 实现 Join 维表的常见方式,并给每种的方式优劣和适用场景给出一点可作为参考的个人观点。
衡量指标
总体来讲,关联维表有三个基础的方式:实时数据库查找关联(Per-Record Reference Data Lookup)、预加载维表关联(Pre-Loading of Reference Data)和维表变更日志关联(Reference Data Change Stream),而根据实现上的优化可以衍生出多种关联方式,且这些优化还可以灵活组合产生不同效果(不过为了简单性这里不讨论同时应用多种优化的实现方式)。对于不同的关联方式,我们可以从以下 7 个关键指标来衡量(每个指标的得分将以 1-5 五档来表示):
实现简单性: 设计是否足够简单,易于迭代和维护。
吞吐量: 性能是否足够好。
维表数据的实时性: 维度表的更新是否可以立刻对作业可见。
数据库的负载: 是否对外部数据库造成较大的负载(负载越低分越高)。
内存资源占用: 是否需要大量内存来缓存维表数据(内存占用越少分越高)。
可拓展性: 在更大规模的数据下会不会出现瓶颈。
结果确定性: 在数据延迟或者数据重放情况下,是否可以得到一致的结果。
和大多数架构设计一样,这三类关联方式不存在绝对的好坏,更多的是针对业务场景在各指标上的权衡取舍,因此这里的得分也仅仅是针对通用场景来说。
实时数据库查找关联
实时数据库查找关联是在 DataStream API 用户函数中直接访问数据库来进行关联的方式。这种方式通常开发量最小,但一般会给数据库带来很大的压力,而且因为关联是基于 Processing Time 的,如果数据有延迟或者重放,会得到和原来不一致的数据。
同步数据库查找关联
同步实时数据库查找关联是最为简单的关联方式,只需要在一个 Map 或者 FlatMap 函数中访问数据库,处理好关联逻辑后,将结果数据输出。
2020-04-08_174742.jpg (32.69 KB, 下载次数: 0)
2020-4-8 17:37 上传
这种方式的主要优点在于实现简单、不需要额外内存且维表的更新延迟很低,然而缺点也很明显:
因为每条数据都需要请求一次数据库,给数据库造成的压力很大;
访问数据库是同步调用,导致 subtak 线程会被阻塞,影响吞吐量;
关联是基于 Processing Time 的,结果并不具有确定性;
瓶颈在数据库端,但实时计算的流量通常远大于普通数据库的设计流量,因此可拓展性比较低。
2020-04-08_174814.jpg (63.56 KB, 下载次数: 0)
2020-4-8 17:37 上传
从应用场景来说,同步数据库查找关联可以用于流量比较低的作业,但通常不是最好的选择。
异步数据库查找关联
异步数据库查找关联是通过 AsyncIO[2]来访问外部数据库的方式。利用数据库提供的异步客户端,AsyncIO 可以并发地处理多个请求,很大程度上减少了对 subtask 线程的阻塞。
因为数据库请求响应时长是不确定的,可能导致后输入的数据反而先完成计算,所以 AsyncIO 提供有序和无序两种输出模式,前者会按请求返回顺序输出数据,后者则会缓存提前完成计算的数据,并按输入顺序逐个