乐趣区

关于redis:Redis高级数据类型HyperloglogBitmap快速带你上手


前言

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

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

自身咱们抉择的这个行业竞争就极强,学历拼不过难道还要常识都拼不过吗???

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

话不多说,开始吧,⬇


Hyperloglog


Hyperloglog 简介

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

<font size=”3″>** 基数:可简略了解为汇合中不同元素的个数,也能够了解为 Set
对于一个汇合 1、2、3、4,那么它的基数为 4
对于一个汇合 1、2、3、4、1,那么它的基数也是 4**


Hyperloglog 作用

咱们能够应用它来统计 UV。

<font size=”3″>UV 即:UniqueVisitor,UV 指的是 == 独立访客的数量 ==,一台电脑被视为一个独立访客。一台电脑早上拜访了一次,下午又拜访了一次,两次拜访的都是同一个网站,只能被计算一次。

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

**Redis 的 HyperLogLog 通过就义准确率来缩小内存空间的耗费,只须要 12K 内存,在标准误差 0.81% 的前提下,可能统计 2^64 个数据。而 Set 就须要耗费大量空间
所以 HyperLogLog 是否适宜在比方统计区间活跃度这样对精度要求不高的场景。**

为什么能这么存储,次要依赖于伯努利试验,各位小伙伴能够去百度理解理解。


命令行中的应用

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


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);
}


能够看到后果值为: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);
}


可见,数据还是 19891


Bitmap


Bitmap 简介

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

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

位操作分为两组

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

位图的最大长处之一是,在 存储信息时,它们通常能够节俭大量空间。例如,在以增量用户 ID 示意不同用户的零碎中,仅应用 512 MB 内存就能够记住 40 亿用户的一位信息


Bitmap 作用

应用场景

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

咱们能够应用它来统计 DAU。

<font size=”3″> == 日均沉闷用户数量 ==(Daily Active User,DAU)是用于反映网站、互联网利用或网络游戏的经营状况的统计指标。日沉闷用户数量通常统计一日(统计日)之内,登录或应用了某个产品的用户数(去除反复登录的用户)。


命令行应用 Bitmap

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

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

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

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


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));

}


尾言

我是 Code 皮皮虾,一个酷爱分享常识的 皮皮虾爱好者,将来的日子里会不断更新出对大家无益的博文,期待大家的关注!!!

创作不易,如果这篇博文对各位有帮忙,心愿各位小伙伴能够 == 点赞和关注我哦 ==,感激反对,咱们下次再见~~~

== 分享纲要 ==

大厂面试题专栏

Java 从入门到入坟学习路线目录索引

开源爬虫实例教程目录索引


关注公众号,更多精彩内容尽在其中!!!

退出移动版