分享

如何利用Spark Streaming实现UV(有状态的)统计

xingoo 发表于 2017-5-9 10:51:36 [显示全部楼层] 回帖奖励 阅读模式 关闭右栏 10 32676
背景需求:
基于实时的用户点击日志,计算出当天的pv、uv。

pv很好说了....UV这种需要按照用户唯一标识去重的如何计算呢?

自己的思路:

1 每一个Streaming的窗口内部单独统计,然后在外部再去做去重。

比如,在一个窗口内部,统计出这个窗口内,每个用户对应的PV;
当天所有的PV累加就是PV、按照用户唯一标识去重就是UV

2 基于有状态的Streaming算法来完成

利用checkpoint,保存每个用户对应的访问情况。不过这样检查点的数据需要保存太多...每次都要重新去hdfs上读取返序列化,感觉性能应该不行。
而且,采用这种方式,如何对接到前端展示也是个问题....

求前辈们指点指点思路...

已有(10)人评论

跳转到指定楼层
xingoo 发表于 2017-5-9 11:41:40
暂时的方案是,计算的数据基于checkpoint没天保存;最终的结果,基于jdbc  insertorupdate到数据库...
回复

使用道具 举报

easthome001 发表于 2017-5-9 12:46:14
pv,uv他们的逻辑是差不多的。
正如楼主所说,uv只需要加一个判断,重复的不统计就可以了。
如果是spark sql,distinct 就完成了。
如果spark streaming,使用相关api,应该也可以实现。
回复

使用道具 举报

xingoo 发表于 2017-5-9 13:11:15
easthome001 发表于 2017-5-9 12:46
pv,uv他们的逻辑是差不多的。
正如楼主所说,uv只需要加一个判断,重复的不统计就可以了。
如果是spark  ...

嗯,目前基本上是这个思路。不过可不是一个的判断那么简单...
回复

使用道具 举报

xingoo 发表于 2017-5-9 13:13:31
easthome001 发表于 2017-5-9 12:46
pv,uv他们的逻辑是差不多的。
正如楼主所说,uv只需要加一个判断,重复的不统计就可以了。
如果是spark  ...

主要是流里面只能拿到当前时间段的数据,是无法知晓过去的数据的,这就不好判断哪些去重哪些不去了。
当然,也可以使用window方法,不过这个window一般也就几个....UV的场景不太适合。

如果在streaming里面,读取当天全部的数据,也就失去streaming的意义了...
回复

使用道具 举报

einhep 发表于 2017-5-9 16:59:34
xingoo 发表于 2017-5-9 13:13
主要是流里面只能拿到当前时间段的数据,是无法知晓过去的数据的,这就不好判断哪些去重哪些不去了。
当 ...

checkpoint主要是用来恢复的。可以使用spark streaming的缓存来实现。将所遇到的用户都放到缓存里,重复就不用放了,最后统计。
回复

使用道具 举报

xingoo 发表于 2017-5-9 17:39:28
einhep 发表于 2017-5-9 16:59
checkpoint主要是用来恢复的。可以使用spark streaming的缓存来实现。将所遇到的用户都放到缓存里,重复 ...

恩恩,测试了一下...我直接用了checkpoint里面的stateful 来保存uv相关的数据,目前应该能满足需求。
到时候会没天清理一下~ 性能应该还可以...
回复

使用道具 举报

Fantasy泽 发表于 2017-5-9 17:48:18
楼主可以看一下redis,里面有set集合,可以帮助你去重,也可以缓存数据
回复

使用道具 举报

xingoo 发表于 2017-5-9 18:10:28
Fantasy泽 发表于 2017-5-9 17:48
楼主可以看一下redis,里面有set集合,可以帮助你去重,也可以缓存数据

嗯,暂时先不打算用redis了....等checkpoint熟练一下,看看性能再说~
不过最后肯定会引入缓存系统,到时候看看是redis还是tachyon
回复

使用道具 举报

zstu 发表于 2017-6-2 16:59:40
xingoo 发表于 2017-5-9 18:10
嗯,暂时先不打算用redis了....等checkpoint熟练一下,看看性能再说~
不过最后肯定会引入缓存系统,到时 ...

楼主,你是怎么用checkpoint来计算uv的,可以代码共享一下吗?
回复

使用道具 举报

12下一页
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

推荐上一条 /2 下一条