redis数据类型 String、Set、Zset、List、hash       Bitmap 。

四种统计类型:

  1. 二值状态统计;
  2. 聚合统计;
  3. 排序统计;
  4. 基数统计

二值状态统计:

就是集合中的元素的值只有 0 和 1 两种,在签到打卡和用户是否登陆的场景中,只需记录签到(1)或 未签到(0)已登录(1)未登陆(0)

在判断用户是否登陆的场景中使用 Redis 的 String 类型实现(key -> userId,value -> 0 表示下线,1 - 登陆),假如存储 100 万个用户的登陆状态,如果以字符串的形式存储,就需要存储 100 万个字符串了,内存开销太大。【注;String 类型除了记录实际数据以外,还需要额外的内存记录数据长度、空间使用等信息。】

当保存的数据包含字符串,String 类型就使用简单动态字符串(SDS)结构体来保存,如下图所示:

<SDS>

  • len:占 4 个字节,表示 buf 的已用长度。
  • alloc:占 4 个字节,表示 buf 实际分配的长度,通常 > len。
  • buf:字节数组,保存实际的数据,Redis 自动在数组最后加上一个 “\0”,额外占用一个字节的开销。

所以,在 SDS 中除了 buf 保存实际的数据, len 与 alloc 就是额外的开销。

另外,还有一个 RedisObject 结构的开销,因为 Redis 的数据类型有很多,而且,不同数据类型都有些相同的元数据要记录(比如最后一次访问的时间、被引用的次数等)。

所以,Redis 会用一个 RedisObject 结构体来统一记录这些元数据,同时指向实际数据。

对于二值状态场景,我们就可以利用 Bitmap 来实现。比如登陆状态我们用一个 bit 位表示,一亿个用户也只占用 一亿 个 bit 位内存 ≈ (100000000 / 8/ 1024/1024)12 MB

Bitmap 的底层数据结构用的是 String 类型的 SDS 数据结构来保存位数组,Redis 把每个字节数组的 8 个 bit 位利用起来,每个 bit 位 表示一个元素的二值状态(不是 0 就是 1)。

可以将 Bitmap 看成是一个 bit 为单位的数组,数组的每个单元只能存储 0 或者 1,数组的下标在 Bitmap 中叫做 offset 偏移量。

Bitmap 提供了 GETBIT、SETBIT 操作,通过一个偏移值 offset 对 bit 数组的 offset 位置的 bit 位进行读写操作,需要注意的是 offset 从 0 开始。

只需要一个 key = login_status 表示存储用户登陆状态集合数据, 将用户 ID 作为 offset,在线就设置为 1,下线设置 0。通过 GETBIT判断对应的用户是否在线。50000 万 用户只需要 6 MB 的空间。

命令:

SETBIT 命令

SETBIT <key> <offset> <value>

设置或者清空 key 的 value 在 offset 处的 bit 值(只能是 0 或者 1)。

GETBIT 命令

GETBIT <key> <offset>

获取 key 的 value 在 offset 处的 bit 位的值,当 key 不存在时,返回 0。

======》

Redis 提供了 BITPOS key bitValue [start] [end]指令,返回数据表示 Bitmap 中第一个值为 bitValue 的 offset 位置

