暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Bitmap和HyperLogLog

原创 soul0202 2023-07-26
395

Bitmap(位存储)

概念:Bitmap即位图数据结构,都是操作二进制位来进行记录,只有0 和 1 两个状态。

例如 11001001,表示的是[1,2,5,8],Bitmap中1的个数就是基数。

Bitmap的长度和集合中元素的个数无关,而是与基数的上限有关。假如要计算上限为1亿的基数,则需要12.5M字节的Bitmap,就算集合中只有10个元素也需要12.5M。计算内存的方法:100000000/8/1024/1024 ≈ 12.5M。但是如果需要统计1000个对象,就需要大约12G的内存。

Bitmap也可以轻松合并多个集合,只需要将多个数组进行异或操作就可以。

常用命令

命令简述使用
setbit设置位图的index位为status(1或0)setbit bitmap index status
getbit获取位图的index位状态getbit bitmap index
bitcount统计位图1 的个数bitcount bitmap

应用场景

比如:统计用户信息,活跃、不活跃!登录、未登录!打卡、未打卡!两个状态的,都可以使用BitMap。

如果存储一年的打卡状态需要多少内存呢?365 天 = 365 bit 1 字节 = 8 bit ,46个字节左右。


使用场景1:统计一周打卡次数
0-6为周一到周末,1表示已打卡,0表示未打卡
#========================记录一周内的打卡情况========================
127.0.0.1:6379> setbit sign 0 1
(integer) 0
127.0.0.1:6379> setbit sign 1 1
(integer) 0
127.0.0.1:6379> setbit sign 2 0
(integer) 0
127.0.0.1:6379> setbit sign 3 0
(integer) 0
127.0.0.1:6379> setbit sign 4 1
(integer) 0
127.0.0.1:6379> setbit sign 5 1
(integer) 0
127.0.0.1:6379> setbit sign 6 0
(integer) 0
#========================查看具体某一天的打卡情况========================
127.0.0.1:6379> getbit sign 2
(integer) 0
#========================统计一周内打卡次数========================
127.0.0.1:6379> bitcount sign
(integer) 4

使用场景2:统计活跃用户
使用时间作为Key,然后用户ID为offset,如果当日活跃过就设置为1
#记录2021年08月12日用户的状态
127.0.0.1:6379> setbit 20210812 1 1
(integer) 0
127.0.0.1:6379> setbit 20210812 2 0
(integer) 0
127.0.0.1:6379> setbit 20210812 3 0
(integer) 0
#查看指定用户在2021年08月12日是否活跃
127.0.0.1:6379> getbit 20210812 2
(integer) 0
#查看在2021年08月12日活跃的用户数
127.0.0.1:6379> bitcount 20210812
(integer) 1

HyperLogLog(基数统计)

一个大型的网站,每天IP比如有100万,粗算一个IP消耗15字节,那么100万个IP就是15M。而HyperLogLog在Redis中每个键占用的内容都是12K,理论存储近似接近264个值,不管存储的内容是什么,他是一个基于基数估算的算法, 只能比较准确的估算出基数,可以使用少量固定的内存去存储并识别集合中的唯一元素。而且这个估算的基数并不一定准确,是一个带有0.81%标准错误的近似值。

常用命令

命令简述使用
pfadd添加指定元素到 HyperLogLog 中pfadd key element [element...]
pfcount返回给定 HyperLogLog 的基数估算值pfcount key
pfmerge将多个 HyperLogLog 合并为一个 HyperLogLogpfmerge destkey sourcekey [sourcekey ...]

应用场景

  • 统计各种计数。比如注册IP数、每日访问IP数、页面实时UV、在线用户数、共同好友数等。


Redis 在 2.8.9 版本添加了 HyperLogLog 结构。
Redis HyperLogLog 是用来做基数统计的算法,HyperLogLog 的优点是,在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定 的、并且是很小的。
在 Redis 里面,每个 HyperLogLog 键只需要花费 12 KB 内存,就可以计算接近 2^64 个不同元素的基 数。这和计算基数时,元素越多耗费内存就越多的集合形成鲜明对比。
但是,因为 HyperLogLog 只会根据输入元素来计算基数,而不会储存输入元素本身,所以 HyperLogLog 不能像集合那样,返回输入的各个元素。


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


使用实例:
#添加指定元素到 HyperLogLog 中
127.0.0.1:6379> pfadd key1 a b c d e f g h
(integer) 1
#返回给定 HyperLogLog 的基数估算值
127.0.0.1:6379> pfcount key1
(integer) 8
127.0.0.1:6379> pfadd key2 e f g h x w y x z
(integer) 1
127.0.0.1:6379> pfcount key2
(integer) 8
#将多个 HyperLogLog 合并为一个 HyperLogLog
127.0.0.1:6379> pfmerge key3 key1 key2
OK
127.0.0.1:6379> pfcount key3
(integer) 12

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

文章被以下合辑收录

评论