redis通过位图法记录在线用户的状态详解

 更新时间:2018年11月05日 14:08:18   作者:小草莓子桑  
这篇文章主要给大家介绍了关于redis如何通过位图法记录在线用户的状态的相关资料,文中先对位图进行了一个简单的介绍,而后通过示例代码将实现的方法介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

前言

在进入今天的主题前,先简单地解释下Redis中的位图到底是什么。Redis官方文档对于位图的介绍如下:

位图不是一个真实的数据类型,而是定义在字符串类型上的面向位的操作的集合。由于字符串类型是二进制安全的二进制大对象,并且最大长度是 512MB,适合于设置 2^32个不同的位。

位操作分为两组:常量时间单个位的操作,像设置一个位为 1 或者 0,或者获取该位的值。对一组位的操作,例如计算指定范围位的置位数量。

位图的最大优势是有时是一种非常显著的节省空间来存储信息的方式。例如,在一个系统中,不同用户由递增的用户 ID 来表示,可以使用 512MB 的内存来表示 400 万用户的单个位信息(例如他们是否需要接收信件)。

简而言之,位图操作是用来操作比特位的,其优点是节省内存空间。为什么可以节省内存空间呢?假如我们需要存储100万个用户的登录状态,使用位图的话最少只需要100万个比特位(比特位1表示登录,比特位0表示未登录)就可以存储了,而如果以字符串的形式存储,比如说以userId为key,是否登录(字符串“1”表示登录,字符串“0”表示未登录)为value进行存储的话,就需要存储100万个字符串了,相比之下使用位图存储占用的空间要小得多,这就是位图存储的优势。

这几天在工作中,遇到一个case,就是需要自己实现一个IM在线用户状态的记录,当时查了很多中实现方式,今天来分享一下

主要思想

构造一个位图,里面存的是二进制数据,如:1 0 1 0 1 0 1,通过修改userId对应位置上的0和1来修改用户在线状态,由于默认值为0,所以1代表用户处于在线状态,0代表用户处于离线状态,如图:


构造了Mon、Thus、Web三个位图

构造了Mon、Thus、Web三个位图,对于Mon来说,userId=1的用户处于在线状态,userId=2的用户处于离线状态,userId=3的用户处于在线状态,当userId=10的用户上线后,就把第10位上值变成1

空间预估

二进制数据1位为1bit

1千兆字节(gb)=8589934592比特(bit)

理论上1G的内存可以记录85亿多的用户状态,如果userId不连贯,有的userId位数超过85亿位,可以使用一些算法、或者对userId按位分段来解决

使用命令

setbit key offset value 修改key中,第offset位的值为value

Setbit

getbit key offset 获取key中,第offset位上的value

getbit

bitcount key 统计key中,1的个数

bitcount

bitop op destKey key1 key2 ….. 其中op可以为AND(于)、OR(或)、NOT(非)、XOR(异或)
命令的主要作用是,给key1、key2..等,这种二进制数据,按位做逻辑运算,结果付到destkey中,没有setbit的位置默认为0

举个栗子

构造了Mon、Thus、Web三个位图,作为近三天登录状态的位图


构造了Mon、Thus、Web三个位图

第一天
userId=10000,userId=9999,userId=8888的用户登录了

setbit mon 10000 1; 
setbit mon 9999 1; 
setbit mon 8888 1; 

统计第一天在线用户量

bitcount mon

有三个用户登录

第一天有三个用户登录

第二天

userId=9999,userId=7777的用户登录了

setbit thus 9999 1; 
setbit thus 7777 1;

获取userId=7777用户在线状态

getbit thus 7777

7777用户处于登录状态

第三天
userId=9999,userId=6666的用户登录了

setbit web 9999 1;  
setbit web 6666 1;

获取三天都登录的用户数

bitop and resultand mon thus web;

获取三天都登录的用户数

获取三天内登陆过的用户数

bitop or resultor mon thus web;

获取三天内登陆过的用户数

redis使用位图法记录在线用户的状态就为大家说到这里,欢迎大家来交流,指出文中一些说错的地方,让我加深认识。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对脚本之家的支持。

相关文章

  • Redis数据结构原理浅析

    Redis数据结构原理浅析

    这篇文章主要为大家介绍了Redis数据结构原理浅析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-02-02
  • Redis Redisson lock和tryLock的原理分析

    Redis Redisson lock和tryLock的原理分析

    这篇文章主要介绍了Redis Redisson lock和tryLock的原理分析,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-04-04
  • 解析Redis 数据结构之简单动态字符串sds

    解析Redis 数据结构之简单动态字符串sds

    Redis 的 string 类型为何使用sds而不是 C 字符串,本文主要介绍 string 的数据结构—— 简单动态字符串(Simple Dynamic String) 简称sds的相关知识,需要的朋友可以参考下
    2021-11-11
  • Redis中有序集合的内部实现方式的详细介绍

    Redis中有序集合的内部实现方式的详细介绍

    本文主要介绍了Redis中有序集合的内部实现方式的详细介绍,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-03-03
  • 浅谈redis采用不同内存分配器tcmalloc和jemalloc

    浅谈redis采用不同内存分配器tcmalloc和jemalloc

    下面小编就为大家带来一篇浅谈redis采用不同内存分配器tcmalloc和jemalloc。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-12-12
  • Windows下搭建Redis集群的方法步骤

    Windows下搭建Redis集群的方法步骤

    本文主要介绍了Windows下搭建Redis集群的方法步骤,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-03-03
  • Redis主从复制问题和扩容问题的解决思路

    Redis主从复制问题和扩容问题的解决思路

    这篇文章主要介绍了Redis主从复制问题和扩容问题的解决思路,其中扩容问题的解决思路来自Redis作者,需要的朋友可以参考下
    2014-06-06
  • 关于Redis数据库入门详细介绍

    关于Redis数据库入门详细介绍

    大家好,本篇文章主要讲的是关于Redis数据库入门详细介绍,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下,方便下次浏览
    2021-12-12
  • 详解Redis实现限流的三种方式

    详解Redis实现限流的三种方式

    这篇文章主要介绍了详解Redis实现限流的三种方式,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-04-04
  • redis缓存延时双删的原因分析

    redis缓存延时双删的原因分析

    延时双删就是在增删改某实体类的时候,要对该实体类的缓存进行清空,清空的位置在数据库操作方法的前后,这篇文章主要介绍了redis缓存为什么要延时双删,需要的朋友可以参考下
    2022-08-08

最新评论