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