Redis高级数据类型
1. HyperLoglog 超级日志
- 采用一种基数算法,用于完成独立总数的统计。[统计UV]
- 占据空间小,无论统计多少个数据,只占12K的内存空间。
- 不精确的统计算法,标准误差为0.81%。
2. Bitmap 位图
- 不是一种独立的数据结构,实际上就是字符串。
- 支持按位存取数据,可以将其看成是byte数组。
- 适合存储大量的连续的数据的布尔值。[统计签到]
3. 实例
@Test
public void testHyperLogLog(){
String redisKey = "test:hll:01";
for (int i = 0; i < 100000; i++) {
redisTemplate.opsForHyperLogLog().add(redisKey,i);
}
for (int i = 0; i < 100000; i++) {
int j = (int) (Math.random() * 100000 + 1);
redisTemplate.opsForHyperLogLog().add(redisKey,j);
}
System.out.println(redisTemplate.opsForHyperLogLog().size(redisKey));
}
@Test
public void testHyperLogLogUnion(){
String redisKey2 = "test:hll:02";
for (int i = 0; i < 10000; i++) {
redisTemplate.opsForHyperLogLog().add(redisKey2,i);
}
String redisKey3 = "test:hll:03";
for (int i = 5001; i < 15000; i++) {
redisTemplate.opsForHyperLogLog().add(redisKey3,i);
}
String redisKey4 = "test:hll:04";
for (int i = 10001; i < 20000; i++) {
redisTemplate.opsForHyperLogLog().add(redisKey4,i);
}
String unionKey = "test:hll:union";
redisTemplate.opsForHyperLogLog().union(unionKey, redisKey2, redisKey3, redisKey4);
System.out.println(redisTemplate.opsForHyperLogLog().size(unionKey));
}
@Test
public void testBitMap(){
String redisKey = "test:bm:01";
redisTemplate.opsForValue().setBit(redisKey, 1, true);
redisTemplate.opsForValue().setBit(redisKey, 3, true);
redisTemplate.opsForValue().getBit(redisKey, 0);
redisTemplate.opsForValue().getBit(redisKey, 1);
Object result = redisTemplate.execute(new RedisCallback() {
@Override
public Object doInRedis(RedisConnection redisConnection) throws DataAccessException {
return redisConnection.bitCount(redisKey.getBytes());
}
});
System.out.println(result);
}
@Test
public void testBitMapOper(){
String redisKey2 = "test:bm:02";
redisTemplate.opsForValue().setBit(redisKey2, 1, true);
redisTemplate.opsForValue().setBit(redisKey2, 2, true);
String redisKey3 = "test:bm:03";
redisTemplate.opsForValue().setBit(redisKey3, 3, true);
redisTemplate.opsForValue().setBit(redisKey3, 4, true);
String redisKey4 = "test:bm:04";
redisTemplate.opsForValue().setBit(redisKey4, 5, true);
redisTemplate.opsForValue().setBit(redisKey4, 6, true);
String redisKeyOr = "test:bm:or";
Object result = redisTemplate.execute(new RedisCallback() {
@Override
public Object doInRedis(RedisConnection redisConnection) throws DataAccessException {
redisConnection.bitOp(RedisStringCommands.BitOperation.OR,
redisKeyOr.getBytes(), redisKey2.getBytes(), redisKey3.getBytes(), redisKey4.getBytes());
return redisConnection.bitCount(redisKeyOr.getBytes());
}
});
System.out.println(result);
}