我的编程空间,编程开发者的网络收藏夹
学习永远不晚

如何使用redis的bit位操作

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

如何使用redis的bit位操作

这篇文章主要介绍“如何使用redis的bit位操作”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“如何使用redis的bit位操作”文章能帮助大家解决问题。

本文redis试验代码基于如下环境:

操作系统:Mac OS 64位

版本:Redis 5.0.7 64 bit

运行模式:standalone mode

redis位操作

reids位操作也叫位数组操作、bitmap,它提供了SETBIT、GETBIT、BITCOUNT、BITTOP四个命令用于操作二进制位数组。

先来看一波基本操作示例

如何使用redis的bit位操作

SETBIT

语法:SETBIT key offset value

即:命令 key 偏移量 0/1

setbit命令用于写入位数组指定偏移量的二进制位设置值,偏移量从0开始计数,且只允许写入1或者0,如果写入非0和1的值则写入失败:

如何使用redis的bit位操作

GETBIT

语法:GETBIT key offset

即:命令 key 偏移量

gitbit命令用于获取位数组指定偏移量上的二进制值:

如何使用redis的bit位操作

BITCOUNT

语法:BITCOUNT key

即:命令 key

bitcount命令用于获取指定key的位数组中值为1的二进制位的数量,之前我们写入了偏移量0的值为1,偏移量10 的值为1,偏移量8的值为0:

如何使用redis的bit位操作

BITOP

语法:BITOP operation destkey key [key...]

即:命令 操作 结果目标key key1 key2 ...

bitop命令可以对多个位数组的key进行and(按位与)、or(按位或)、xor(按位异或)运算,并将运算结果设置到destkey中:

如何使用redis的bit位操作

底层数据结构分析

SDS是redis中的一种数据结构,叫做简单动态字符串(Simple Dynamic String),并且它是一种二进制安全的,在大多数的情况下redis中的字符串都用SDS来存储。

SDS的数据结构:

struct sdshdr {   #记录buff数组中已使用字节的数量   #也是SDS所保存字符串的长度   int len;   #记录buff数组中未使用字节的数量   int free;   #字节数组,字符串就存储在这个数组里   char buff[];  }

数据存储示例:

如何使用redis的bit位操作

图片来源《redis设计与实现》

SDS的优点:

  1. 鸿蒙官方战略合作共建——HarmonyOS技术社区

  2.  时间复杂度为O(1)

  3.  杜绝缓冲区溢出

  4.  减少修改字符串长度时候所需的内存重分配次数

  5.  二进制安全的API操作

