最近有一个需求,需要实时展示页面访问量排名,主要的实现思路如下。

为什么使用redis存储实时统计的数据?

1、实时统计的数据属于查多写少的类型
2、Redis的SortedSet数据结构天然可以非常快的得出topn的数据

如何使用redis存储Spark的实时统计数据?

(1)考虑到Spark直接操作Redis的话,各个组件之间的耦合会比较严重,所以我们将Spark的实时统计数据先推到kafka里面,然后不断的取出kafka的数据插入到redis中。

(2)进一步的,如果把所有的统计结果都放到redis里面的话,由于数据量比较大可能会对redis的性能有比较大的压力,而实际上我们需要查看的统计结果是有限的,所以只需要将topn的数据存放的redis中即可,可以根据当前的实时数据统计情况,设置插入的阈值,从而减少redis的性能压力。

#取出当前排名1k的统计值,获取当前插入数据的阈值
ZREVRANGE title_count 1000 1000 WITHSCORES

如何删除超时的统计数据?

既然是实时的统计数据,如果没有删除超时数据的机制,统计的结果实时上就变成了历史单位时间段的排名了,所以需要定时删除超时的统计数据。

但其实redis中SortedSet中的子元素是不能设置超时时间的,所以我们使用了另外一个SortedSet来存储子元素的插入时间,然后定时去扫描有没有子元素已经超时,超时的子元素集会在原始的统计表中被清理掉。

#查询超时的元素集,其中1534562250为超时的时间戳阈值
ZREVRANGEBYSCORE title_count_ttl 0 1534562250
#删除超时的元素集
ZREM title_count baidu.com bing.com

总结

整个方案在删除超时统计数据上还是有一些瑕疵,毕竟这个SortedSet TTL的实现方案需要插入两次数据,如果朋友们有更好的解决方案欢迎一起讨论,谢谢。

文章目录
  1. 1. 为什么使用redis存储实时统计的数据?
  2. 2. 如何使用redis存储Spark的实时统计数据?
  3. 3. 如何删除超时的统计数据?
  4. 4. 总结