Redis之HyperLogLog类型解读

举报
yd_249383650 发表于 2023/08/31 16:00:41 2023/08/31
【摘要】 ​ 目录基本介绍基本命令pfaddpfcountpgmerge统计访客应用场景 什么是UV、PV、DAU、MAU场景说明java代码示例基本介绍HyperLogLog 是用来做基数统计的算法,HyperLogLog 的优点是,在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定 的、并且是很小的。在 Redis 里面,每个 HyperLogLog 键只需要花费 12 KB 内存,...

 

目录

基本介绍

基本命令

pfadd

pfcount

pgmerge

统计访客应用场景 

什么是UV、PV、DAU、MAU

场景说明

java代码示例



基本介绍

HyperLogLog 是用来做基数统计的算法,HyperLogLog 的优点是,在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定 的、并且是很小的。

在 Redis 里面,每个 HyperLogLog 键只需要花费 12 KB 内存,就可以计算接近 2^64 个不同元素的基数。这和计算基数时,元素越多耗费内存就越多的集合形成鲜明对比。

但是,因为 HyperLogLog 只会根据输入元素来计算基数,而不会储存输入元素本身,所以 HyperLogLog 不能像集合那样,返回输入的各个元素。

基数是什么?

比如数据集 {1, 3, 5, 7, 5, 7, 8}, 那么这个数据集的基数集为 {1, 3, 5 ,7, 8}, 基数(不重复元素)为5。 基数估计就是在误差可接受的范围内,快速计算基数。

去重复统计功能的基数估计算法-就是HyperLogLog(用于统计一个集合中不重复的元素个数,就是对集合去重复后剩余元素的计算) ,需要注意存在误差(准确率来换取空间,误差仅仅只是0.81%左右)

全集i={1,2,3,4,5,6,7,8,8,9,9,5}
去掉重复的内容
基数={1,2,3,4,5,6,7,8,9}

基本命令

序号 命令及描述
1 PFADD key element [element ...] 添加指定元素到 HyperLogLog 中。
2 PFCOUNT key [key ...] 返回给定 HyperLogLog 的基数估算值。
3 PFMERGE destkey sourcekey [sourcekey ...] 将多个 HyperLogLog 合并为一个 HyperLogLog

pfadd

Pfadd 命令将所有元素参数添加到 HyperLogLog 数据结构中。

redis> PFADD mykey a b c d e f g h i j
(integer) 1

redis> PFCOUNT mykey
(integer) 10

返回值:整型,如果至少有个元素被添加返回 1,否则返回 0。 

pfcount

Pfcount 命令返回给定 HyperLogLog 的基数估算值

语法:PFCOUNT key [key ...] 

redis> PFADD hll foo bar zap
(integer) 1

redis> PFADD hll zap zap zap
(integer) 0

redis> PFADD hll foo bar
(integer) 0

redis> PFCOUNT hll
(integer) 3

redis> PFADD some-other-hll 1 2 3
(integer) 1

redis> PFCOUNT hll some-other-hll
(integer) 6

返回值:整数,返回给定 HyperLogLog 的基数值,如果多个 HyperLogLog 则返回基数估值之和。

pgmerge

Pgmerge 命令将多个 HyperLogLog 合并为一个 HyperLogLog ,合并后的 HyperLogLog 的基数估算值是通过对所有 给定 HyperLogLog 进行并集计算得出的。

redis> PFADD hll1 foo bar zap a
(integer) 1

redis> PFADD hll2 a b c foo
(integer) 1

redis> PFMERGE hll3 hll1 hll2
OK

redis> PFCOUNT hll3
(integer) 6

返回值:返回 OK。

统计访客应用场景 

什么是UV、PV、DAU、MAU


①. UV:Unique Visitor,独立访客,一般理解为客户端IP(需要去重考虑)

②. PV:Page View,页面浏览量(不用去重)

③. DAU:日活跃用户量(登录或者使用了某个产品的用户数(去重复登录的用户))

④. MAU:MonthIy Active User,月活跃用户量 

场景说明

淘宝、天猫首页的UV,平均每天是1~1.5个亿左右

每天存1.5个亿的IP,访问者来了后先去查是否存在,不存在加入

一个用户一天内的多次访问只能算作一次

java代码示例

@Service
@Slf4j
public class HyperLogLogService {
    @Resource
    private RedisTemplate redisTemplate;

    /**
     * 模拟有用户来点击首页,每个用户就是不同的ip,不重复记录,重复不记录
     */
    @PostConstruct
    public void init() {
        log.info("------模拟后台有用户点击,每个用户ip不同");
        //自己启动线程模拟,实际上产不是线程
        new Thread(() -> {
            String ip = null;
            for (int i = 1; i <=200; i++) {
                Random random = new Random();
                ip = random.nextInt(255)+"."+random.nextInt(255)+"."+random.nextInt(255)+"."+random.nextInt(255);

                Long hll = redisTemplate.opsForHyperLogLog().add("hll", ip);
                log.info("ip={},该ip访问过的次数={}",ip,hll);
                //暂停3秒钟线程
                try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) { e.printStackTrace(); }
            }
        },"t1").start();
    }
}
@RestController
@Slf4j
public class HyperLogLogController {

    @Resource
    private RedisTemplate redisTemplate;

    @ApiOperation("获得ip去重复后的首页访问量,总数统计")
    @RequestMapping(value = "/uv",method = RequestMethod.GET)
    public long uv() {
        //pfcount
        return redisTemplate.opsForHyperLogLog().size("hll");
    }
}

 通过牺牲准确率来换取空间,对于不要求绝对准确率的场景下可以使用,因为概率算法不直接存储数据本身 通过一定的概率统计方法预估基数值,同时保证误差在一定范围内,由于又不储存数据故此可以大大节约内存 HyperLogLog就是一种概率算法的实现


【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。