【Redis】Redis中bitmap的原理和使用

news2024/11/24 0:24:33

文章目录

  • 一、原理
  • 二、BitMap 相关命令
  • 三、BitMap 空间计算
  • 四、使用场景
    • 1. 用户签到
    • 2. 统计活跃用户(用户登陆情况)
    • 3. 统计用户在线状态
    • 4. 实现布隆过滤器
  • 五、总结

一、原理

先声明一下:Redis 有5种数据类型,而 BitMap 在 Redis 中并不是一个新的数据类型,其底层是 Redis 实现。

通常情况下,我们在 redis 中存储一个字符串,如:“big”,它的位图如下:
在这里插入图片描述

0.001kb = 1b = 8bit

所以,字符串“big”占3个字符,也就是24个bit位。

Redis 从 2.2.0 版本开始新增了 setbit,getbit,bitcount 等几个 bitmap 相关命令。虽然是新命令,但是并没有新增新的数据类型,因为 setbit 等命令只不过是在 set 上的扩展。

利用上述命令,Redis 可以操作二进制的位,可以取/改每一个位对应的值,简单写几个:

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

通过上面的例子,我们可以发现:

  • getbit,setbit 可以对字符串进行位操作,可以获取/修改某位上的值;
  • 字符串的位修改以后,字符串本身也发生了根本变化,big -> cig。

BitMap 原本的含义是用一个 bit 位来进行0或者1的设置,映射某个元素的状态。

由于一个比特位只能表示 0 和 1 两种状态,也就是说一个 bit 能存储的最多信息量是 2,所以 BitMap 能映射的状态有限,但是使用比特位的优势是能大量的节省内存空间。

二、BitMap 相关命令

在 Redis 中,Bitmap 是一串连续的2进制数字(0或1),所以,可以把 Bitmaps 想象成一个以比特位为单位的数组,数组的每一位所在的位置为偏移(offset),数组的下标在 Bitmaps 中叫做偏移量,在 bitmap 上可执行AND,OR,XOR以及其它位操作。

# 设置值,其中value只能是 0 和 1
setbit key offset value
 
# 获取值
getbit key offset
 
# 获取指定范围内值为 1 的个数
# start 和 end 以字节为单位
bitcount key start end
 
# BitMap间的运算
# operations 位移操作符,枚举值
  AND 与运算 &
  OR 或运算 |
  XOR 异或 ^
  NOT 取反 ~
# result 计算的结果,会存储在该key中
# key1 … keyn 参与运算的key,可以有多个,空格分割,not运算只能一个key
# 当 BITOP 处理不同长度的字符串时,较短的那个字符串所缺少的部分会被看作 0。返回值是保存到 destkey 的字符串的长度(以字节byte为单位),和输入 key 中最长的字符串长度相等。
bitop [operations] [result] [key1] [keyn…]
 
# 返回指定key中第一次出现指定value(0/1)的位置
bitpos [key] [value]

三、BitMap 空间计算

因为 BitMap 中的 bit 位 是 字符串的映射,字符串在 value 中的存储是有上限的,所以 BitMap 的valu额存储空间可以用相同的方式计算。

Redis 中字符串的最大长度是 512M,所以 BitMap 的 offset (偏移量)最大值为:

512 * 1024 * 1024 * 8  =  2^32

四、使用场景

1. 用户签到

很多网站都提供了签到功能,并且需要展示最近一个月的签到情况,这种情况可以使用 BitMap 来实现。
根据日期 offset = (今天是一年中的第几天) % (今年的天数),key = 年份:用户id。

如果需要将用户的详细签到信息入库的话,可以考虑使用一个一步线程来完成。

# 2021年第一天,用户Id = userId 的用户签到
setbit 2021:userId 1 1

2. 统计活跃用户(用户登陆情况)

使用日期作为 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

3. 统计用户在线状态

