专栏首页golang+phpredis中setbit(位操作)的实际应用

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

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

本文分享自微信公众号 - 程序员养成日记(programmer_grow),作者:程序员养成日记

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-12-01

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • setbit的实际应用

    程序员养成日记
  • redis的sort命令详解

    最简单的sort用法是 sort key 和sort key desc(key的对象是list类型的数据)

    程序员养成日记
  • redis的安装与启动以及注意事项

    安装步骤 (注意,在安装之前一定要注意系统的时间一定要正确,否则会出问题) 在redis中文官网上下载安装包 http://www.redis.cn/do...

    程序员养成日记
  • setbit的实际应用

    程序员养成日记
  • 独家 | 政府政务知识库应用的探索与实践(附PPT下载)

    [导读]本文整理自2017年6月27日,由清华-青岛数据科学研究院主办,清数大数据产业联盟承办和中国科学技术产业化促进会指导发起的清华大数据“应用·创新”系列讲...

    数据派THU
  • PMPBOK6之项目管理的33个文件

    活动属性是指每项活动所具有的多重属性,用来扩充对活动的描述,活动属性随时间演进。在项目初始阶段,活动属性包括唯一活动标识 (ID)、WBS 标识和活动标签或名称...

    菲宇
  • React Native组件(一)组件的生命周期

    前言 React Native有很多组件比如Image、ListView等等,想要合理的使用组件,首先要先了解组件的生命周期。 1.概述 无论你是开发Andr...

    用户1269200
  • LeetCode 网易-2. 古老的游戏机

    小易有一个古老的游戏机,上面有着经典的游戏俄罗斯方块。因为它比较古老,所以规则和一般的俄罗斯方块不同。

    Michael阿明
  • 海量之道系列文章之弱联网优化 (六)

    基于一个快速和高效管理的链路之上,做好IO调度和控制,也是提升效能和改善用户体验的重要环节,本节主要来探讨 IO 管理与 强监控。

    樊华恒
  • phpstudy后门文件分析以及检测脚本

    2019.9.20得知非官网的一些下载站中的phpstudy版本存在后门文件,基于研究的目的,于是有了以下这文。

    ChaMd5安全团队

扫码关注云+社区

领取腾讯云代金券