Redis:Bitmap的setbit,getbit,bitcount,bitop等使用与应用场景

您所在的位置:网站首页 redis的实际应用场景 Redis:Bitmap的setbit,getbit,bitcount,bitop等使用与应用场景

Redis:Bitmap的setbit,getbit,bitcount,bitop等使用与应用场景

2024-07-16 04:02| 来源: 网络整理| 查看: 265

详细介绍redis中bitmap的相关命令用法以及使用场景如:用户上下线记录、日活月活留存率等统计计算

简介 优点缺点 Redis Getbit 命令Redis Setbit 命令Redis Bitcount 命令Redis Bitop 命令应用场景 1.可作为简单的布尔过滤器来判断用户是否执行过某些操作2.用户日活,月活,留存率的统计3.实现用户上线次数统计4.用户在线状态及人数统计记录

官方redis教程

简介

几个前提:

数据在redis中都是二进制存储setbit和getbit和bitcount是string数据类型的命令8bit表示一个ascll字符,因为是c写的redisoffset偏移量是从0开始

操作String数据结构的key所存储的字符串值指定偏移量上的位,返回的是原位置上的值

优点 极其省空间:通过一个bit位来表示某个元素对应的值或者状态,其中的key就是对应元素本身。我们知道8个bit可以组成一个Byte,所以bitmap本身会极大的节省储存空间。极其效率高:setbit和getbit的时间复杂度就是O(1),其他位运算也是效率极高的

空间占用、以及第一次分配空间需要的时间:

在一台2010MacBook Pro上,offset为2^32-1(分配512MB)需要~300ms,offset为2^30-1(分配128MB)需要~80ms,offset为2^28-1(分配32MB)需要~30ms,offset为2^26-1(分配8MB)需要8ms。 大概的空间占用计算公式是:($offset/8/1024/1024)MB

缺点

缺点也在于位计算和位表示数值的局限。故如要用位来做业务数据记录,那么就不要在意value的值了

Redis Getbit 命令

对 key 所储存的字符串值,获取指定偏移量上的位(bit)。

语法:getbit key offset 注:offset表示偏移量返回值:字符串值指定偏移量上的位(bit)。当偏移量 OFFSET 比字符串值的长度大,或者 key 不存在时,返回 0 。

案例:

127.0.0.1:6379> set A a OK 127.0.0.1:6379> get A "a" 127.0.0.1:6379> getbit A 0 (integer) 0 127.0.0.1:6379> getbit A 1 (integer) 1 127.0.0.1:6379> getbit A 2 (integer) 1 127.0.0.1:6379> getbit A 3 (integer) 0 127.0.0.1:6379> getbit A 4 (integer) 0 127.0.0.1:6379> getbit A 5 (integer) 0 127.0.0.1:6379> getbit A 6 (integer) 0 127.0.0.1:6379> getbit A 7 (integer) 1 Redis Setbit 命令

对 key 所储存的字符串值,设置或清除指定偏移量上的位(bit)。

语法: setbit key offset value返回值:指定偏移量原来储存的位。

案例:将上述A的值“a”的第6位修改为1,也就是相当于ASCLL码加2,从而值从a变成了c。

127.0.0.1:6379> setbit A 6 1 (integer) 0 127.0.0.1:6379> get A "c" 127.0.0.1:6379> Redis Bitcount 命令

计算给定key的字符串值中,被设置为 1 的比特位的数量。 不存在的 key 被当成是空字符串来处理,因此对一个不存在的 key 进行 BITCOUNT 操作,结果为 0 。

语法:BITCOUNT key [start] [end]返回值:1比特位的数量

案例:值c的二进制数应该是01100011,故bitcount计算出来应该是4

127.0.0.1:6379> get A "c" 127.0.0.1:6379> bitcount A (integer) 4 Redis Bitop 命令

对一个或多个保存二进制位的字符串 key 进行位元操作,并将结果保存到 destkey 上

语法:operation 可以是 AND 、 OR 、 NOT 、 XOR 这四种操作中的任意一种:

BITOP AND destkey key [key ...] ,对一个或多个 key 求逻辑并,并将结果保存到 destkey 。BITOP OR destkey key [key ...] ,对一个或多个 key 求逻辑或,并将结果保存到 - destkey 。BITOP XOR destkey key [key ...] ,对一个或多个 key 求逻辑异或,并将结果保存到 destkey 。BITOP NOT destkey key ,对给定 key 求逻辑非,并将结果保存到 destkey 。

