Redis数据库的BitMaps、Hyperloglog、Streams、Bloom Filter

1. BitMaps

Bitmaps并不属于Redis中数据结构的一种,它的命令基于String操作,是set、get等一系列字符串操作的一种扩展,与其不同的是,它提供的是位级别的操作,从这个角度看,我们也可以把它当成是一种位数组、位向量结构。当我们需要存取一些boolean类型的信息时,Bitmap是一个非常不错的选择,在节省内存的同时也拥有很好的存取速度(getbit/setbit操作时间复杂度为O(1))。

在这里插入图片描述
在这里插入图片描述

127.0.0.1:6543 > set hello big
"OK"
 
127.0.0.1:6543 > getbit hello 0
"0"
 
127.0.0.1:6543 > getbit hello 1
"1"
 
127.0.0.1:6543 > setbit hello 7 1
"0"
 
127.0.0.1:6379 > get hello
"cig"

1.1. 使用场景

  1. 用户签到
# 2021年第一天,用户Id = userId 的用户签到
setbit 2021:userId 1 1
  1. 统计活跃用户(用户登陆情况)

使用日期作为 key,然后用户 id 为 offset,如果当日活跃过就设置为1。具体怎么样才算活跃这个标准大家可以自己指定。
假如:

  • 20220101 活跃用户情况是: [1,0,1,1,0]
  • 20220102 活跃用户情况是 :[ 1,1,0,1,0 ]

统计连续两天活跃的用户总数:

bitop and dest1 20220101 20220102 
# dest1 中值为1的offset,就是连续两天活跃用户的ID
bitcount dest1

统计20220101 ~ 20220102 活跃过的用户总数:

bitop or dest2 20220101 20220102
# dest2 中值为1的offset,就是两天都活跃的用户的ID
bitcount dest2
  1. 统计用户在线状态
# userId 登录,设置状态为1
setbit key userId 1
 
# 获取 userId 的状态:1 - 在线;0 - 不在线
getbit key userId
  1. 视频属性的无限延伸

一个拥有亿级数据量的短视频app,视频存在各种属性(是否加锁、是否特效等等),需要做各种标记。

  1. 存储在mysql中,肯定不行,一个是随着业务增长属性一直增加,并且存在有时间限制的属性,直接对数据库进行加减字段是非常不合理的做法。即使是存在一个字段中用json等压缩技术存储也存在读效率的问题,并且对于大几亿的数据来说,废弃的字段回收起来非常麻烦。

  2. 直接记录在redis中,根据业务属性+uid为key来存储。读写效率角度没毛病,但是存储的角度来说key的数据量都大于value了,太耗费空间了。即使是用json等压缩技术来存储。也存在问题,解压需要时间,并且大几亿的数据回收也是难题。

  3. key由属性id+视频分片id组成。value按照视频id对分片范围取模来决定偏移量offset。10亿视频一个属性约120m还是挺划算的。

1.2 总结

  • bigmap 基于最小的单位bit进行存储,最大优势是非常省空间;
  • 设置时候时间复杂度O(1)、读取时候时间复杂度O(n),操作是非常快的;
  • 二进制数据的存储,进行相关计算的时候非常快,也能方便扩容;
  • 不要给一个很短的 bigmap 设置很长位的偏移量的值,这样有可能堵塞。

