redis中bitmaps进行状态统计

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,看下图:

  offset 是从左边往后边数(高位往低位数),开始索引从0开始。

举例
统计当天登录用户数量,模拟用户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;
}
});
}
}

猜你喜欢

转载自blog.csdn.net/chy2z/article/details/80504961