一灰灰blog 一灰灰blog
首页
  • InfluxDB
  • MongoDB
  • MySql
  • 基础系列
  • DB系列
  • 搜索系列
  • MQ系列
  • WEB系列
  • 中间件
  • 运维
  • SpringSecurity
  • SpringCloud
  • QuickAlarm
  • QuickCrawer
  • QuickFix
  • QuickMedia
  • QuickSpi
  • QuickTask
  • 高可用
  • 分类
  • 标签
  • 归档
  • 收藏
  • 关于
GitHub (opens new window)

一灰灰blog

资深搬运工
首页
  • InfluxDB
  • MongoDB
  • MySql
  • 基础系列
  • DB系列
  • 搜索系列
  • MQ系列
  • WEB系列
  • 中间件
  • 运维
  • SpringSecurity
  • SpringCloud
  • QuickAlarm
  • QuickCrawer
  • QuickFix
  • QuickMedia
  • QuickSpi
  • QuickTask
  • 高可用
  • 分类
  • 标签
  • 归档
  • 收藏
  • 关于
GitHub (opens new window)
  • 基础系列

  • DB系列

    • H2Database

    • JPA

    • JdbcTemplate

    • Jooq

    • Mybatis

    • 事务

    • MongoDB

    • Redis

      • 【DB系列】Redis之基本配置
      • 【DB系列】Redis之Jedis配置
      • 【DB系列】Redis之String数据结构的读写
      • 【DB系列】Redis之List数据结构使用姿势
      • 【DB系列】Redis之Hash数据结构使用姿势
      • 【DB系列】Redis之Set数据结构使用姿势
      • 【DB系列】Redis之ZSet数据结构使用姿势
      • 【DB系列】借助Redis实现排行榜功能(应用篇)
      • 【DB系列】借助Redis搭建一个简单站点统计服务(应用篇)
      • 【DB系列】Redis集群环境配置
      • 【DB系列】Redis之管道Pipelined使用姿势
      • 【DB系列】Redis高级特性之Bitmap使用姿势及应用场景介绍
      • 【DB系列】Redis高级特性之发布订阅
      • 【DB系列】Redis高级特性之HyperLoglog
        • I. 基本使用
          • 1. 配置
          • 2. 使用姿势
          • 3. 原理说明
          • 4. 应用场景
        • II. 其他
          • 0. 项目
          • 1. 一灰灰Blog
      • 【DB系列】Redis高级特性之GEO
      • 【DB系列】redisson分布式锁使用及注意事项
      • 【DB系列】缓存注解@Cacheable @CacheEvit @CachePut使用姿势介绍
      • 【DB系列】SpringBoot缓存注解@Cacheable之自定义key策略及缓存失效时间指定
      • 【DB系列】借助redis来实现延时队列(应用篇)
      • 【DB系列】Redis实现分布式锁(应用篇)
    • 实例

  • 搜索系列

  • MQ系列

  • WEB系列

  • 中间件

  • 运维

  • SpringSecurity

  • SpringCloud

  • Spring系列
  • DB系列
  • Redis
一灰灰
2020-10-21

【DB系列】Redis高级特性之HyperLoglog

hyperloglog算法,利用非常少的空间,实现比较大的数据量级统计;比如我们前面在介绍bitmap的过程中,说到了日活的统计,当数据量达到百万时,最佳的存储方式是hyperloglog,本文将介绍一下hyperloglog的基本原理,以及redis中的使用姿势

# I. 基本使用

# 1. 配置

我们使用SpringBoot 2.2.1.RELEASE来搭建项目环境,直接在pom.xml中添加redis依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
1
2
3
4

如果我们的redis是默认配置,则可以不额外添加任何配置;也可以直接在application.yml配置中,如下

spring:
  redis:
    host: 127.0.0.1
    port: 6379
    password:
1
2
3
4
5

# 2. 使用姿势

我们下来看使用姿势,原理放在后面说明

redis中,hyperlolog使用非常简单,一般就两个操作命令,添加pfadd + 计数pfcount;另外还有一个不常用的merge

# a. add

添加一条记录

public boolean add(String key, String obj) {
    // pfadd key obj
    return stringRedisTemplate.opsForHyperLogLog().add(key, obj) > 0;
}
1
2
3
4

# b. pfcount

非精准的计数统计

public long count(String key) {
    // pfcount 非精准统计 key的计数
    return stringRedisTemplate.opsForHyperLogLog().size(key);
}
1
2
3
4

