您的当前位置:首页正文

你知道Redis中的getbit、setbit的作用吗?

2024-12-03 来源:个人技术集锦

1.什么是偏移量

在计算机里所有的数据都是以二进制的形式存储的,每一个非中文字符占一个字节(Byte),中文字符占两个字节,而一个字节又是占8bit。

先在redis中设置一个k-v(key:foo value:bar)

注意:

2.常用的方法

这里主要演示一下在代码中使用spring-redis api来操作。

  1. getbit/setbit
    获取对应的二进制值
// key是对应的key
// offset偏移量
// true则是值1 false则为0
redisTemplate.opsForValue().setBit(key, offset, true);
  1. bitcount
    统计一共有多少位是1
// springredis没有提供的api方法
// 需要用到底层提供的execute方法使用connection去统计
long count = (long) redisTemplate.execute((RedisCallback<Object>) conn -> conn.bitCount(signInRedisKey.getBytes()));
  1. bitField
    统计偏移量范围内的值
/** key就是值
   offset是偏移多少,比如10
   from就是从多少开始数 比如 0
   那么就会返回 0-10 一百个数转换成的十进制数
   比如 0000000010 就返回 2 
   注意:返回的是List,集合中只有第一个数有值,如果该key不存在那么就会返回0
**/
List<Long> list = redisTemplate.execute((RedisCallback<List<Long>>) conn ->
                conn.bitField(key.getBytes(), BitFieldSubCommands.create().get(BitFieldSubCommands.BitFieldType.unsigned(offset).valueAt(from)));

3.用处

相信很多人刚了解的时候都会有这个疑问,我使用场景只是存储字符串,也不需要去拿其某一位二进制数据啊。

不知道大家有没有思考过,钉钉的群聊 10人未查看,5人已读是怎么实现的。

如果单纯一条信息存储一个已读数和未读数,这样会造成大量数据库读写,一个群聊几十上百人,信息一天可能达到几万条,如此高频读写,数据库怎么吃得消?何况要怎么记录是哪个人读了,哪个人没读?

我们用setbit看一看能不能实现,比如我们当前是 群 1 第 1001 条消息 一共有100个人
每个人对应一个id假设 0-99
setbit group:message:1001:1 99 1
使用bitcount就可以统计一共有多少人已读。

现在有新的问题,如果有用户退群了呢?比如用户2退群了

那么记录一下退群数 +1 总人数 +1,如果已读人数=总人数-退群数,那么就说明已读了,否则是未读数。

那么新的进群用户我们就可以 setbit group:message:1001:1 100 1,方便快捷无需扩容等,但切记最大值是4294967295

总结

redis的getbit、setbit特性可以帮助解决很多现实问题,而且因为存储空间小,一位就一个bit,所以能够很好的节省空间、提高性能。在了解该特性之前,没想到它能解决那么多场景问题,打卡、群聊等,而仔细了解后发现,用这种方式解决真的很恰当美妙。

显示全文