专注Java教育14年 全国咨询/投诉热线:400-8080-105
动力节点LOGO图
始于2009,口口相传的Java黄埔军校
首页 hot资讯 Redis数据结构:位图

Redis数据结构:位图

更新时间:2022-11-09 09:35:41 来源:动力节点 浏览594次

位图是当需要将巨大域的布尔信息映射为紧凑表示时立即出现在您脑海中的数据结构。当内存空间非常宝贵时,它是一种非常流行的数据结构。Redis 作为内存数据结构服务器,提供对位操作操作的支持。

中的数据结构。当内存空间非常宝贵时,它是一种非常流行的数据结构:操作系统内核(内存页、inode 等)、数字成像等。

Redis 作为内存数据结构服务器,提供对位操作操作的支持。但是, Redis 中的位图没有特殊的数据结构 。相反,基本 Redis 结构支持位级操作: 字符串。现在,Redis 字符串的最大长度为 512 MB。因此,Redis 可以映射为 Bitmap 的最大域是 2 32 (512 MB = 2 29 字节 = 2 32 位)。

Redis 中与位相关的操作有两种:恒定时间 (O(1)),例如获取/设置特定位的操作,以及基本上对一组位进行操作的 O(N) 操作。在这些情况下,N 是操作需要处理的位长度。让我们看一些例子。

命令

#  SETBIT  key  offset  value :在'key'的偏移'offset'处存储 位 值 'value  ' 。欧( 1 )    
# 返回 存储在该偏移处的 原始 位 值 。   
127.0 . 0.1 : 6379 > 设置位 k  10  1
(整数) 0
#  GETBIT  key  offset :在'key'中获取 'offset'的值 。欧( 1 )   
127.0 . 0.1 : 6379 > 获取比特 k  10
(整数) 1
127.0 . 0.1 : 6379 > 获取位 k  11
(整数) 0
127.0 . 0.1 : 6379 > 获取位 k  0
(整数) 0
127.0 . 0.1 : 6379 > 设置位 k  9  1
(整数) 0
127.0 . 0.1 : 6379 > 设置位 k  8  1
(整数) 0
# 因为它仍然是一个通用的String , 所以这里是一个 get 。      
127.0 . 0.1 : 6379 > 得到 k
"\x00\xe0"
#  "\x00\xe0"  ->  "0000 0000 111"
#BITCOUNT  key [ start end ] :范围内设置的位数。_  _ 欧( ñ )       
# 重要:开始 和 结束 是 字节 而不是 位
127.0 . 0.1 : 6379 > 比特 数 k
(整数) 3
127.0 . 0.1 : 6379 > 设置 m  “喵”
好的
# 喵 ->  01101101  01100101  01101111  01110111 
127.0 . 0.1 : 6379 > 位数 m
(整数) 21
#  BITPOS  key  bit [ start ] [ end ] : key in range中1或0的第 一个位置 。欧( ñ )        
127.0 . 0.1 : 6379 > 设置我的密钥“\  xff  \xf0\x00”
好的
127.0 . 0.1 : 6379 >  BITPOS  mykey  0
(整数) 12

除了对键本身起作用的运算符外,BITOP 运算符还用于多个键之间的按位逻辑运算。

#  BITOP 操作 destkey  key [ key ...]. 欧( ñ )
# 运算 可以 是  AND , OR , XOR 和 NOT
127.0 . 0.1 : 6379 > 设置 一个 “\xff\xff”
好的
127.0 . 0.1 : 6379 >  bitop 不是 nota  _
(整数) 2
127.0 . 0.1 : 6379 > 得到 通知
"\x00\x00"
127.0 . 0.1 : 6379 > 设置 b  "\x0f\x0f"
好的
127.0 . 0.1 : 6379 > 设置 c  "\xf0\xf0"
好的
127.0 . 0.1 : 6379 >  BITOP 或 orbc  b  c
(整数) 2
127.0 . 0.1 : 6379 > 获得 orbc
"\xff\xff"
127.0 . 0.1 : 6379 >  BITOP  AND  andbc  b  c
(整数) 2
127.0 . 0.1 : 6379 > 得到 andbc
"\x00\x00"
127.0 . 0.1 : 6379 >  BITOP  XOR  xorbc  b  c
(整数) 2
127.0 . 0.1 : 6379 > 得到 xorbc
"\xff\xff"

内件