除了 NOT 操作之外,其他操作都可以接受一个或多个 key 作为输入。

处理不同长度的字符串

当 BITOP 处理不同长度的字符串时,较短的那个字符串所缺少的部分会被看作 0 。

空的 key 也被看作是包含 0 的字符串序列。

可用版本:>= 2.6.0

时间复杂度: O(N)

BITOP 的复杂度为 O(N) ,当处理大型矩阵(matrix)或者进行大数据量的统计时,最好将任务指派到附属节点(slave)进行,避免阻塞主节点。

案例:

127.0.0.1:6379> set E a OK 127.0.0.1:6379> set F b OK 127.0.0.1:6379> set G d OK 127.0.0.1:6379> bitop and andEFG E F G (integer) 1 127.0.0.1:6379> get andEFG "`" 127.0.0.1:6379> bitop or orEFG E F G (integer) 1 127.0.0.1:6379> get orEFG "g" 127.0.0.1:6379> bitop xor xorEFG E F G (integer) 1 127.0.0.1:6379> get xorEFG "g" 127.0.0.1:6379> bitop not notE E (integer) 1 127.0.0.1:6379> get notE "\x9e"

注:

值a的2进制数据为:01100001;值b的2进制数据为:01100010;值d的2进制数据为:01100100;

得出来的值可以去查下ascll码表应该是正确的

应用场景

首先,这两个命令是效率极高且省内存,因为直接操作的是redis存储的数据。

一般应用场景:

1.可作为简单的布尔过滤器来判断用户是否执行过某些操作 2.用户日活,月活,留存率的统计

案例:

需求:每个用户登陆/做任意操作 ,记为 今天活跃,否则记为不活跃。计算出日活7日活月活等数据。

具体实施:使用redis的bitmap

设置一个key专门用来记录用户日活的,可以使用时间来翻滚比如1号的key为active01.使用每个用户的唯一标识映射一个偏移量,比如使用id,这里可以把id换算成一个数字或直接使用id的二进制值作为该用户在当天是否活跃偏移量用户登录则把该用户偏移量上的位值设置为1每天按日期生成一个位图(bitmap)计算日活则使用bitcount即可获得一个key的位值为1的量计算月活(一个月内登陆的用户去重总数)即可把30天的所有bitmap做or计算,然后再计算bitcount计算留存率(次日留存=昨天今天连续登录的人数/昨天登录的人数) 即昨天的bitmap与今天的bitmap做and计算就是连续登录的再做bitcount就得到连续登录人数,再bitcount得到昨天登录人数,就可以通过公式计算出次日留存。 如下案例: 127.0.0.1:6379> bitop and andValue A B (integer) 1 127.0.0.1:6379> get andValue "b" 127.0.0.1:6379> bitop or orValue A B (integer) 1 127.0.0.1:6379> get orValue "c" 127.0.0.1:6379> bitcount andValue (integer) 3 127.0.0.1:6379> bitcount orValue (integer) 4 3.实现用户上线次数统计 假设现在我们希望记录自己网站上的用户的上线频率,比如说,计算用户 A 上线了多少天,用户 B 上线了多少天,诸如此类,以此作为数据,从而决定让哪些用户参加 beta 测试等活动 —— 这个模式可以使用 SETBIT 和 BITCOUNT 来实现。比如说,每当用户在某一天上线的时候,我们就使用 SETBIT ,以用户名作为 key ,将那天所代表的网站的上线日作为 offset 参数,并将这个 offset 上的为设置为 1 。举个例子,如果今天是网站上线的第 100 天,而用户 peter 在今天阅览过网站,那么执行命令 SETBIT peter 100 1 ;如果明天 peter 也继续阅览网站,那么执行命令 SETBIT peter 101 1 ,以此类推。当要计算 peter 总共以来的上线次数时,就使用 BITCOUNT 命令:执行 BITCOUNT peter ,得出的结果就是 peter 上线的总天数。 4.用户在线状态及人数统计记录

同样是使用一个bitmap,用用户的id来映射偏移量,在线标识为1,下线标识为0。可以轻松实现用户上下线查询和总在线人数的统计等等

参考:

Redis中bitmap的妙用用户上线统计:Fast, easy, realtime metrics using Redis bitmaps


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3