本篇内容介绍了“bitmap的相关命令有哪些”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!
1.使用场景
用户上线次数统计、统计活跃用户,签到,点赞等具有标识性功能
2.原理
就是通过一个bit位来表示某个元素对应的值或者状态,其中的key就是对应元素本身,是bit不是byte,1byte=8bit,优点凸显,就是贼鸡儿省空间
空间占用、以及第一次分配空间需要的时间
在一台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)
说起来bitmap不能算为一种新数据类型,只是set的扩展
3.命令
命令 | 作用 |
setbit | 设置Bitmap的值 |
getbit | 获取Bitmap的值 |
bitcount | 获取指定范围内值为1的个数 |
destkey | 对Bitmap做操作,可以是and(交集),or(并集),not(非集)或者xor(异或) |
BITOP | BITOP operation destkey key [key ...], 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 作为输入 |
BITPOS | BITPOS key bit [start][end] 返回字符串里面第一个被设置为 1 或者 0 的bit位。 |
BITFIELD | BITFIELD key [GET type offset][SET type offset value][INCRBY type offset increment][OVERFLOW WRAP|SAT|FAIL] |
溢出控制
用户可以通过 OVERFLOW 命令以及以下展示的三个参数, 指定 BITFIELD 命令在执行自增或者自减操作时, 碰上向上溢出(overflow)或者向下溢出(underflow)情况时的行为:
WRAP :使用回绕(wrap around)方法处理有符号整数和无符号整数的溢出情况。对于无符号整数来说, 回绕就像使用数值本身与能够被储存的最大无符号整数执行取模计算, 这也是 C 语言的标准行为。对于有符号整数来说, 上溢将导致数字重新从最小的负数开始计算, 而下溢将导致数字重新从最大的正数开始计算。比如说, 如果我们对一个值为 127 的 i8 整数执行加一操作, 那么将得到结果 -128 。
SAT :使用饱和计算(saturation arithmetic)方法处理溢出, 也即是说, 下溢计算的结果为最小的整数值, 而上溢计算的结果为最大的整数值。举个例子, 如果我们对一个值为 120 的 i8 整数执行加 10 计算, 那么命令的结果将为 i8 类型所能储存的最大整数值 127 。与此相反, 如果一个针对 i8 值的计算造成了下溢, 那么这个 i8 值将被设置为 -127 。
FAIL :在这一模式下, 命令将拒绝执行那些会导致上溢或者下溢情况出现的计算, 并向用户返回空值表示计算未被执行。
需要注意的是, OVERFLOW 子命令只会对紧随着它之后被执行的 INCRBY 命令产生效果, 这一效果将一直持续到与它一同被执行的下一个 OVERFLOW 命令为止。在默认情况下, INCRBY 命令使用 WRAP 方式来处理溢出计算。
4.优点
省空间
5.缺点
暂无,虽然一个标识位只能记录一个用户,那也够用了毕竟你没有2^32-1的数据量
6.实现场景点赞
新增redis方法setbit
//bitmap/** * Sets the bit at {@code offset} in value stored at {@code key}. * * @param key must not be {@literal null}. * @param offset * @param value * @since 1.5 * @see <a href="http://redis.io/commands/setbit">Redis Documentation: SETBIT</a> */Boolean setBit(K key, long offset, boolean value);/** setbit* */public Boolean setBitMap(String key,long commentDatailId,boolean value){return redisTemplate.opsForValue().setBit(key,commentDatailId,value);}
在命令中value是标识1或0的,也就是true/false对应值
key:设置的key,比如日活,签到,就用时间+id,那标识点赞未点赞就用信息id即可
offset:即所占标识位,一看就想起来偏移量
value:设置0/1
Boolean :返回0或1来标识是否
boolean flag = redisService.setBitMap(userIdStr,commentDetailId,true);
以前的逻辑不变set之前判断是否存在
if(redisService.getBitMap(userIdStr,commentDetailId)){ redisService.setBitMap(userIdStr,commentDetailId,true);}else{ redisService.setBitMap(userIdStr,commentDetailId,false);}
问题:如果我的id很大或者是uuid开始呢?
正常的id是不会的,但uuid有可能,如果是uuid可以使用uuid减去初始位来进行放置
实现场景大数据量黑名单
此业务适合大数据量业务存储的占用空间问题,而且基于redis速度不用担心
日活统计
bitop and time moday thurday
1.节约空间,统计一亿人每天的登录情况,用一亿bit,约1200WByte,约10M的字符就能表示(因为bitop命令的返回值是保存到 time中的字符串的长度(以字节byte为单位),和输入 key 中最长的字符串长度相等。即1亿除以8bit=1250万Byte);
2.计算方便
性能:
如果你的 bitmap 数据非常大,那么可以考虑使用以下两种方法:
● 将一个大的 bitmap 分散到不同的 key 中,作为小的 bitmap 来处理。使用 Lua 脚本可以很方便地完成这一工作。
● 使用 BITCOUNT 的 start 和 end 参数,每次只对所需的部分位进行计算,将位的累积工作(accumulating)放到客户端进行,并且对结果进行缓存 (caching)。
何时使用:
如果活跃用户在百万级别,使用Redis BitMap很划算。
如果活跃用户很少,而用户id都是10位以上的int。那就很浪费内存了,还不如使用set集合,然后求交集就可以了。
“bitmap的相关命令有哪些”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注亿速云网站,小编将为大家输出更多高质量的实用文章!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。