如何理解Redis中的二进制数组(bitmap)

690 阅读3分钟
  • 前言

  • 1. bitmap

  • 1.1. bitmap是什么?

  • 2.redis相关命令

  • 2.1. SETBIT

  • 2.2 GETBIT

  • 2.3 BITCOUNT

  • 2.4 BITOP

前言

1. bitmap

1.1. bitmap是什么

redis中的bitmap跟实际所理解的bitmap是相同的都是一种按位运算的一种结构,这种结构图如下:

image.png

所以在bitmap中存储的就是0或者1,用来标识是或者否,以用户登录为例,要统计微信内有多少用户登录,那么如果用户登录就设置对应位中的数据为1,并且是按照自增进行设置,要统计有多少用户登录时就可以将bitmap中所有的数据进行计算得到所有登录的用户(如果刷过剑指offer可以知道这样的计算就是统计一个二进制中所有1的个数)。

而redis中也是通过这样的结构来实现对应的需求。并且redis还提供了SETBIT、GETBIT、BITCOUNT、BITOP四个命令用于处理bitmap数组。

2. redis相关命令

2.1. SETBIT

SETBIT用于为数组指定偏移量上的二进制位设置值,位数组的偏移量从0开始计数,而二进制的值则可以是0或者1

命令使用如下:

image.png

我设置名为bit的数组偏移量为0的二进制值为1,因此可以将bit理解为0001;

image.png

设置bit数组偏移量为3的二进制位1,那么可以将bit理解为1001;

2.2. GETBIT

GETBIT用于获取位数组指定偏移量上的二进制位的值:命令在上图中已展示。

2.3. BITCOUNT

BITCOUNT命令用于统计位数组里面值为1的二进制的数量

image.png

如上图中通过命令获取了bit数组中1的值,我们知道在对位进行计算时性能是很高的,所以直接通过位运算得到1的个数在性能上有很大的提升,这里具体如何计算的可以参考剑指offer15题:leetcode-cn.com/problems/er…

2.4. BITOP

BITOP命令可以对多个位数组按位与(and)、按位或(or)、按位异或(xor)运算:

image.png

上图中设置bit数组的数据结果为:1001

bit2数组的数据结构为:1101

通过bitop对bit和bit2做and运算后得到1001;做or运算后1101

bitop操作可以实际应用在如下场景:

如统计连续三天登录的用户数量,这时可以每天设置一个位数组,

例如20201208是一个位数组,20201209是一个位数组,20201210是一个位数组。

填充数据如下,那么我要统计连续三天登录的用户,那么对三个位数组进行操作,得到最终的数据然后统计1的个数即可得到连续三天登录用户的数量,下图中会统计出两个用户。

image.png

以上就是redis中关于如何使用bitmap记录,要将bitmap联系到实际场景更容易理解其中的实现方式以及原理。

关于GETBIT、SETBIT、BITCOUNT、BITOP的实现原理下一章节继续研究!

参考资料:

  1. 《redis的设计与实现》