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主从复制实践
May 19 Redis
分布式锁为什么要选择Zookeeper而不是Redis?看完这篇你就明白了
May 21 Redis
浅谈Redis位图(Bitmap)及Redis二进制中的问题
Jul 15 Redis
关于redisson缓存序列化几枚大坑说明
Aug 04 Redis
Redis字典实现、Hash键冲突及渐进式rehash详解
Sep 04 Redis
聊聊redis-dump工具安装问题
Jan 18 Redis
Redis监控工具RedisInsight安装与使用
Mar 21 Redis
Redis超详细讲解高可用主从复制基础与哨兵模式方案
Apr 07 Redis
浅谈Redis缓冲区机制
Jun 05 Redis
浅谈Redis变慢的原因及排查方法
Jun 21 Redis
Redis+AOP+自定义注解实现限流
Jun 28 Redis
基于redis+lua进行限流的方法
Jul 23 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导入导出CSV文件
2014/11/03 PHP
PHP反射学习入门示例
2019/06/14 PHP
5分钟理解JavaScript中this用法分享
2013/11/09 Javascript
javascript中interval与setTimeOut的区别示例介绍
2014/03/14 Javascript
60个很实用的jQuery代码开发技巧收集
2014/12/15 Javascript
JS获取Table中td值的方法
2015/03/19 Javascript
js获取字符串字节数方法小结
2015/06/09 Javascript
D3.js中data(), enter() 和 exit()的问题详解
2015/08/17 Javascript
动态加载js、css的简单实现代码
2016/05/26 Javascript
JS实现图片的不间断连续滚动的简单实例
2016/06/03 Javascript
node.js中http模块和url模块的简单介绍
2017/10/06 Javascript
微信小程序实现点击按钮修改字体颜色功能【附demo源码下载】
2017/12/05 Javascript
jquery应用实例分享_实现手风琴特效
2018/02/01 jQuery
vue.js element-ui tree树形控件改iview的方法
2018/03/29 Javascript
详解vue-cli3开发Chrome插件实践
2019/05/29 Javascript
nodejs读取图片返回给浏览器显示
2019/07/25 NodeJs
解决layui-open关闭自身窗口的问题
2019/09/10 Javascript
[01:03:18]DOTA2-DPC中国联赛 正赛 RNG vs Dynasty BO3 第一场 1月29日
2021/03/11 DOTA
Python读取ini文件、操作mysql、发送邮件实例
2015/01/01 Python
python3批量删除豆瓣分组下的好友的实现代码
2016/06/07 Python
Python处理命令行参数模块optpars用法实例分析
2018/05/31 Python
eclipse创建python项目步骤详解
2019/05/10 Python
pytorch实现mnist数据集的图像可视化及保存
2020/01/14 Python
Fossil美国官网:Fossil手表、手袋、珠宝及配件
2017/02/01 全球购物
华为消费者德国官方网站:HUAWEI德国
2020/11/03 全球购物
花卉与景观设计系大学生求职信
2013/10/01 职场文书
写给女生的道歉信
2014/01/14 职场文书
师范大学生求职信
2014/06/13 职场文书
个人年终总结怎么写
2015/03/09 职场文书
2015年教学工作总结
2015/04/02 职场文书
父亲节感言
2015/08/03 职场文书
2016个人廉洁自律承诺书
2016/03/25 职场文书
编写python程序的90条建议
2021/04/14 Python
Redis RDB技术底层原理详解
2021/09/04 Redis
win11系统中dhcp服务异常什么意思? Win11 DHCP服务异常修复方法
2022/04/08 数码科技
Springboot中如何自动转JSON输出
2022/06/16 Java/Android