千万数据去重_如何在 1 秒内做到大数据精准去重?

去重计数在企业日常分析中应用广泛,如用户留存、销售统计、广告营销等。海量数据下的去重计数十分消耗资源,动辄几分钟,甚至几小时,Apache Kylin 如何做到秒级的低延迟精确去重呢?

什么是去重计数

去重计数是数据分析中的常用分析函数,指查询某列中不同值的个数,在 SQL 中的函数是 count(distinct col)。它与 count(col) 函数的区别在于有一个 distinct 描述符,意思是去掉重复值,因此称为去重计数。

去重计数使用广泛,例如:在网站/app 使用统计中,PV/UV 是最常用的指标,其中 UV(unique visitor,独立访问用户)就是去重后的数字,即同一个用户的所有访问记录只计入一次。对于网站/app 所有者,PV (page view)代表的使用量的高低,UV 代表用户的多少,两个数字都很重要;只有结合两个数字一起,才能更加准确地了解网站/app的用户、用量增长情况。

图 1:PV/UV 统计

大数据上去重运算的难点与挑战

去重运算因为涉及到数值的比较,因此它的计算要比单纯的 PV 计数要略复杂。当数据量不大的时候,单机运行的性能或许还能忍受。但是当数据量渐长的时候,所花的时间越来越长,依靠单节点处理难以满足,此时就需要依靠分布式框架如 MapReduce 或 Spark 等并行处理,把大数据分而治之。

学习过 MapReduce 的朋友,一定对它的 WordCount  范例非常了解。下图解释了使用MapReduce 进行并行词语出现次数统计的过程:

图2:WordCount 过程示例

试想,如果你的网站/app,访问用户数较大,如一千万,访问记录一亿(假设一个人平均点击 10 次)。假如每个用户的 ID 已经用 int 表示了,那么一次简单的去重运算,需要 shuffle 的数据量就是:1亿*4字节 = 400 MB = 3200 Mb。以内网千兆网 1000 Mbps 来计算,至少也需要 3 秒的传输;再加上磁盘读写、排序、序列化、反序列化操作,这样的一个计数运算最终的时间基本在 10 秒以上。现实中情况可能更加复杂:

用户标识符可能是 email、uuid、身份证、手机号等更长的字符,空间占用更大;

去重之前需要某些条件过滤,占用更多计算资源,如查询过去 2 天在某几个地区的 UV;

访问记录多(行为日志往往在数十亿以上);

网络和磁盘 IO 忙,查询性能会出现抖动。

总之,大数据上的去重计数是一个耗资源的计算,做到秒级的低延迟响应十分困难;如果这方面查询较频繁,必定需要优化数据结构和算法。

大数据去重算法

事实上,研究人员早就意识到了这里存在优化空间,开发了多种算法和数据结构。最著名的当属 HyperLogLog 和 Bitmap 两种。前不久,Kyligence工程师在 2019 年 4 月的北京 Kylin Meetup 上做了分享,并撰写了技术文章,感兴趣的同学请参考文末的“参考阅读”【1】和【2】。

这两种算法结构的共同点是,以非常精凑的结构存储去重集合的特征(或完整集合),这样不但可以回答去重数,还可以用于后续合并运算(如昨天和今天的去重)。相比较于每次都从原始值上做去重,它的存储和计算效率可以大大提高。

但这两种算法也有明显的差异点:

1) HyperLogLog,以下简称 HLL,它的空间复杂度非常低(log(log(n)) ,故而得名 HLL),几乎不随存储集

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值