美文网首页
Redis中的位操作

Redis中的位操作

作者: lfboo | 来源:发表于2021-11-21 14:31 被阅读0次

简介

redis的五种数据类型相信大家都非常清楚了,任何人问你基本都能脱口而出(string,hash,list,set,zset)。如果还不清楚,建议先看看redis基础,但是还有这几种类型很多人会忽略到。比如 Setbit(位操作),GEO(地理位置信息)等等。

今天我们就来看一看setbit,看一看实际场景中到底是怎么用的,以及有哪些优势?
我们先来回顾一下setbit吧,大家知道位操作,只有两个值,0和1,8个位正好是1b,所以位操作是非常节省空间的一种操作。
setbit用法:

redis> SETBIT bit 10086 1  #把第10086个位置设置为1
(integer) 0
redis> GETBIT bit 10086    #获取第10086个位置的值  看是0还是1
(integer) 1
redis> GETBIT bit 100   # bit 默认被初始化为 0
(integer) 0

其实就是把某个位标记为1或者0而已,但是它的好处在于非常节省空间。另外既然是位,就会涉及到或运算或者与运算。

实例

场景: 1亿个用户,每个用户登陆/做任意操作,记为 今天活跃,否则记为不活跃。
每周评出: 有奖活跃用户: 连续7天活动
每月评,等等...
其实简单说就是统计一下连续7天(或者连续30天)有多少人连续登陆过。

咱们先来想一想传统的方案
很容易就会想到只要用户登陆了,我在表中插入一条数据,并且记录上对应的日期,然后用mysql里面的记录来逐个判断,类似于这样:

Userid   date        active
1       2020-07-27  1
1       2020-07-26   1
2       2020-07-27  1
...

但这样是存在一些问题的,主要的问题在于用户量高达1亿,每个用户登陆一次就远远的超过mysql的极限了,更不要说统计一星期了,而且用上group ,sum运算,计算也是非常慢的。所以在这种用户量大,而且统计比较简单的问题上,咱们可以运用位(setbit)操作来解决问题。

先分析一下思路,对于某一天来说,我们可以把这一天想像成一根小木棍,分成了不同的段落,每个段落对应的就是用户的位(因为有user_id),默认值都是0,只要有人登陆了,就把对应的用户的位置标为1即可。


image.png

如上图所示,这个就是一天的登陆情况,user_id为6和user_id为8的用户登陆过。其余的都为没有登陆过。因为这个是位操作,所以占的空间很小,1亿的用户,所占的空间也就不到12M。

一天的问题咱们解决了,如何解决他们是否连续登陆过呢?
我们可以用上多个"木棍"


image.png

我们可以把每一天作为一个键,然后每天对用户登陆状态进行标记,在最后用每天做一个"与运算"就可以准确的知道哪些用户连续登陆了。

其实总结一下过程如下:

1. 记录用户登陆

每天按日期生成一个位图, 用户登陆后,把user_id位上的bit值置为1

2. 把1周的位图 and 计算

位上为1的,即是连续登陆的用户
代码实现如下:

redis 127.0.0.1:6379> setbit mon 100000000 0
(integer) 0

redis 127.0.0.1:6379> setbit mon 3 1
(integer) 0

redis 127.0.0.1:6379> setbit mon 5 1
(integer) 0

redis 127.0.0.1:6379> setbit mon 7 1
(integer) 0

redis 127.0.0.1:6379> setbit thur 100000000 0
(integer) 0

redis 127.0.0.1:6379> setbit thur 3 1
(integer) 0

redis 127.0.0.1:6379> setbit thur 5 1
(integer) 0

redis 127.0.0.1:6379> setbit thur 8 1
(integer) 0

redis 127.0.0.1:6379> setbit wen 100000000 0
(integer) 0

redis 127.0.0.1:6379> setbit wen 3 1
(integer) 0

redis 127.0.0.1:6379> setbit wen 4 1
(integer) 0

redis 127.0.0.1:6379> setbit wen 6 1
(integer) 0

redis 127.0.0.1:6379> bitop and  res mon feb wen
(integer) 12500001

如上例,优点为:
1、节约空间, 1亿人每天的登陆情况,用1亿bit,约1200WByte,约10M 的字符就能表示
2、计算方便

相关文章

  • redis位操作

    redis的字符串类型存储的是二进制数据,一个字节由8个二进制位组成,redis提供了4个命令可以直接对二进制位进...

  • 03-Redis 操作之Hash操作

    Redis 操作之Hash操作 Hash操作,redis中Hash在内存中的存储格式如下: hset(name, ...

  • Java位集合之BitMap,BitSet解析

    1 Java位集合 前几天刚学习了Redis中位操作命令[https://jingzh.blog.csdn.net...

  • 02-Redis 操作之String操作

    Redis 操作之String操作 String操作,redis中的String在在内存中按照一个name对应一个...

  • Redis学习之路(二):Redis数据结构简介

    Redis提供的5种结构 Redis中的字符串 基本命令 操作练习: Redis中的列表 基本命令 基本操作: R...

  • 04-Redis 操作之List操作

    Redis 操作之List操作 List操作,redis中的List在在内存中按照一个name对应一个List来存...

  • redis pipeline简介

    java中redis的pipeline pipeline方式执行redis操作: doInRedis方法中实现需要...

  • Python操作redis

    Python操作redis python连接方式:点击 下面介绍详细使用 1、String 操作 redis中的S...

  • 050-Redis集群

    009-Redis讲了redis在springboot中的基本操作,下面介绍springboot整合redis集群...

  • Redis' lists

    Redis列表基本操作命令 Redis list底层结构 Redis list由链表来实现。在Redis中链表的应...

网友评论

      本文标题:Redis中的位操作

      本文链接:https://www.haomeiwen.com/subject/jolbtrtx.html