Redis 位图BitMap

应用场景:

  1. 用户签到
  2. 用户在线状态
  3. 统计活跃用户
  4. 各种状态值
  5. 自定义布隆过滤器
  6. 点赞功能

说明:

用string类型作为底层数据结构实现的一种统计状态的数据类型。

位图本质是数组,它基于string数据类型的按位操作。该数组由多个二进制位组成,每个二进制位都对应一个偏移量(可以成为一个索引或者位格)。Bitmap支持的最大位数是2^32位,它可以极大的节省存储空间,使用512M内存就可以存储42.9亿的字节信息(2^32=4294967296)

Redis 位图BitMap

举例:

拿签到功能举例,比如京东的签到,估算3000万签到用户,一天一条数据,一个月就是9亿条,存储在mysql会很恐怖。

如何解决这个痛点?

  1. 一条签到记录对应一条记录,会占据越来越大的空间。
  2. 一个月最多31天,刚好int类型是32位,这样一个int类型就可以搞定一个月,32位大于31天,当天签到了就是1,没签到就是0
  3. 一条数据直接存储一个月的记录,不再存储一天的签到记录。

按年去存储一个用户的签到情况,365天只需要365/8≈46byte,1000w用户量一年也只需要44MB足够。

假如是亿级的系统,每天使用1个1亿位的Bitmap约占12M的内存(10^8/8/1024/1024),10天Bitmap的内存开销约为120MB,内存压力不算太高。在实际使用时,最好对Bitmap设置过期时间,让redis自动删除后而不再需要的签到记录节省内存开销。

Redis 位图BitMap
//用户1,10月份第三天签到,设置为1
127.0.0.1:6379> setbit sign:u1:10 3 1
(integer) 0
127.0.0.1:6379> setbit sign:u1:10 30 1
(integer) 0
127.0.0.1:6379> getbit sign:u1:10 0 //获取10月份第一天,没签到返回0
(integer) 0
127.0.0.1:6379> getbit sign:u1:10 3
(integer) 1
127.0.0.1:6379> bitcount sign:u1:10 //签到总天数
(integer) 2
127.0.0.1:6379>

用户签到场景

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

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

用户是否在线以及总在线人数统计
同样是使用一个位数组,用户的id映射偏移量,在线标识为1,下线标识为0。即可实现用户上下线查询和总在线人数的统计
APP内用户的全局消息提示小红点
现在大多数的APP里都有站内信的功能,当有消息的时候,则提示一个小红点,代表用户有新的消息。

位图计数:
位图计数 的意思是统计bitmap中值为1的位的个数,位统计的效率时很高的。
redis中允许使用二进制的key和二进制的value,bitmap就是二进制的value。

点赞/取消点赞:
假设用户ID为100,对照片ID为100的照片进行点赞。首先根据照片ID生成数据存储的redis key,比如生成策略是like_photo:{photo_id},用户ID为1000的用户点赞只需将like_photo:100的第1000位设置为1即可(取消置为0)。
redis setbit操作的时间复杂度为O(1),所以这种点赞方式十分高效。
当前是否点赞:
用户打开图片的时候需要查询当前是否点赞过该照片,查询是否点赞可以通过redis getbit操作实现。

查询点赞总次数:
比如需要显示照片ID为1000的照片的获赞总次数,只需对like_photo:1000进行位图计数操作即可:bitcount。时间复杂度为O(N)。个人以为可以在照片表中加一个字段记录获赞总次数,这样就不用循环统计各个照片的获赞次数。

