Redis高级数据类型Hyperloglog、Bitmap的使用


Posted in Redis onMay 24, 2021

前言

很多小伙伴在面试中都会被问道 Redis的常用数据结构有哪些?

可能很大一部分回答都是 string、hash、list、set、zset。当然啦,这个答案肯定是没有错的,但是相信这个答案,面试官已经听的耳朵都起茧了。

本身我们选择的这个行业竞争就极强,学历拼不过难道还要知识都拼不过吗???

希望进来的小伙伴能好好看完这篇文章,也希望你以后的回答能是 常用的数据结构有string、hash、list、set、zset,但我平时可能还会用到 Hyperloglog和Bitmap。相信面试官听到你的回答,会有眼前一亮的感觉!

话不多说,开始吧,⬇

Hyperloglog

Hyperloglog简介

HyperLogLog是一种概率数据结构,用来估算数据的基数。

基数:可简单理解为集合中不同元素的个数,也可以理解为Set
对于一个集合 1、2、3、4,那么它的基数为 4
对于一个集合 1、2、3、4、1,那么它的基数也是 4

Hyperloglog作用

我们可以使用它来统计 UV。

UV即:UniqueVisitor,UV指的是独立访客的数量,一台电脑被视为一个独立访客。一台电脑早上访问了一次,下午又访问了一次,两次访问的都是同一个网站,只能被计算一次。

那可能有小伙伴问了,及刚才都说了可以理解为一个Set,那我为什么要用它来统计UV?

Redis 的 HyperLogLog 通过牺牲准确率来减少内存空间的消耗,只需要12K内存,在标准误差0.81%的前提下,能够统计2^64个数据。而Set就需要消耗大量空间
所以 HyperLogLog 是否适合在比如统计区间活跃度这样对精度要求不高的场景。

为什么能这么存储,主要依赖于伯努利试验,各位小伙伴可以去百度了解了解。

命令行中的使用

  • pfadd <key> [element]:添加数据
  • pfcount <key>:统计数量

Redis高级数据类型Hyperloglog、Bitmap的使用

Redis高级数据类型Hyperloglog、Bitmap的使用

SpringBoot中的使用

@Test
public void testHyperloglog() {

    String key = "language";

    for (int i = 1; i <= 10000; i++) {
        redisTemplate.opsForHyperLogLog().add(key,i);
    }

    for (int i = 5000; i <= 15000; i++) {
        redisTemplate.opsForHyperLogLog().add(key,i);
    }

    for (int i = 10000; i <= 20000; i++) {
        redisTemplate.opsForHyperLogLog().add(key,i);
    }

    long size = redisTemplate.opsForHyperLogLog().size(key);
    System.out.println(size);
}

Redis高级数据类型Hyperloglog、Bitmap的使用

可以看到结果值为:19891与真实值:20000相差不了多少,虽说有误差,但相比于set已经是很好了!

除此之外,在SpringBoot中还可以对多个key进行合并,统计合并之后的数据量

@Test
public void testHyperloglog() {

    String key1 = "language1";
    String key2 = "language2";
    String key3 = "language3";
    String unionKey = "language";


    for (int i = 1; i <= 10000; i++) {
        redisTemplate.opsForHyperLogLog().add(key1,i);
    }

    for (int i = 5000; i <= 15000; i++) {
        redisTemplate.opsForHyperLogLog().add(key2,i);
    }

    for (int i = 10000; i <= 20000; i++) {
        redisTemplate.opsForHyperLogLog().add(key3,i);
    }

    redisTemplate.opsForHyperLogLog().union(unionKey,key1,key2,key3);

    long size = redisTemplate.opsForHyperLogLog().size(unionKey);
    System.out.println(size);
}

Redis高级数据类型Hyperloglog、Bitmap的使用

可见,数据还是19891

Bitmap

Bitmap简介

位图不是特殊的数据结构,它其实就是普通的字符串,也就是 byte 数组(有了解布隆过滤器的小伙伴可展开联想一下)

通过一个bit位来表示某个元素对应的值或者状态,其中的key就是对应元素本身。

位操作分为两组:

  • 固定时间的单个位操作(如将一个位设置为1或0或获取其值)
  • 对位组的操作,例如计算给定位范围内设置的位的数量(例如,人口计数)。

位图的最大优点之一是,在存储信息时,它们通常可以节省大量空间。例如,在以增量用户ID表示不同用户的系统中,仅使用512 MB内存就可以记住40亿用户的一位信息

Bitmap作用

使用场景

  • 各种实时分析。
  • 存储与对象ID相关联的空间高效但高性能的布尔信息。

我们可以使用它来统计 DAU。

日均活跃用户数量(Daily Active User,DAU)是用于反映网站、互联网应用或网络游戏的运营情况的统计指标。日活跃用户数量通常统计一日(统计日)之内,登录或使用了某个产品的用户数(去除重复登录的用户)。

命令行使用Bitmap

使用 setbit 和 getbit 命令设置和检索位:

  • setbit命令将位号作为其第一个参数,将其设置为1或0的值作为其第二个参数。如果所寻址的位超出当前字符串长度,则该命令将自动放大字符串。
  • getbit 只是返回指定索引处的位的值。超出范围的位(寻址超出存储在目标键中的字符串长度的位)始终被视为零。