由于位图操作没有自己的数据结构,因此没有特殊的数据结构可以描述。Redis 字符串本身是作为二进制安全字符串实现的。Redis 字符串数据结构内部称为简单动态字符串(SDS)。它本质上是一个带有一些额外簿记信息的原生 char []。

位图函数的实现在文件 bitops.c中。

PS 鉴于位操作算法对关键操作系统和图形功能的重要性,大多数架构都为此类操作提供了特殊指令。阅读各种有趣的计算机算术算法的好地方是永恒的经典 Hacker's Delight。

应用

这个 流行的 GetSpool 博客 是使用位图对大型数据集进行实时分析的一个很好的例子。它也是位图经典用例的一个示例:将极大域的布尔信息存储到(相对)较小的空间中,同时保持良好的性能。

尺寸通常是非常大的位图的一个问题,因为对其最有用的操作是 O(N)。为了避免使用大键,Redis 文档 建议 将大键拆分为多个较小的键。在密钥变大之前,BITCOUNT 性能仍然可以接受。此时,建议是拆分键或使用范围参数进行增量查询。 处理缓慢的 BITOP 操作的 建议是在从站上运行它。因此,一般来说,处理中等大小的密钥并通过将密钥拆分为多个密钥来规划未来的潜在增长是有意义的。

Redis 集合与 Redis 位图

Redis Sets 和位图操作提供的功能本质是相似的。所以经常混淆这两种方法中的哪一种更好。好吧,这实际上取决于用例的确切性质。显然,这个讨论只对集合和位图都可以实现的那种操作有效。

Redis Sets 通常是高效且可扩展的,并且应该是首选的数据结构,直到它的大小变得难以为继。Redis Set 也更易于管理,编程和调试适用于大多数应用程序。不应低估 Set 的易用性:操作位图的代码通常难以阅读、理解、调试和维护。即使域非常大,集合仍然可能是合适的。例如,如果一个应用程序旨在跟踪对热门电子商务网站的每日访问量,那么结果可能仍然很适合一组,因为通常只有 5-10% 的整个用户群会每天访问该网站。对于预计 60% 的整个用户群每天登录的网站来说,这显然会发生变化。然后,考虑到对大量键的逻辑按位操作的大小和性能,位图变得更加相关。Redis Set 还具有不必将 ID 映射到位偏移量的明显优势。同样,如果您的值来自大于 2 的域32 那么Redis Sets必须比找出机制来分割位图的域更容易使用。

MOOC 的分析

这是一个编造的(但足够真实!)示例,用于可能应用 Redis 位图操作的地方。假设您正在运行一个非常受欢迎的在线 MOOC ,成千上万的学生已经注册了该 MOOC。促进课程的学术团队想要一个仪表板,他们可以在其中查看学生进度的实时状态以及注册学生的一般背景。您决定通过 Redis 位图操作来实现这一点。这是一个逐步的方法。

创建一个计划以在学生 ID 和位图偏移之间进行映射。它可以像 ID 作为位图中的偏移量一样简单。

课程开始后,创建和填充各种与人口统计相关的位图。例如,在同一所大学注册其他 MOOC 的学生、教育水平、性别等。

现在随着课程的进行,您可以创建新的位图来记录课程进度。例如,完成第一周所有讲座的学生,完成第一周所有作业的学生等。

现在,基于这些键创建实时分析将是一个非常简单的练习,并且可以在拖放 UI 上完成。例如

一位教授想看看有多少学生观看了第一周(A)的讲座,但没有完成第一周(B)的作业:操作员:BITOP。操作:A AND(非 B)。

完成第 1 周 (A)、第 2 周 (B)、第 3 周 (C) 和第 4 周 (D) 的所有作业的学生:操作员:BITOP。操作 A AND B AND C AND D. 说,这些是通过课程的人。

通过课程的所有男学生(M)(如上计算,比如说,P):操作员:BITOP。操作:M AND P。

通过课程的学生人数:BITCOUNT P.

类似地,可以将任意数量的有趣群组设置为位图,并在其上运行此类排列。

以上就是关于“Redis数据结构:位图”介绍,如果大家想了解更多相关知识,不妨来关注一下本站的Redis教程,里面还有更丰富的知识等着大家去学习,希望对大家能够有所帮助。

提交申请后,顾问老师会电话与您沟通安排学习

免费课程推荐 >>
技术文档推荐 >>