数据库 频道

Spark千亿级数据去重,性能优化踩坑之路

大家好,我是狗哥,今天给大家写一点干货,这次咱们就从0-1把思路给大家讲一下,这也是我同事在数据开发中踩过的坑,希望能帮助到大家。

先虚拟一个业务场景,方便大家思考

我举个例子,拿京东或者淘宝说吧,如果你的业务让你计算几个维度(广告位置、小时、广告类型等等吧,我就随便举个例子),每个维度的数据uv量级,方便业务评估和市场决策,数据精准度不要求完全精准,误差在1%以内就行了,你该如何做?

我们针对两个开发者思路,来跟大家梳理我们踩过的坑。

思路一,能跑就行,不关注性能

解决方式:直接count distinct

优势:应届生都会

弊端:数据去重性能差

计算性能:刚开始数据量少,4-6个小时可以出来,随着数据量增多运行时间 6-12个小时,业务对此非常不满意,早上来了看不到数据报表,需要等下午才产出,直接影响数据人员的口碑(老板开周会,肯定会diss做数据的,不能忍呀兄弟们,一定要精益求精!!!)。

思路二,用bitmap去重复

经过一番技术调研,发现用bitmap去重复,性能会很高,但设备id(imei、idfa) 不是数字,没有办法用bitmap,如果想用bitmap,需要把设备ID做hash计算,还得取绝 对值,正数才行

解决方式:abs(hash(imei))

优势:bitmap去重复性能高效,数据计算性能降低到了40分钟,从之前的10个小时跑不出来,变成了40分钟可以运行出来,直接单车变摩托。

弊端:发现数据误差到了6%,排查发现,是数据设备ID在hash的时候会出现正负数,也就是两个设备他的hash值是正负对称的(举个例子:一个设备hash值 -1,一设备个hash值1),两个设备取绝 对值abs,会出现都等于1。

针对这个问题,狗哥给出了建议,就是先根据设备ID取模1000(这个数大家可以自己去根据数据量调试),进行设备ID分桶,这样的好处相同设备会分在同一个桶内,同时减少了hash值绝 对值这之后相互影响的情况,然后每个分桶的u去重复uv再累加,这样下来,分维度的数据uv就会计算出来了,数据准确度到了0.03%,符合业务要求,同时数据性能稳定在40分钟左右。

0
相关文章