业务计算中,我们经常会遇到使用Flink实时计算UV的问题,比如计算一天的实时UV,或者每个小时的UV。
应为UV是需要去重的,再大数据量的情况下,如何使用Flink进行高效的UV统计呢#比如计算一天实时UV
1. windowAll+HashSet大数据量不可行,因为要缓存一天数据,OOM问题随时会发生
2. keyBy+window+MapState+配置RocksDB转态存储可行,只是因为MapState每次都需要变量才能获取到总数据量大小,效率不高
3. keyBy+window+ValueState+BloomFilter+配置RocksDB转态存储,可行,BloomFilter的加入使得计算变得高效,但是BloomFliter有误判率,不能实现100%精确,但是一般的业务场景,对于实时UV也并非要求100%精确,因此这是一个不错的选择.(这里的BloomFilter也可以使用HyperLogLog数据结构,都有误判率)
4. 将数据存储到第三方系统,比如Redis或者HBase,之后再统计计算. 在Redis中存储可用使用bitmap数据结构,空间占用小。
也可以使用HyperLogLog数据结构`(每个 HyperLogLog 键只需要花费12 KB 内存,就可以计算接近2^64个不同元素的基数)`,不能保证精确,但是比bitmap数据结构占用空间更小。