Bitmap
Bitmap是一串连续的2进制数字(0或1),每一位所在的位置为偏移(offset)。
在bitmap上可执行AND,OR,XOR以及其它位操作。
bitmap最大长度是512 MB,所以它们可以表示2 ^ 32=4294967296个不同的位。
位图计数
位图计数统计的是bitmap中值为1的位的个数。位图计数的效率很高。
Redis Bitmaps
Redis允许使用二进制数据的Key(binary keys) 和二进制数据的Value(binary values)。Bitmap就是二进制数据的value。Redis的 setbit(key,
offset, value)操作对指定的key的value的指定偏移(offset)的位置1或0,时间复杂度是O(1)。
setbit 、 getbit、bitcount 命令
setbit 设置bit位的值(值为1或者0)
getbit 获取bit位的值
bitcount 统计bit位为1的总数
例如:
> setbit key 1 1
> setbit key 2 1
> setbit key 8 1
> setbit key 9 1
> bitcount key
结果 4
将第1,2,8,9bit位设置成1,看下图:
举例
统计当天登录用户数量,模拟用户id为(1,2,3,4,20)的用户登录
//key
String key1 = "20180501";
//用户id
int useId1 = 1;
int useId2 = 2;
int useId3 = 3;
int useId4 = 4;
int useId20 = 20;
//设置用户登录状态
redisDao.setBit(key1, useId1, true);
redisDao.setBit(key1, useId2, true);
redisDao.setBit(key1, useId3, true);
redisDao.setBit(key1, useId4, true);
redisDao.setBit(key1, useId20, true);
//二进制:0111 1000 0000 0000 0000 1000 16进制: 0x7800 0x08
long login1 =redisServiceExtend.bitCount(key1);
System.out.println("用户登录数量: " + login1);
redis 存储的二进制值:0111 1000 0000 0000 0000 1000 转换16进制: 0x780008
用户登录数量: 5
spring-data-redis 中StringRedisTemplate不能使用bitcount方法,需要自己扩展
@Repository
public class RedisServiceExtend {
@Autowired
RedisTemplate<String, String> redisTemplate;
private static String redisCode = "utf-8";
/**
* 统计bit位为1的总数
* @param key
*/
public long bitCount(final String key) {
return redisTemplate.execute(new RedisCallback<Long>() {
@Override
public Long doInRedis(RedisConnection connection) throws DataAccessException {
long result = 0;
result = connection.bitCount(key.getBytes());
return result;
}
});
}
}