Redis -使用 Bitmap的更多相关文章

  1. 基于Redis分布式BitMap的应用

    一.序言 在实际开发中常常遇到如下需求:判断当前元素是否存在于已知的集合中,将已知集合中的元素维护一个HashSet,使用时只需耗时O(1)的时间复杂度便可判断出结果,Java内部或者Redis均提供 ...

  2. Redis中bitmap的妙用

    BitMap是什么 就是通过一个bit位来表示某个元素对应的值或者状态,其中的key就是对应元素本身.我们知道8个bit可以组成一个Byte,所以bitmap本身会极大的节省储存空间. Redis中的 ...

  3. 5、分布式缓存Redis之bitmap、setbit

    基本语法: 1)SETBIT redis 127.0.0.1:6379> setbit KEY_NAME OFFSET VALUE //该命令用于对 key 所储存的字符串值,设置或清除指定偏移 ...

  4. redis的bitmap

    BitMap是什么 就是通过一个bit位来表示某个元素对应的值或者状态,其中的key就是对应元素本身.我们知道8个bit可以组成一个Byte,所以bitmap本身会极大的节省储存空间. Redis中的 ...

  5. Redis 中 BitMap 的使用场景

    BitMap BitMap 原本的含义是用一个比特位来映射某个元素的状态.由于一个比特位只能表示 0 和 1 两种状态,所以 BitMap 能映射的状态有限,但是使用比特位的优势是能大量的节省内存空间 ...

  6. Redis的bitmap从基础到业务

    1. 位与字节 1个字节(byte)等于8个位(bit).(计算机常识). 2. string与bitmap Redis里的bitmap是属于string这个数据类型里的.可以help进行查看bit相 ...

  7. redis位图(bitmap)常用命令的解析

    描述   bitmap是redis封装的用于针对位(bit)的操作,其特点是计算效率高,占用空间少,常被用来统计用户签到.登录等场景 常用命令及解析 常用命令 setbit key offset va ...

  8. 利用redis的bitmap实现用户签到功能

    一.场景需求 适用场景如签到送积分.签到领取奖励等,大致需求如下: 比如签到1天送1积分,连续签到2天送2积分,3天送3积分,3天以上均送3积分等. 如果连续签到中断,则重置计数,每月初重置计数. 显 ...

  9. Redis实战篇(二)基于Bitmap实现用户签到功能

    很多应用上都有用户签到的功能,尤其是配合积分系统一起使用.现在有以下需求: 签到1天得1积分,连续签到2天得2积分,3天得3积分,3天以上均得3积分等. 如果连续签到中断,则重置计数,每月重置计数. ...

随机推荐

  1. idea数据库报错java.lang.ClassNotFoundException: com.mysql.jdbc.Driver

    通过idea操作数据库,进行数据的增加,运行时报错java.lang.ClassNotFoundException: com.mysql.jdbc.Driver 原因:没有导入mysql-connec ...

  2. 零基础学习java------26--------获取省访问量的top3,APP版本数据分析,事务,json,json字符串与对象间的相互转换,求电影平均分

    一. day23中的ip,url案例(前面答案错了) 思路分析: 1.创建javabean,用来存储ip.txt各字段的信息 2. 创建java工具类,封装相应的方法 (1) 加载读取ip.txt文档 ...

  3. C++异常处理(try、catch、throw)

    本文为转载 博主原文连接 我们通常希望自己编写的程序能够在异常的情况下也能作出相应的处理,而不至于程序莫名其妙地中断或者中止运行了.在设计程序时应充分考虑各种异常情况,并加以处理. 在C++中,一个函 ...

  4. spring定时任务执行两次

    最近用Spring的quartz定时器的时候,发现到时间后,任务总是重复执行两次,在tomcat或jboss下都如此. 打印出他们的hashcode,发现是不一样的,也就是说,在web容器启动的时候, ...

  5. vue SCSS

        C:\eclipse\wks\vue\esql-ui>node -v v12.18.1 C:\eclipse\wks\vue\esql-ui>npm -v 6.14.5 直接修改p ...

  6. 优化 if-else 代码的 8 种方案

    前言 代码中如果if-else比较多,阅读起来比较困难,维护起来也比较困难,很容易出bug,接下来,本文将介绍优化if-else代码的八种方案. 方案. 优化方案一:提前return,去除不必要的el ...

  7. Oracle 创建 md5 加密函数

    使用 Oracle 的 utl_raw.DBMS_OBFUSCATION_TOOLKIT 可以获取 md5 加密字符串: select utl_raw.cast_to_raw(DBMS_OBFUSCA ...

  8. docker之镜像制作

    #:下载镜像并初始化系统 root@ubuntu:~# docker pull centos #:创建目录 root@ubuntu:/opt# mkdir dockerfile/{web/{nginx ...

  9. SpringBoot java配置类@Configuration 的两种写法

    首先在Springboot项目中,件一个java类,使用注解@Configuration  ,则这个类是SpringBoot bean的创建的配置文件类,,这种配置文件类有两种写法 1.使用包扫描 , ...

  10. Linux:$?,$n,$#,$0

    $? 获取执行上一个指令的返回值(0为成功,非零为失败) $n 获取当前执行的shell脚本的第n个参数值,n=1...9,当n=0的时表示脚本的文件名,如果n大于9,大括号括起来${10} $# 获 ...