数据倾斜问题和滑动窗口uv统计问题

背景:item的滑动窗口内的uv统计,item会有头部内容问题,即会引起数据倾斜。

注释:实时统计,java语言。

关键词:

HyperLogLog、Redis、storm。

一、uv统计

1.对于大数据量的uv实时统计肯定不能使用set来实现,目前大多使用的方法是HyperLogLog估算。对于固定窗口的uv统计相对来说也是比较容易实现的,但是对于滑动窗口就很不好做了。

2.最开始我们使用的是一个流式计算平台,它是使用HBase来存储数据的,但是因为实时数据量很大,每个worker有3000qps,加上需要滑动窗口,且来一条记录需要计算多个窗口的uv值,所以导致最后的qps翻了很多倍,且java的HyperLogLog对性能的消耗很大,每一条记录过来,我们需要调用近百次的HyperLogLog计算,所以处理速度根本上不来,一个小时也就能处理几分钟的数据,导致延时无限增加。

后来改用storm加redis单实例来做测试,redis本身支持HyperLogLog计算,且读写性能很好。但是测试中发现单个redis实例cpu打到100%也扛不住。无奈就只能想办法分到多个redis实例去计算。

在分多redis实例时,用item去分显然是不合理的,因为item的热剧问题很明显。

后来想用用户id去hash,然后分到不同的redis实例,uv计算本身就是对用户id进行去重,所以根据用户id去hash可以近似保证同一个用户会走同一个redis。


3.关于滑动窗口遇到的坑:

(1)为了提高性能,肯定希望读表和计算次数越少越好,但是实时流是需要来一条就要更新表信息的,所以对于滑动窗口,比如1小时窗口,以1分钟为刻度滑动:

一般会需要计算一个中间值,如前59分钟的加上当前分钟值,但是需要考虑如果前59分钟的值还会变化的情况。



附:一些去重方法

1.sql

(1)内存去重distinct:count(distinct value)

(2)基数估计:适合key范围较小的,比如年龄;

2.布隆过滤器:优缺点都很明显,适用于大数据量,准确率99%;



二、热点数据倾斜问题

1.通常可以通过给item后面加上一个随机数或者把item哈希到某个区间,然后分桶(分partition)去处理,最后merge一下。也就是分层处理。

但是这种方法虽然解决了数据倾斜,但是增加了计算和IO,尤其是uv统计场景的去重计算量并不会减少,反而会增加;


2.map的local reduce

在时间和空间上都打散,

3.缓存

缓存一批数据,比如对实时性要求不太高的,可以缓存10s的数据,做一些简单的聚合操作,10s后批量处理一次。


你可能感兴趣的:(Java,数据处理)