Redis高级数据类型

1.数据类型

  • HyperLogLog
    • 采用一种基数算法,用于完成独立总数的统计
    • 占据空间小,无论统计多少个数据,只占12k的内存
    • 不精确的统计算法,标准误差为0.81%
  • Bitmap(统计用户的签到情况)
    • 不是一种独立的数据结构,实际上就是字符串
    • 支持按位存取数据,可以将其看成是byte数组
    • 适合存储大量的联系的数据的布尔值

2.测试案例

  • 测试
/**
     * 统计20万个重复数据的独立总数
     */
    @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);

    }

    /**
     * 统计三组数据的布尔值,并对这三组数据进行OR运算
     */
    @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,性能好且可以统计精确的结果
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值