1.3. 参考

  • 《Redis 中 bitmap 的原理和使用》:https://blog.csdn.net/weixin_44259720/article/details/122364337?utm_medium=distribute.pc_relevant.none-task-blog-2defaultbaidujs_baidulandingword~default-0-122364337-blog-85220910.pc_relevant_default&spm=1001.2101.3001.4242.1&utm_relevant_index=3
  • 《一看就懂系列之 详解redis的bitmap在亿级项目中的应用》:https://blog.csdn.net/u011957758/article/details/74783347?spm=1001.2101.3001.6661.1&utm_medium=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-1-74783347-blog-122364337.pc_relevant_antiscanv3&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-1-74783347-blog-122364337.pc_relevant_antiscanv3&utm_relevant_index=1
  • 《Bitmap的秘密》:http://www.infoq.com/cn/articles/the-secret-of-bitmap/
  • 《Redis内存压缩实战》:http://www.tuicool.com/articles/6nuQJzA
  • 《Redis中bitmap的妙用》:https://segmentfault.com/a/1190000008188655
  • 《Redis中BitMap是如何储存的,以及PHP如何处理》:https://segmentfault.com/a/1190000008205145
  • 《使用redis的setbit和bitcount来进行区间统计的坑》:http://blog.linuxphp.org/archives/1627/

2. Hyperloglog

Redis中的HyperLogLog是一种基于基数估算的算法,所谓基数估算就是在一批数据中不重复的元素个数有多少个。

基数计数(cardinality counting),则是指计算一个集合的基数,意即count-discint。 基数计算的场景很广泛,计算网站的访问uv,计算网络流量网络包请求header中的源地址的distinct数来作为网络攻击的重要指标。想要实现计数最直接想到的方式就是通过字典/HashSet,每条数据流入后直接保存相应的key,最后统一次集合的size就得到集基数。但是,这种方法的空间复杂度很高,在面对大数据的场景下做这样的统计代价很高。在近几十年有学者提出了很数估算的算法,在容许一定的误差的情况下,基于统计概率进行估算,本文的HyperLogLog就是一种基于基数估算的算现了不保存数据却可以实现去重计数。

在这里插入图片描述

2.1. 使用场景

  1. 统计注册ip数
  2. 统计每日访问 IP 数
  3. 统计页面实时 UV 数
  4. 统计在线用户数
  5. 统计用户每天搜索不同词条的个数

2.2. 参考

  • 《基数估计算法》:https://www.jianshu.com/p/abec15091798

3. Streams

Stream 是 Redis 5.0 引入的一种新数据类型,它以更抽象的方式对日志数据结构进行建模。然而,日志的本质仍然是完整的:就像日志文件一样,通常实现为以仅附加模式打开的文件,Redis Streams 主要是一种仅附加数据结构。至少在概念上,因为作为一种在内存中表示的抽象数据类型,Redis Streams 实现了强大的操作来克服日志文件的限制。

尽管数据结构本身非常简单,但使 Redis 流成为最复杂的 Redis 类型的原因在于它实现了额外的、非强制性的特性:一组阻塞操作允许消费者等待通过以下方式添加到流中的新数据生产者,除此之外还有一个名为Consumer Groups的概念。

消费者组最初是由流行的消息传递系统 Kafka ™ 引入的。Redis 用完全不同的术语重新实现了一个类似的想法,但目标是相同的:允许一组客户端合作消费同一消息流的不同部分。

3.1. 参考

  • 《Redis之Stream》:https://blog.csdn.net/cainiao1412/article/details/122348103

4. Bloom Filter

布隆过滤器(Bloom Filter)是 1970 年由布隆提出的,是一种非常节省空间的概率数据结构,运行速度快,占用内存小,但是有一定的误判率且无法删除元素。它实际上是一个很长的二进制向量和一系列随机映射函数组成,主要用于判断一个元素是否在一个集合中。

通常我们都会遇到判断一个元素是否在某个集合中的业务场景,这个时候我们可能都是采用 HashMap的Put方法或者其他集合将数据保存起来,然后进行比较确定,但是如果元素很多的情况下,采用这种方式就会非常浪费空间,最终达到瓶颈,检索速度也会越来越慢,这时布隆过滤器(Bloom Filter)就应运而生了。

4.1. 参考

  • 《Redis-布隆过滤器(Bloom Filter)详解》:https://blog.csdn.net/wuhuayangs/article/details/121830094
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

自己的九又四分之三站台

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值