業(yè)務計算中,我們經(jīng)常會遇到使用Flink實時計算UV的問題,比如計算一天的實時UV,或者每個小時的UV。
應為UV是需要去重的,再大數(shù)據(jù)量的情況下,如何使用Flink進行高效的UV統(tǒng)計呢#比如計算一天實時UV
1. windowAll+HashSet大數(shù)據(jù)量不可行,因為要緩存一天數(shù)據(jù),OOM問題隨時會發(fā)生
2. keyBy+window+MapState+配置RocksDB轉(zhuǎn)態(tài)存儲可行,只是因為MapState每次都需要變量才能獲取到總數(shù)據(jù)量大小,效率不高
3. keyBy+window+ValueState+BloomFilter+配置RocksDB轉(zhuǎn)態(tài)存儲,可行,BloomFilter的加入使得計算變得高效,但是BloomFliter有誤判率,不能實現(xiàn)100%精確,但是一般的業(yè)務場景,對于實時UV也并非要求100%精確,因此這是一個不錯的選擇.(這里的BloomFilter也可以使用HyperLogLog數(shù)據(jù)結構,都有誤判率)
4. 將數(shù)據(jù)存儲到第三方系統(tǒng),比如Redis或者HBase,之后再統(tǒng)計計算. 在Redis中存儲可用使用bitmap數(shù)據(jù)結構,空間占用小。
也可以使用HyperLogLog數(shù)據(jù)結構`(每個 HyperLogLog 鍵只需要花費12 KB 內(nèi)存,就可以計算接近2^64個不同元素的基數(shù))`,不能保證精確,但是比bitmap數(shù)據(jù)結構占用空間更小。