使用 Redis 统计网站 UV 的方法

这篇具有很好参考价值的文章主要介绍了使用 Redis 统计网站 UV 的方法。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

使用 Redis 统计网站 UV 的方法(概率算法)

文章目录

    • 前言
    • 思路
    • HyperLogLog
      • 使用 Redis 命令操作
      • 使用 Java 代码操作
    • HyperLogLog 实现原理及特点
    • 使用 Java 实现 HyperLogLog
    • 小结

前言

网站 UV 就是指网站的独立用户访问量Unique Visitor,即相同用户的多次访问需要去重。

思路

提到 UV 去重,猜大家都会想到Set集合类。

  • 使用Set集合是一个不错的办法,Set里面存储用户的id。每一个用户访问页面的时候,我们直接把id存入Set,最终获取Setsize即可。问题就是Set的容量需要设置多大呢?如果应用是分布式的,是否需要合并操作?第一个问题其实可以通过计算来估计,如果用户量上亿的话,存储空间也是需要非常大的;第二个问题其实可以通过 Redis、DB 等存储,如 Redis 的Set结构,DB 的唯一键。
  • 我们上面提到的 DB 也是一种解决方案,不过写入量很大时,数据库压力会比较大。用户如果很多,则row也相应的多,且可能需要对每天的数据进行分表。在用户访问量小的情况下,可以采用该处理方式。

上面两种方式虽然可以实现统计网站 UV 的功能,但是一个比较占用内存,一个比较占用数据库资源。那我们该如何规避这两个问题呢?在这里,我们就介绍另外一种实现方法,即使用 Redis 里面的HyperLogLog结构,且仅占用12k的空间。

HyperLogLog

HyperLogLog的使用比较简单,实现略复杂。我们先看一下如何利用HyperLogLog来进行页面 UV 的统计。

使用 Redis 命令操作

# 添加元素
127.0.0.1:6379> pfadd user zhangsan lisi wangwu
# 添加成功返回1,添加失败返回0
(integer) 1
# 统计数量
127.0.0.1:6379> pfcount user
# 返回现在数量
(integer) 3
# 再生成一个pfkey
127.0.0.1:6379> pfadd user2 zhangsan2 lisi2 wangwu
(integer) 1
127.0.0.1:6379> pfcount user2
(integer) 3
# pfmerge会将后面pfkey中的值合并到前面的pfkey中
127.0.0.1:6379> pfmerge user2 user
OK
# 查看merge后的user2
127.0.0.1:6379> pfcount user2
(integer) 5

使用 Java 代码操作

import org.springframework.data.redis.core.HyperLogLogOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
@Service
public class RedisService {
    @Resource
    private RedisTemplate < String, String > redisTemplate;
    /*** 记录用户访问** @param user*/
    public long statistic(String Key, String user) {
          HyperLogLogOperations<String,String>hyperLogLog=redisTemplate.opsForHyperLogLog();
            return hyperLogLog.add(Key, user);
        }
        /*** 统计当前 UV** @return*/
    public long size(String Key) {
          HyperLogLogOperations<String,String>hyperLogLog=redisTemplate.opsForHyperLogLog();
            return hyperLogLog.size(Key);
        }
        /*** 删除当前 key*/
    public void clear(String Key) {
        HyperLogLogOperations < String,String>hyperLogLog=redisTemplate.opsForHyperLogLog();
        hyperLogLog.delete(Key);
    }
}

HyperLogLog 实现原理及特点

  • 原理:其实这是个概率问题。举个 Java 的例子,我们每次将一个字符串放入HyperLogLog,其实是把字符串转换成了一个值,可以把它当成hash值,将这个值转换成 2 进制,从后向前看第一个 1 出现的位置。那么 1 出现在第三个位置的时候(xxxx x100),概率是多少呢?(1/2)^3=1/8,也就是大概有八个数字进到这个数据结构时,第一个 1 曾出现在第三个的位置的可能会比较大,所以我们只需要维护一个 1 出现位置的最大值(暂且称之为max position),我们就可以知道整个HyperLogLog数量是多少了。
  • 去重:我们上面讲到hash值,其实整个算法就是将一个固定的value固定的映射成一个数字就可以解决重复的问题了。如zhangsan对应8,那么max position=4,再来一个zhangsan,还是对应8,则max position不变。
  • 特点:因为是概率问题,总会出现不准确的情况,所以你在使用HyperLogLog时,可以将user数量设置大一些,如 100W。但是其结果,有可能你看到的是不到 100W,也有可能计算出来的 UV 还比 100W 大。

使用 Java 实现 HyperLogLog

public class HyperLogLogSelf {
    static class BitKeeper {
        private int maxBits;

        public void random() {// 这里的随机数可以当成一个对象的hashCode。
            // long value = new Object().hashCode() ^ (2 << 32);
            long value = ThreadLocalRandom.current().nextLong(2L << 32);
            int bits = lowZeros(value);
            if (bits > this.maxBits) {
                this.maxBits = bits;
            }
        }

        /*** 低位有多少个连续0* 思路上 ≈ 倒数第一个1的位置** @param value* @return*/
        private int lowZeros(long value) {
            int i = 1;
            for (; i < 32; i++) {
                if (value >> i << i != value) {
                    break;
                }
            }
            return i - 1;
        }
    }

    static class Experiment {
        private int n;
        private BitKeeper keeper;

        public Experiment(int n) {
            this.n = n;
            this.keeper = new BitKeeper();
        }

        public void work() {
            for (int i = 0; i < n; i++) {
                this.keeper.random();
            }
        }

        public void debug() {
            double v = Math.log(this.n) / Math.log(2);
            System.out.printf("%d %.2f %d\n", this.n, v, this.keeper.maxBits);
        }
    }

