Redis的HyperLogLog实现uv统计
创始人
2024-03-25 20:13:06

为什么集合写的好好的,突然要来写 Redis 呢 ?

一切的原因都要从今天的需求说起,今天接了一个需求,目标是做一个推广页的 UV (统计访客, 每天只记录同一个访客一次) 统计,因为前段时间刚刚看过老钱写的 《Redis深度历险》 HyperLogLog 篇依旧历历在目,一样是统计 UV 的场景,我就直接提出用 HyperLogLog 去处理这个问题,然后被领导问为什么要用 HyperLogLog 好在哪的时候卡壳了,emmm ... 本来想凭借我这广阔的技术海无形装逼,这特么不尴尬了。

HyperLogLog 与 基数统计

HyperLogLog 是最早由 Flajolet 及其同事在 2007 年提出的一种 估算基数的近似最优算法,具体定义可以参考维基百科:https://en.jinzhao.wiki/wiki/HyperLogLog

所谓基数统计可以理解为用来统计一个集合中不重复的元素,也就是我们今天要讲解 HyperLogLog 的原因

业务场景分析

领导的需求是:统计每个网页的访客数量, 每个用户只记录一次

我们来捋顺一下思路, 可能你会想出如下几种方案:

  • Plan A : 数据库里建张表,没有一个表解决不了的问题,如果有那么就建两张表 .

  • Plan B : 建立一个 Set 集合, 存储当天访问过此页面的所有用户 id .

  • Plan C : bitmap,类似用户签到的解决方案,依据年月做 key , 日期作为偏移量 .

我们来分析一下这几种方案,首先数据库解决是不可能了,甭说做每个月的 UV 统计分析了, 一天的访问量存起来空间就占了太多了; 那么为每个页面设置一个 Set 怎么样呢 ? 依旧是访问量的问题,如果访问量很高 Set 的集合会非常大,集合一大去重的时候就 ... 你懂的, 所以 Set 也不行; 那么 bitmap 呢 ? bitmap 的一个元素可以对应到 bit 数组中的一位,使用 bitmap 确实很节省内存,可是在大数据量的场景下,依旧需要很多内存,并不适用 。

三个计划全部拉闸,怎么办呢?哎,拉闸就对了,不拉闸怎么讲我们今天要说的 HyperLogLog 呢?

概率算法

HyperLogLog 采取概率算法,所谓概率算法就是通过一定的概率统计方法预估基数值,而概率算法并不直接存储数据集合本身,这种方法可以极大的节省内存,并保证误差在一定范围内,HyperLogLog 在标准误差(0.81%)的前提下能够统计 2^64 个数据!

 实例

private static String COUNT = "cpp_bank_list_total_size_today";
private static String TOTAL_COUNT = "cpp_bank_list_total_size";
private static String TOTAL_ID = "0";

数据存入:

//获取访问者的ip
String ipAdress = IPUtil.getIpAddress(httpServletRequest);
log.debug("访问列表页的ip地址为:[{}]", ipAdress);
//将ip存入redis
HyperLogLogOperations hyperlog = redisTemplate.opsForHyperLogLog();
hyperlog.add(COUNT, ipAdress);

数据读取:

public void saveUserAccessLog() {HyperLogLogOperations hyperlog = redisTemplate.opsForHyperLogLog();int count = hyperlog.size(COUNT).intValue();Calendar calendar = Calendar.getInstance();calendar.add(Calendar.DAY_OF_MONTH, -1);CppBankAccessLog cppBankAccessLog = CppBankAccessLog.builder().id(Sequence.getInstance().getSequenceNumber()).time(new SimpleDateFormat("yyyy-MM-dd").format(calendar.getTime())).count(count).build();cppBankAccessLogMapper.insertSelective(cppBankAccessLog);//合并每天的访问量到总计中hyperlog.union(TOTAL_COUNT, COUNT);int totalCount = hyperlog.size(TOTAL_COUNT).intValue();cppBankAccessLogMapper.updateCountById(TOTAL_ID, totalCount);log.info("日活量信息入库,昨日数据:[{}],总数据:[{}]", count, totalCount);//删除today中的数据hyperlog.delete(COUNT);
}

相关内容

热门资讯

应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...