Contents

随着2019年8月份,Flink1.9.0正式发布,Flink并入Blink代码,开始同时支持批和流的处理,于此同时,批量同时处理所遇到的问题也就产生了

首先我们要知道,什么是批,什么是流,批好比一瓶水,我们看到到它在那里,流就像雨水,我们只能看着它慢慢的从天上掉下来,什么时候掉完我们不知道

批处理解决我们非常好理解,分而治之即可,然而对于流数据的解决该如何呢,当然也是分而治之,但是我们分的是时间,所以对于流数据最重要的第一是不能让历史数据沉淀下来

我们回到现实中,理想状态我们处理数据总希望数据全部都能获取到,由于数据库三范式的存在,我们的数据不是完整的,比如消费记录只会存一个id代表用户,而我们希望统计用户记录的年龄分布就不能只通过记录表来实现

所以我们第一个挑战就是Join,把多个维度表汇集到一起,什么是Join呢,就是把不同的表进行分组,我们这里就不讨论大表和大表的Join,因为这个不是Flink的强项,对于这个来说,我只能说MapReduce欢迎您。

我们就讨论一种情况,大表处理表,小表配置表,因为这代表实际大数据处理的中最常见的情况,由于Flink的批流一致的支持,我们现在处理Join有两张情况

第一种是批流进行Join,第二种是流和流(双流)Join,当然由于Flink底层其实把批看做一种特殊的流(无后续增加),我们也可以看成一种

对于批和流的Join,Flink的优化是将批变成State,这样流只需要进行内存匹配而不需要每次进行Join的时候在读取一遍批处理数据,这个方式来说最简单,但是也有一个问题,我们的配置表变成的“一次性”的了,假如我们想更新配置表,但是流计算察觉不到变化也就实现不了一个动态的更新

接下来我们在看看流和流的Join,对于最简单的双流Join来说,为了维持流数据的更新,必须存贮两个流的所以历史数据,对于小表来说存储耗费不了内存,但是大表来说就不一样的,所以双流Join不适合大表和小表的Join,但是统计的话可以,Flink针对一些东西做了优化不会存储所以历史数据,只保留一个统计State,会根据更新动态来修改,那么大表和小表就没法实现双流Join了吗

当然不是,我们想想为什么大表小表会保留历史数据才能维持结果正确,我们思考一个例子,我们有很多不同种类的商品,然后我们有一个本子记录客人想买的商品(实时更新),为了做到正确匹配客人像要的商品,我们必须记住我们所以种类的商品,当有个客人想买的时候才能匹配上,假如你忘了你们有什么匹配的商品,那么这个客人就买不到了,因为匹配不上

这种情况是必须要记住所以种类的,但是我们大部分情况是这样的,我们的大表里面记录了系统某个指标,我们的配置表里面保存了我们想监听的指标,当我们更新我们的配置表的时候代表从这个时刻起我们对某个指标感兴趣,对于历史的数据我们其实是不感兴趣的,所以,你完全可以“忘掉”原来的大表历史数据,Flink对于这个功能使用了Temporal Join来支持

例如:

select * from source a, lateral table (ConfigTable(a.protime)) b
where a.id = b.id;

我们只要注册ConfigTable到一个流表上就代表告诉Flink历史数据可以不用记住了,我只关心现在的最新配置能不能匹配上,这样就解决了对大表的时间分片

Contents