    public static void main(String[] args) {
        for (int i = 10000; i < 1000000; i += 10000) {
            Experiment exp = new Experiment(i);
            exp.work();
            exp.debug();
        }
    }
}

如上述代码所示,如果只有一个BitKeeper,那么精度很难控制,BitKeeper越多,则越精确,所以 Redis 在设置HyperLogLog的时候,设置了16384个桶,也就是2^14,每个桶的maxbits需要 6 个bit来存储,最大可以表示maxbits=63,于是总共占用内存就是2^14 * 6 / 8 = 12k字节。

小结

我们从应用场景开始,讲述了HyperLogLog的使用方法和实现原理,还给出了HyperLogLog的 Java 简单实现。

最后,我们在使用HyperLogLog的时候,需要注意:文章来源地址https://www.toymoban.com/news/detail-480884.html

  • HyperLogLog需要占用12k内存的(数据量大的时候),所以HyperLogLog不适合单独存储一个user相关的信息;
  • HyperLogLog是有一定精度损失的,可能比真实数量多,也可能比真实数量少,但基本上都在n‰(0<n<10)以内。

到了这里,关于使用 Redis 统计网站 UV 的方法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Redis应用】UV统计(四)

    🚗Redis应用学习·第四站~ 🚩本文已收录至专栏:Redis技术学习 首先我们要搞懂两个概念: UV :全称 Unique Visitor ,也叫 独立访客量 ,是指通过互联网访问、浏览这个网页的自然人。1天内同一个用户多次访问该网站,只记录1次。 PV :全称 Page View ,也叫 页面访问量或点击量

    2024年02月09日
    浏览(49)
  • 大数据-玩转数据-Flink 网站UV统计

    在实际应用中,我们往往会关注,到底有多少不同的用户访问了网站,所以另外一个统计流量的重要指标是网站的独立访客数(Unique Visitor,UV)。 对于UserBehavior数据源来说,我们直接可以根据userId来区分不同的用户。 将userid放到SET集合里面,统计集合长度,便可以统计到网

    2024年02月11日
    浏览(46)
  • Redis - 附近商铺、用户签到、UV统计

    底层都是基于地理坐标进行搜索,支持地理坐标的技术有很多,Redis就是其中之一 GEO 就是Geolocation的简写形式,代表 地理坐标 。 Redis 在3.2版本中加入了对GEO的支持, 允许存储地理坐标信息 ,帮助我们根据经纬度来检索数据。 常见的命令有 : GEOADD :添加一个地理空间信息,

    2024年02月13日
    浏览(39)
  • Redis:原理速成+项目实战——Redis企业级项目实战终结篇(HyperLogLog实现UV统计)

    👨‍🎓作者简介:一位大四、研0学生,正在努力准备大四暑假的实习 🌌上期文章:Redis:原理速成+项目实战——Redis实战14(BitMap实现用户签到功能) 📚订阅专栏:Redis:原理速成+项目实战 希望文章对你们有所帮助 这篇是实战部分的终结篇,其实Redis的核心操作,主要是

    2024年01月17日
    浏览(48)
  • 网站百度统计被恶意刷广告的处理方法

    在百度统计的数据中,查看网站的实时访客或者来源,有时候,会发现有一些乱七八糟的用户流量,这并不是网站被攻击或者被刷流量了,而是百度统计被被恶意刷广告,只是针对统计的行为,不影响网站的排名。 现象: 1、访问的链接,链接中有问号?,并包含其他网站的网

    2024年02月04日
    浏览(42)
  • 基于埋点日志数据的网络流量统计 - PV、UV

    水善利万物而不争,处众人之所恶,故几于道💦 一、 网站总流量数统计 - PV   1. 需求分析   2. 代码实现    方式一    方式二    方式三:使用process算子实现    方式四:使用process算子实现 二、网站独立访客数统计 - UV   1. 需求分析   2. 代码实现   PV全称

    2024年02月14日
    浏览(35)
  • 3dmax uv贴图方法大全

    方法1 / 渲染 材质编辑器 在基本色 漫反射中 选择 位图 image.png 点击查看图像调整要显示区域. image.png 多边形编辑模式选择面. 然后分离出一个单独的面 image.png 把材质拖上去,勾选应用即可 image.png 方法2 uvm贴图 支持多种方式投射贴图 , 支持gizmo缩放 移动调整 ,类似投影仪的效

    2024年02月10日
    浏览(37)
  • 统计鸟网站统计搜索引擎蜘蛛名称及释义

    搜索引擎用来爬行和访问页面的程序被称为蜘蛛(spider),也叫机器人(bot)。搜索引擎蜘蛛访问网站页面时类似于普通用户使用浏览器,蜘蛛程序发出页面访问请求后,服务器返回HTML代码,蜘蛛程序把收到的代码存入原始页面数据库,搜索引擎为了提高爬行和抓取的速度,

    2024年04月27日
    浏览(45)
  • 面试题分析:统计网站访问次数

    难度:较低 平台的访问量非常高,需要实时统计网站的访问次数,请设计一个计数器解决: 初级工程师,可能回答使用synchronized锁或重入锁,进一步探讨,synchronized锁太重,有没其他方式,可能回答atomic类,进一步问,atomic类原理,什么场景下适合用,什么场景下不适合用

    2024年02月12日
    浏览(82)
  • Python3.6统计模块statsmodels的安装教程及使用方法

    Python3.6统计模块statsmodels的安装教程及使用方法 如果你需要对数据进行深入的统计分析和建模,那么Python编程语言中的statsmodels模块会是你的不二之选。该模块提供了多种统计模型、工具和功能,用于进行统计建模、推断、预测以及数据探索。本文将为大家详细介绍Python3.6下

    2024年02月11日
    浏览(37)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包