如果需要提供一个查询当前用户是否在线的接口,也可以考虑使用 BitMap ,即节约空间效率又高,只需要一个 key,然后用户 id 为 offset,如果在线就设置为 1,不在线就设置为 0。

# userId 登录,设置状态为1
setbit key userId 1
 
# 获取 userId 的状态:1 - 在线;0 - 不在线
getbit key userId

4. 实现布隆过滤器

布隆过滤器解决缓存穿透。

更多关于布隆过滤器的介绍请参考我写的文章:布隆(Bloom Filter)过滤器

五、总结

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/530633.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【k8s】Ubuntu22.04离线部署k8s集群:搭建软件仓库和镜像仓库(repo节点)

上两篇主要记录了在CentOS 7环境中离线部署k8s的方案,本篇继续介绍方案二在Ubuntu 22.04的实现。(当然,整体思路还是跟上篇基本相似) 目录 Ubuntu22.04离线部署k8s集群:搭建软件仓库和镜像仓库(repo节点&am…

总结852

学习目标: 月目标:5月(张宇强化前10讲,背诵15篇短文,熟词僻义300词基础词) 周目标:张宇强化前5讲并完成相应的习题并记录,英语背3篇文章并回诵 每日必复习(5分钟&#…

云上高校导航 小程序 开发教程 1.0.1

​ Gitee仓库:云上高校导航 GitHub仓库:云上高校导航 “云上高校导航”是一套基于小程序云开发的校园导航类系统开发方案,该开发方案可供开发者进行二次开发,用于解决师生和访客的校园出行需求。 项目优势及创新:…

ChatGPT vs. Bing vs. Bard

随着 2022 年 ChatGTP 的推出,人工智能聊天机器人的世界突然走上了一条新道路。如今,密切关注 AI 的人都知道,不同公司推出了几款产品。从谷歌拥有自己的 Bard AI,到微软发布新的 Bing AI Chat,再到 OpenAI 发布GPT-4。…

云服务器搭建Python项目实现学术优化chatgpt

云服务器搭建实现学术优化chatgpt 1 服务器准备2 云服务器配置2.1 python虚拟环境2.1.1 python3.9安装配置2.1.2 下载python项目2.1.3 创建python虚拟环境 3 后台运行python项目(不然不能关闭与云服务器的连接,那意义何在?) 1 服务…

GEE:将年度NDVI时间序列影像集合(Image Collection)转变为多波段影像,并下载

作者:CSDN @ _养乐多_ 本文将重点介绍如何使用 Google Earth Engine (GEE) 将多波段影像堆叠并导出,并探讨其应用场景和好处。 通过使用 GEE 的多波段影像堆叠功能,我们可以将不同波段的遥感影像整合成一个多波段影像,以支持各种地理空间分析任务。这种方法适用于遥感影…

以太网端口类型

以太网端口有 3种链路类型:access、trunk、hybird Access类型端口只能属于1个VLAN 般用于连接计算机 端口;Trunk类型端口可以允许多个VLAN通过,可以接收和发送多个VLAN 报文,一般用于交换机之间的连接;Hybrid类型端口可以允许多个VLAN通过,可…

Dubbo的使用

Dubbo在开发中,存在两种开发思路。基于SOA(面向服务的体系架构)思想和辅助SpringCloud架构提升效率。 Dubbo 默认使用 Netty 框架 Dubbo基于SOA思想 正常SpringBoot项目是只有一个启动类,接口定义在web层(即Controller层)中,然后调用Service层。&…

Matlab 梯度下降法

一、简介 梯度下降法(Gradient descent)或最速下降法(steepest descent)是求解无约束最优化问题的一种常用方法。 假设fx)在R上具有一阶连续偏导数的函数。要求解的无约束最优化问题是。其本质是一个迭代的方法,选择…

VMware Workstation 网络备忘 + 集群规模

概述 在虚拟机中部署服务,进行IP规划,进行相关的前期准备 3 张网卡 2个不同的网段 1个NAT 概述截图 NAT 截图 VMnet0 截图 VMnet1 截图 总结: 网卡(网络适配器)名称IP网段备注NATens33192.168.139.0VMnet0ens34VMne…

手把手教你在RT-THREAD bsp上运行pikascript脚本点亮小灯

简介 这篇文章介绍如何在RT-THREAD bsp上运行pikascript脚本。 pikascript相当于一个小型的micropython。 最近有一些结构上的调整,写这篇文章大概介绍一下如何使用,以及开发过程中需要注意的问题。 这篇文章几乎适配所有的RT-THREAD上的bsp。&#xff…

在Kubernetes(K8S) 上运行第一个应用

1、启动代理 : kubectl proxy 2、部署应用程序最简单的方式是使用 kubectl run 命令,该命令可以创建所有必要的组件而无需JSON或YAML文件。 --imageluksa/kubia 显示的是指定要运行的容器镜像,--port8080 选项告诉Kubernetes应用正在监听808…

每日一算-冒泡排序

冒泡排序是最简单的排序算法,如果相邻元素的顺序错误,则通过重复交换它们来工作。该算法不适用于大数据集,因为它的平均和最坏情况时间复杂度都很高。 原理 输入: arr[] {6, 3, 0, 5} 第一步: 冒泡排序从最前面的两个…

每日一算-选择排序算法

大家好,我是易安! 今天我们开始每日一算的篇章,今天带来的是选择算法。 选择排序是一种简单而高效的排序算法,它通过从列表的未排序部分中重复选择最小(或最大)元素并将其移动到列表的已排序部分来工作。该…

Kubernetes集群安全加固

本博客地址:https://security.blog.csdn.net/article/details/130678814 一、系统账户加固 1、对账户的登录次数进行检查,连续超过3次登录失败后,对用户锁定150s # 每个设备上都运行 sed -i~ 2iauth required pam_faillock.so deny3 unloc…

玩转Google开源C++单元测试框架Google Test系列(gtest)之五 - 死亡测试

一、前言 “死亡测试”名字比较恐怖,这里的“死亡”指的的是程序的崩溃。通常在测试过程中,我们需要考虑各种各样的输入,有的输入可能直接导致程序崩溃,这时我们就需要检查程序是否按照预期的方式挂掉,这也就是所谓的…

CBFS Shell .NET 22.0.85 Crack

使用虚拟文件夹、自定义菜单、工具栏、详细信息列等扩展和自定义 Windows 资源管理器! CBFS Shell 窗口资源管理器自定义 使用 CBFS Shell 为您的用户扩展 Windows 资源管理器。定义用户如何与文件和文件夹交互、自定义上下文菜单、添加信息列等。与可能导致资源管…

详细解释什么是LNMP架构

LNMP(Linux-Nginx-MySQL-PHP)是一种常见的Web服务器架构,适用于中小型网站和应用。 它包括四个核心组件: 1. Linux:LNMP架构是在Linux操作系统上运行的。通常选择Ubuntu、Debian等基于Debian的发行版作为Linux系统。 2. Nginx:Nginx是一个高性能的Web服…

支付系统设计三:支付网关设计09-总结

文章目录 前言一、设计目标二、设计实现1. 开发框架2. 配置管理后台3. 屏蔽渠道差异4. 各阶段工作内容4.1 业务处理前期准备阶段4.2 业务处理阶段4.2.1 交易处理模板获取4.2.2 参数验证4.2.3 幂等性验证4.2.4 交易数据准备服务获取4.2.5 路由处理4.2.6 支付渠道数据补全4.2.7 交…

Docker高级(完结)

一、DockerFile DockerFile简介 Docker是用来构建Docker镜像文件,由一条条docker指令和参数构成的脚本。 DockerFile构建过程 小总结 从应用软件的角度来看,Dockerfile、Docker镜像与Docker容器分别代表软件的三个不同阶段, Dockerfile是…