redis中setbit(位操作)的实际应用

45 篇文章 1 订阅
10 篇文章 1 订阅

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

今天我们就来淦一淦setbit,看一看实际场景中到底是怎么用的,以及有哪些优势?

我们先来回顾一下setbit吧,大家知道位操作,只有两个值,0和1,8个位正好是1b,所以位操作是非常节省空间的一种操作。

1 Byte(B) = 8 bit

1 Kilo Byte(KB) = 1024B

1 Mega Byte(MB) = 1024 KB

1 Giga Byte (GB)= 1024 MB

在redis中他的用法也非常简单, 基本语法如下:

redis 127.0.0.1:6379> Setbit KEY_NAME OFFSET

例子:

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即可。

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

一天的问题咱们解决了,如何解决他们是否连续登陆过呢?

我们可以用上多个"木棍"

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

其实总结一下过程如下:

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、计算方便。

  • 6
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Redis具有多种实际应用场景,包括但不限于以下几个方面: 1. 缓存Redis最常见的用途就是作为缓存层,将经常访问的数据存储在内存,以提高读取速度和减轻后端数据库的负载。通过使用Redis的高速读写能力,可以大幅提升系统的响应性能。 2. 会话存储:Redis可以用作会话存储,将用户的会话数据存储在内存,实现快速的会话访问和管理。这对于需要处理大量并发用户请求的应用程序特别有用。 3. 消息队列:Redis支持发布-订阅模式(Pub/Sub),可以作为消息队列系统使用。通过将消息发布到特定的频道,不同的客户端可以订阅这些频道并接收实时的消息推送。这在实时通知、实时聊天和异步任务处理等场景非常有用。 4. 计数器和排行榜:Redis提供了原子性操作和快速的计数功能,可用于实现计数器和排行榜功能。例如,在社交媒体应用,可以使用Redis来实时统计用户的粉丝数量或文章的点赞数,并根据这些数据生成排行榜。 5. 地理位置服务:Redis的地理位置功能(Geo)可以存储和查询地理位置信息,如坐标和半径范围内的位置。这使得Redis在构建地理位置服务(如附近的人、门店定位等)时非常有用。 总之,Redis是一个功能强大且灵活的内存数据库,可用于多种实际应用场景,包括缓存、会话存储、消息队列、计数器和排行榜,以及地理位置服务等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值