Redis高级数据类型Hyperloglog、Bitmap的使用

在位组上还有以下三个命令:

  • bitop 在不同的字符串之间执行按位运算。提供的运算为AND,OR,XOR和NOT。
  • bitcount 执行填充计数,报告设置为1的位数。
  • bitpos 查找具有指定值0或1的第一位。

Redis高级数据类型Hyperloglog、Bitmap的使用

SpringBoot使用Bitmap

@Test
public void testBitmap() {

    String key = "bitmap";

    redisTemplate.opsForValue().setBit(key,1,true);
    redisTemplate.opsForValue().setBit(key,4,true);
    redisTemplate.opsForValue().setBit(key,2,true);
    redisTemplate.opsForValue().setBit(key,5,true);

    System.out.println(redisTemplate.opsForValue().getBit(key,2));
    System.out.println(redisTemplate.opsForValue().getBit(key,3));
    System.out.println(redisTemplate.opsForValue().getBit(key,5));

}

Redis高级数据类型Hyperloglog、Bitmap的使用

尾言

到此这篇关于Redis高级数据类型Hyperloglog、Bitmap的使用的文章就介绍到这了,更多相关Redis Hyperloglog、Bitmap内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Redis 相关文章推荐
redis限流的实际应用
Apr 24 Redis
redis 查看所有的key方式
May 07 Redis
redis实现共同好友的思路详解
May 26 Redis
浅谈Redis的几个过期策略
May 27 Redis
详解缓存穿透击穿雪崩解决方案
May 28 Redis
redis客户端实现高可用读写分离的方式详解
Jul 04 Redis
详解Redis在SpringBoot工程中的综合应用
Oct 16 Redis
关于SpringBoot 使用 Redis 分布式锁解决并发问题
Nov 17 Redis
基于Redis zSet实现滑动窗口对短信进行防刷限流的问题
Feb 12 Redis
Redis 操作多个数据库的配置的方法实现
Mar 23 Redis
关于Redis的主从复制及哨兵问题
Jun 16 Redis
一文教你快速生成MySQL数据库关系图
Jun 28 Redis
redis实现排行榜功能
May 24 #Redis
分布式锁为什么要选择Zookeeper而不是Redis?看完这篇你就明白了
May 21 #Redis
Redis 配置文件重要属性的具体使用
May 20 #Redis
浅谈redis缓存在项目中的使用
May 20 #Redis
详解Redis主从复制实践
详解redis分布式锁的这些坑
为Java项目添加Redis缓存的方法
You might like
PHP完整的日历类(CLASS)
2006/11/27 PHP
PHP入门学习笔记之一
2010/10/12 PHP
PHP把空格、换行符、中文逗号等替换成英文逗号的正则表达式
2014/05/04 PHP
laravel 5.5 关闭token的3种实现方式
2019/10/24 PHP
IE和Mozilla的兼容性汇总event
2007/08/12 Javascript
JS 控制CSS样式表
2009/08/20 Javascript
JavaScript中常见陷阱小结
2010/04/27 Javascript
基于ajax实现文件上传并显示进度条
2015/08/03 Javascript
JavaScript基本语法学习教程
2016/01/14 Javascript
AngularJS深入探讨scope,继承结构,事件系统和生命周期
2016/11/02 Javascript
bootstrap中模态框、模态框的属性实例详解
2017/02/17 Javascript
js实现延迟加载的几种方法
2017/04/24 Javascript
JavaScript 上传文件(psd,压缩包等),图片,视频的实现方法
2017/06/19 Javascript
React Native 搭建开发环境的方法步骤
2017/10/30 Javascript
纯JS实现可用于页码更换的飞页特效示例
2018/05/21 Javascript
webpack 样式加载的实现原理
2018/06/12 Javascript
vue点击input弹出带搜索键盘并监听该元素的方法
2018/08/25 Javascript
微信小程序进入广告实现代码实例
2019/09/19 Javascript
[02:42]岂曰无衣,与子同袍!DOTA2致敬每一位守护人
2020/02/17 DOTA
Windows系统下安装Python的SSH模块教程
2015/02/05 Python
Python类的用法实例浅析
2015/05/27 Python
Python利用Beautiful Soup模块搜索内容详解
2017/03/29 Python
浅谈Python基础之I/O模型
2017/05/11 Python
Python 计算任意两向量之间的夹角方法
2019/07/05 Python
Python 保持登录状态进行接口测试的方法示例
2019/08/06 Python
Python openpyxl读取单元格字体颜色过程解析
2019/09/03 Python
享誉全球的多元化时尚精品购物平台:Farfetch发发奇(支持中文)
2017/08/08 全球购物
Superdry极度干燥美国官网:英国制造的服装品牌
2018/11/13 全球购物
优秀毕业生自我鉴定
2014/02/11 职场文书
汉语言文学专业求职信
2014/06/19 职场文书
活动费用申请报告
2015/05/15 职场文书
2016年师德先进个人事迹材料
2016/02/29 职场文书
PostgreSQL通过oracle_fdw访问Oracle数据的实现步骤
2021/05/21 PostgreSQL
python中pandas对多列进行分组统计的实现
2021/06/18 Python
python 标准库原理与用法详解之os.path篇
2021/10/24 Python
Python OpenCV超详细讲解调整大小与图像操作的实现
2022/04/02 Python