Flink双流Join数据重复问题如何解决?
-
使用 Interval Join
左流和右流会在 interval 时间之内相互等待,如果等到了则输出数据;
如果等不到,并且另一条流的时间已经推进到当前这条数据在也不可能 join 到另一条流的数据时,则直接输出。
-
下游进行数据去重
一、利用状态去重
计算每个广告每小时的点击用户数,广告点击日志包含:广告位ID、用户设备ID、点击时间。(1)实现步骤:
-
为了当天的数据可重现,这里选择事件时间也就是广告点击时间作为每小时的窗口期划分
-
数据分组使用广告位ID+点击事件所属的小时
-
选择processFunction来实现,一个状态用来保存数据、另外一个状态用来保存对应的数据量
-
计算完成之后的数据清理,按照时间进度注册定时器清理
二、利用Flink Sql进行去重
三、利用HyperLogLog进行去重(或者布隆过滤器,Flink-sql注册udaf函数)
关于HyperLogLog算法原理可以参考:https://www.jianshu.com/p/55defda6dcd2
四、利用HyperLogLog进行去重(优化版本)
在HyperLogLog去重实现中,如果要求误差在0.001以内,那么就需要1048576个int,
也就是会消耗4M的存储空间,但是在实际使用中有很多的维度的统计是达不到这个数据量,那么可以在这里做一个优化
优化方式是:初始HyperLogLog内部使用存储是一个set集合,当set大小达到了指定大小(1048576)就转换为HyperLogLog存储方式。这种方式可以有效减小内存消耗。五、利用BitMap精确去重进行去重
在前面提到的精确去重方案都是会保存全量的数据,但是这种方式是以牺牲存储为代价的,
而hyperloglog方式虽然减少了存储但是损失了精度,
那么如何能够做到精确去重又能不消耗太多的存储呢,可以使用bitmap做精确去重。六、利用布隆过滤器进行去重
-