  6.  兼容部分C字符串函数

关于SDS的详细介绍请大家参阅《redis设计与实现》一文。

redis中的位数组采用的是String字符串数据格式来存储,而字符串对象使用的正是上文说的SDS简单动态字符串数据结构。

如何使用redis的bit位操作

图片来源《redis设计与实现》

大家都知道的是一个字节用的是8个二进制位来存储的,也就是8个0或者1,即一个字节可以存储十进制0~127的数字,也即包含了所有的数字、英文大小写字母以及标点符号。

1Byte=8bit

1KB=1024Byte

1MB=1024KB

1GB=1024MB

位数组在redis存储世界里,每一个字节也是8位,初始都是:

0 0 0 0 0 0 0 0

而位操作就是在对应的offset偏移量上设置0或者1,比如将第3位设置为1,即:

0 0 0 0 1 0 0 0  #对应redis操作即:  setbit key 3 1

在此基础上,如果要在偏移量为13的位置设置1,即:

setbit key 13 1  #对应redis中的存储为:  0 0 1 0 | 0 0 0 0 | 0 0 0 0 | 1 0 0 0

时间复杂度

GETBIT命令时间复杂度O(1)

STEBIT命令时间复杂度O(1)

BITCOUNT命令时间复杂度O(n)

BITOP命令时间复杂度O(n)、O(n2)

我们来看GETBIT以及SETBIT命令的时间复杂度为什么是O(1),当我们执行一个SETBIT key 10086 1的值的时候,reids的计算方式如下:

获取到要写入位数组中的哪个字节:10086÷8=1260,需要写入到位数组的下标1260的字节

获取要写入到这个字节的第几位:10086 mod 8 = 6,需要写入到这个字节的下标为6即第7位上去。

通过这两种计算方式大家可以清晰的看到,位操作的GETBIT和SETBIT都是常量计算,因此它的时间复杂度为O(1)。

而BITCOUNT命令需要对整个位数组的所有元素进行遍历算出值为1的有多少个,当然redis对于大数据了的bit执行bitcount命令会有一整套复杂的优化的算法,但是核心思路还是这个意思,无非是减少部分遍历查询次数。比如以128位为一次遍历,那么他的遍历次数就是所有的位数除以128。

BITTOP命令则是根据不同的操作有不同的执行方式。比如AND操作,则需要查看位值为1的即可。

存储空间计算

根据上面的介绍,相信大家已经知道了基于redis的位数组数据结构存储的数据占用内存大小是怎么计算的了。比如有100亿的数据,那么它需要的字节数组:

1000000000÷8÷1024÷1024≈119.21MB

也就是存储10亿的数据只需要119MB左右的内存空间,这对于现在动辄16G、32G集群版的redis,完全没有问题。

需要注意的是,如果你的数据量不大,那就不要把起始偏移量搞的很大,这样也是占空间的,比如我们只需要存储几百条数据,但是其中的偏移量却很大,这就会造成了很大的内存空间浪费。

应用场景

实际项目开发中有很多业务都适合采用redis的bit来实现。

用户签到场景

每天的日期字符串作为一个key,用户Id作为offset,统计每天用户的签到情况,总的用户签到数

活跃用户数统计

用户日活、月活、留存率等均可以用redis位数组来存储,还是以每天的日期作为key,用户活跃了就写入offset为用户id的位值1。

同理月活也是如此。

用户是否在线以及总在线人数统计

同样是使用一个位数组,用户的id映射偏移量,在线标识为1,下线标识为0。即可实现用户上下线查询和总在线人数的统计

APP内用户的全局消息提示小红点

现在大多数的APP里都有站内信的功能,当有消息的时候,则提示一个小红点,代表用户有新的消息。

关于“如何使用redis的bit位操作”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识,可以关注亿速云行业资讯频道,小编每天都会为大家更新不同的知识点。

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

如何使用redis的bit位操作

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

如何使用Java操作Redis

这篇文章给大家分享的是有关如何使用Java操作Redis的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。首先让我们创建一个普通的Maven工程,添加相应的依赖
2023-06-15

怎么优雅地使用Redis位图操作

本篇内容主要讲解“怎么优雅地使用Redis位图操作”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“怎么优雅地使用Redis位图操作”吧!在进入今天的主题前,先简单地解释下Redis中的位图到底是什
2023-06-05

redis如何使用jedis连接并操作

本篇文章给大家分享的是有关redis如何使用jedis连接并操作,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。Redis是一个著名的key-value存储系统,也是nosql中
2023-05-31

java是如何操作redis的

本文详细介绍了使用Java语言操作Redis的三种方法:Jedis:轻量级、高性能客户端库,提供同步API。SpringDataRedis:基于SpringFramework,提供Spring风格的抽象。Redisson:功能丰富的客户端,提供原子操作和分布式功能。选择方法时,应考虑同步或异步操作需求、功能丰富性、与其他框架的集成等因素。本文还提供了代码示例,演示如何使用这些方法连接Redis、获取键值对和创建分布式锁。
java是如何操作redis的
2024-04-02

如何使用Node.js和Redis实现增删改查操作

这篇文章主要介绍“如何使用Node.js和Redis实现增删改查操作”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“如何使用Node.js和Redis实现增删改查操作”文章能帮助大家解决问题。什么是N
2023-07-05

Python 使用 Redis 作为缓存的操作方法

目录python 如何使用 Redis 作为缓存一、引言二、什么是 Redis?三、Redis 作为缓存的优势四、安装 Redis 和 Python Redis 库4.1 安装 Redis4.2 安装 Python Redis 库五、使用
Python 使用 Redis 作为缓存的操作方法
2024-10-11

如何使用ADO.NET操作

这篇文章主要介绍“如何使用ADO.NET操作”,在日常操作中,相信很多人在如何使用ADO.NET操作问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”如何使用ADO.NET操作”的疑惑有所帮助!接下来,请跟着小编
2023-06-17

如何使用Dapper使用Inner join的操作

这篇文章主要介绍如何使用Dapper使用Inner join的操作,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!1、新创建两张表:Users表和Product表Users表定义如下:CREATE TABLE [dbo
2023-06-29

详解Java如何利用位操作符创建位掩码

在本文中,我们来看看如何使用位操作符实现低级别的位掩码。我们将看到我们如何将一个单一的int变量作为一个单独的数据容器,感兴趣的可以跟随小编一起学习一下
2022-11-13

在spring时使用RedisTemplate如何实现连接并操作Redis

在spring时使用RedisTemplate如何实现连接并操作Redis?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。事务需要开启enableTransact
2023-05-31

如何在java中使用<<、>>进行移位操作

如何在java中使用<<、>>进行移位操作?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。<<,有符号左移位,将运算数的二进制整体左移指定位数,低位用0补齐。int left
2023-05-31

编程热搜

目录