Original: https://www.cnblogs.com/yszr/p/16395781.html
Author: 御世制人
Title: Redis 位图BitMap

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/529046/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • Redis 持久化

    Redis 提供了一系列不同的持久性选项: RDB(Redis 数据库):RDB 持久性以指定的时间间隔执行数据集的时间点快照。 AOF(Append Only File):AOF…

    Linux 2023年5月28日
    083
  • Windows 添加nginx到服务

    一、下载nginx 地址:http://nginx.org/en/download.html (稳定版) 解压到相应的磁盘,本文是:E:\nginx\nginx-1.18.0 二、…

    Linux 2023年6月8日
    0117
  • Spring的循环依赖

    本文简要介绍了循环依赖以及Spring解决循环依赖的过程 循环依赖是指对象之间的循环依赖,即2个或以上的对象互相持有对方,最终形成闭环。这里的对象特指单例对象。 对象之间的循环依赖…

    Linux 2023年6月8日
    0148
  • mysql-高可用架构:MHA

    mysql-高可用架构:MHA 1. MHA简介 MHA(Master High Availability)是由日本人yoshinorim开发的一款成熟且开源的MySQL高可用程序…

    Linux 2023年6月13日
    090
  • mysql select语句查询流程是怎么样的

    mysql select查询的数据是查询内存里面,如果没有查询的数据没有在内存,就需要mysql的innodb引擎读取磁盘,将数据加载的内存后在读取。这就体现了,mysql查询大量…

    Linux 2023年6月8日
    0100
  • 理清计算机中的数据表示方法–2’s complement

    Bits bits是信息的基本单元,计算机通过电压的高低来确定是0还是1;这里的电压是有一定范围的,0~a视为0, a~b视为1,具体数字不用记 Data Types 同一个数字有…

    Linux 2023年6月6日
    099
  • Linux通过ssh命令连接远程服务器

    命令使用语法:1,指定用户:ssh -l root 192.168.0.11或则ssh root@192.168.0.11 2,如果修改过ssh登录端口的可以:ssh -p 123…

    Linux 2023年6月13日
    080
  • 每天一个 HTTP 状态码 前言

    HTTP 状态码由 3 位阿拉伯数字构成,其中第一位用于定义 HTTP 响应的类型… 前前言 在重新开始写博文(其实大多也就最多算是日常笔记小结)之际,就想着从短小精悍…

    Linux 2023年6月7日
    095
  • postgresql强制删除数据库

    sql;gutter:true; SELECT pg_terminate_backend(pg_stat_activity.pid) FROM pg_stat_activity W…

    Linux 2023年6月8日
    092
  • 关闭linux内核反向路由

    route -n Kernel IP routing tableDestination Gateway Genmask Flags Metric Ref Use Iface0.0….

    Linux 2023年6月8日
    0108
  • centos7中防火墙转为iptables

    1、关闭firewall systemctl stop firewalld.service #停止firewall systemctl disable firewalld.serv…

    Linux 2023年6月6日
    092
  • [云原生]Kubernetes-Service详解(第7章)

    * – 一、Service介绍 – 二、Service类型 – 三、Service使用 + 3.1 实验环境准备 + 3.2 ClusterIP…

    Linux 2023年6月13日
    0113
  • Kafka入门实战教程(8):常用的shell工具脚本

    1 Kafka提供的命令行脚本 Kafka默认提供了多个命令行脚本,用于实现各种各样的功能和运维管理。从2.2版本开始,提供了多达30+个Shell脚本。 今天我们来看一些其中比较…

    Linux 2023年5月28日
    0110
  • Django中自定义管理器Manager用法

    Django中Manager用法 第一种 class create_user(models.Manager): def create(self, name, sex, age): …

    Linux 2023年6月14日
    096
  • 浅谈缓存击穿、缓存穿透、缓存雪崩、缓存预热、缓存降级

    对于缓存,大家肯定都不陌生,不管是前端还是服务端开发,缓存几乎都是必不可少的优化方式之一。在实际生产环境中,缓存的使用规范也是一直备受重视的,如果使用的不好,很容易就遇到缓存击穿、…

    Linux 2023年6月14日
    0104
  • k8s 常用命令

    查看所有 pod 列表, -n 后跟namespace,查看指定的命名空间 查看 RC 和service 列表,-o wide 查看详细信息 显示 Node 的详细信息 显示 Po…

    Linux 2023年5月27日
    0123
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球