# a. merge

将多个hyperloglog合并成一个新的hyperloglog;感觉用的场景并不会特别多

public boolean merge(String out, String... key) {
    // pfmerge out key1 key2  ---> 将key1 key2 合并成一个新的hyperloglog out
    return stringRedisTemplate.opsForHyperLogLog().union(out, key) > 0;
}
1
2
3
4

# 3. 原理说明

关于HyperLogLog的原理我这里也不进行详细赘述,说实话那一套算法以及调和平均公式我自己也没太整明白;下面大致说一下我个人的朴素理解

Redis中的HyperLogLog一共分了2^14=16384个桶,每个桶占6个bit

一个数据,塞入HyperLogLog之前,先hash一下,得到一个64位的二进制数据

  • 取低14位,用来定位桶的index
  • 高50位,从低到高数,找到第一个为1出现的位置n
    • 若桶中值 > n,则丢掉
    • 反之,则设置桶中的值为n

那么怎么进行计数统计呢?

  • 拿所有桶中的值,代入下面的公式进行计算

上面这个公式怎么得出的?

之前看到一篇文章,感觉不错,有兴趣了解原理的,可以移步: https://www.jianshu.com/p/55defda6dcd2 (opens new window)

# 4. 应用场景

hyperloglog通常是用来非精确的计数统计,前面介绍了日活统计的case,当时使用的是bitmap来作为数据统计,然而当userId分散不均匀,小的特别小,大的特别大的时候,并不适用

在数据量级很大的情况下,hyperloglog的优势非常大,它所占用的存储空间是固定的2^14 下图引用博文《用户日活月活怎么统计》 (opens new window)

使用HyperLogLog进行日活统计的设计思路比较简单

  • 每日生成一个key
  • 某个用户访问之后,执行 pfadd key userId
  • 统计总数: pfcount key

# II. 其他

# 0. 项目

系列博文

  • 【DB系列】Redis高级特性之发布订阅 (opens new window)
  • 【DB系列】Redis高级特性之Bitmap使用姿势及应用场景介绍 (opens new window)
  • 【DB系列】Redis之管道Pipelined使用姿势 (opens new window)
  • 【DB系列】Redis集群环境配置 (opens new window)
  • 【DB系列】借助Redis搭建一个简单站点统计服务(应用篇) (opens new window)
  • 【DB系列】借助Redis实现排行榜功能(应用篇) (opens new window)
  • 【DB系列】Redis之ZSet数据结构使用姿势 (opens new window)
  • 【DB系列】Redis之Set数据结构使用姿势 (opens new window)
  • 【DB系列】Redis之Hash数据结构使用姿势 (opens new window)
  • 【DB系列】Redis之List数据结构使用姿势 (opens new window)
  • 【DB系列】Redis之String数据结构的读写 (opens new window)
  • 【DB系列】Redis之Jedis配置 (opens new window)
  • 【DB系列】Redis之基本配置 (opens new window)

工程源码

  • 工程:https://github.com/liuyueyi/spring-boot-demo (opens new window)
  • 项目源码: https://github.com/liuyueyi/spring-boot-demo/tree/master/spring-boot/122-redis-template (opens new window)

# 1. 一灰灰Blog

尽信书则不如,以上内容,纯属一家之言,因个人能力有限,难免有疏漏和错误之处,如发现bug或者有更好的建议,欢迎批评指正,不吝感激

下面一灰灰的个人博客,记录所有学习和工作中的博文,欢迎大家前去逛逛

  • 一灰灰Blog个人博客 https://blog.hhui.top (opens new window)
  • 一灰灰Blog-Spring专题博客 http://spring.hhui.top (opens new window)

一灰灰blog

编辑 (opens new window)
#Redis
上次更新: 2021/10/15, 19:56:22
【DB系列】Redis高级特性之发布订阅
【DB系列】Redis高级特性之GEO

← 【DB系列】Redis高级特性之发布订阅 【DB系列】Redis高级特性之GEO→

最近更新
01
【基础系列】基于maven多环境配置
04-25
02
【WEB系列】内嵌Tomcat配置Accesslog日志文件生成位置源码探索
04-24
03
【搜索系列】ES查询常用实例演示
04-18
更多文章>
Theme by Vdoing | Copyright © 2017-2022 一灰灰Blog
MIT License | 鄂ICP备18017282号 |
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式
×