1.数据类型
- HyperLogLog
- 采用一种基数算法,用于完成独立总数的统计
- 占据空间小,无论统计多少个数据,只占12k的内存
- 不精确的统计算法,标准误差为0.81%
- Bitmap(统计用户的签到情况)
- 不是一种独立的数据结构,实际上就是字符串
- 支持按位存取数据,可以将其看成是byte数组
- 适合存储大量的联系的数据的布尔值
2.测试案例
@Test
public void testHyperLogLog() {
String redisKey = "test:hll:01";
for (int i = 1; i <= 100000; i++) {
redisTemplate.opsForHyperLogLog().add(redisKey, i);
}
for (int i = 1; i < 100000; i++) {
int r = (int) (Math.random() * 100000 + 1);
redisTemplate.opsForHyperLogLog().add(redisKey, r);
}
Long size = redisTemplate.opsForHyperLogLog().size(redisKey);
System.out.println(size);
}
@Test
public void testBitMap() {
String rediskey ="test:bm:01";
redisTemplate.opsForValue().setBit(rediskey, 1, true);
redisTemplate.opsForValue().setBit(rediskey, 4, true);
redisTemplate.opsForValue().setBit(rediskey, 7, true);
System.out.println(redisTemplate.opsForValue().getBit(rediskey, 0));
System.out.println(redisTemplate.opsForValue().getBit(rediskey, 1));
System.out.println(redisTemplate.opsForValue().getBit(rediskey, 2));
Object obj = redisTemplate.execute(new RedisCallback() {
@Override
public Object doInRedis(RedisConnection connection) throws DataAccessException {
return connection.bitCount(rediskey.getBytes());
}
});
System.out.println(obj);
}
@Test
public void testBitMapOperation() {
String rediskey2 = "test:bm:02";
redisTemplate.opsForValue().setBit(rediskey2, 0,true);
redisTemplate.opsForValue().setBit(rediskey2, 1,true);
redisTemplate.opsForValue().setBit(rediskey2, 2,true);
String rediskey3 = "test:bm:03";
redisTemplate.opsForValue().setBit(rediskey3, 2,true);
redisTemplate.opsForValue().setBit(rediskey3, 3,true);
redisTemplate.opsForValue().setBit(rediskey3, 4,true);
String rediskey4 = "test:bm:04";
redisTemplate.opsForValue().setBit(rediskey4, 4,true);
redisTemplate.opsForValue().setBit(rediskey4, 5,true);
redisTemplate.opsForValue().setBit(rediskey4, 6,true);
String rediskey = "test:bm:or";
Object obj = redisTemplate.execute(new RedisCallback() {
@Override
public Object doInRedis(RedisConnection connection) throws DataAccessException {
connection.bitOp(RedisStringCommands.BitOperation.OR,rediskey.getBytes(),
rediskey2.getBytes(), rediskey3.getBytes(), rediskey4.getBytes());
return connection.bitCount(rediskey.getBytes());
}
});
System.out.println(obj);
}
3.实际应用
- UV(Unique Visitor)
- 独立访客,需通过用户ip排重统计数据。
- 每次访问都要进行统计
- HyperLogLog,性能好且存储空间小
- DAU(Daily Active User)
- 日活跃用户,需通过用户ID排重统计数据
- 访问过一次,则认为其活跃
- BitMap,性能好且可以统计精确的结果