美文网首页
redis-bitmap

redis-bitmap

作者: zhangsanzhu | 来源:发表于2018-12-29 09:28 被阅读0次

redis-bitmap redis位图

实现原理:

就是字符串,字符数组

优点

1.节省空间,按位存的,比如记录用户登录次数,只需要365/8≈40多byte
2.设置时候时间复杂度O(1)、读取时候时间复杂度O(n),操作是非常快的。只要长度不长,读取是很快的.

注意事项

bitmap有位数限制,512m以内,on的读取复杂度,太长效率太差了.
bitcount key 0 0 这种情况只返回前8位的统计结果.

思考

使用方法(BITPOS 2.8.7可用,代码里面有使用例子)

127.0.0.1:6379> setbit test 100 1
(integer) 0
127.0.0.1:6379> setbit test 99 1
(integer) 0
127.0.0.1:6379> setbit test 98 0
(integer) 0
127.0.0.1:6379> setbit test 97 0
(integer) 0
127.0.0.1:6379> setbit test 96 1
(integer) 0
127.0.0.1:6379> getbit test 96
(integer) 1
127.0.0.1:6379> getbit test 95
(integer) 0
127.0.0.1:6379> getbit test 97
(integer) 0
127.0.0.1:6379> getbit test 98
(integer) 0
127.0.0.1:6379> getbit test 99
(integer) 1
127.0.0.1:6379> getbit test 100
(integer) 1
127.0.0.1:6379> bitcount test 0 -1
(integer) 3

案例:

1.用户签到
用户id作为key,value为签到的情况,1代表签到,0代表未签到.

       //用户uid
        String uid = "1";
        String cacheKey = "sign_" + Integer.valueOf(uid);
        //记录有uid的key
        // $cacheKey = sprintf("sign_%d", $uid);
        
        //开始有签到功能的日期
        String startDate = "2017-01-01";

        //今天的日期
        String todayDate = "2017-01-21";
        
        //计算offset(时间搓)
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        long startTime = format.parse(startDate).getTime();
        long todayTime = format.parse(startDate).getTime();
        long offset = (long) Math.floor((todayTime - startTime) / 86400);

        System.out.println("今天是第" + offset + "天");
        //签到
        //一年一个用户会占用多少空间呢?大约365/8=45.625个字节,好小,有木有被惊呆?
        jedis.setbit(cacheKey, offset, "1");

        //查询签到情况
        boolean bitStatus = jedis.getbit(cacheKey, offset);
        //判断是否已经签到
        //计算总签到次数
        long qdCount = jedis.bitcount(cacheKey);

2.统计活跃用户数:
每天当天的日期作为key,当天的活跃用户作为offset,value设置成1,为bitcount做准备.
通过bitcount 统计value的数量,就可以知道当天活跃用户数了.
如果 是几天的活跃用户数,那么 可以用bittop 命令 合并结果.

  Map<String,List<Integer>>dateActiveuser = new HashMap<>();
        Integer[] temp01 = {1,2,3,4,5,6,7,8,9,10};
        List<Integer>temp01List = new ArrayList<>();
        Collections.addAll(temp01List,temp01);
        dateActiveuser.put("2017-01-10",temp01List);


        Integer[] temp02 = {1,2,3,4,5,6,7,8};
        List<Integer>temp02List = new ArrayList<>();
        Collections.addAll(temp02List,temp02);
        dateActiveuser.put("2017-01-11",temp02List);

        Integer[] temp03 = {1,2,3,4,5,6};
        List<Integer>temp03List = new ArrayList<>();
        Collections.addAll(temp03List,temp03);
        dateActiveuser.put("2017-01-12",temp03List);

        Integer[] temp04 = {1,4,5,6};
        List<Integer>temp04List = new ArrayList<>();
        Collections.addAll(temp04List,temp04);
        dateActiveuser.put("2017-01-13",temp04List);

        Integer[] temp05 = {1,4,5,6};
        List<Integer>temp05List = new ArrayList<>();
        Collections.addAll(temp05List,temp05);
        dateActiveuser.put("2017-01-14",temp05List);

        String date[] = {"2017-01-10","2017-01-11","2017-01-12","2017-01-13","2017-01-14"};

       //测试数据放入redis中
        for (int i=0;i<date.length;i++){
            for (int j=0;j<dateActiveuser.get(date[i]).size();j++){
                jedis.setbit(date[i], dateActiveuser.get(date[i]).get(j), "1");
            }
        }

        //bitOp
        jedis.bitop(BitOP.AND, "stat", "2017-01-10", "2017-01-11","2017-01-12");

        System.out.println("总活跃用户:"+jedis.bitcount("stat"));

        jedis.bitop(BitOP.AND, "stat1", "2017-01-10", "2017-01-11","2017-01-14");
        System.out.println("总活跃用户:"+jedis.bitcount("stat1"));

        jedis.bitop(BitOP.AND, "stat2", "2017-01-10", "2017-01-11");
        System.out.println("总活跃用户:"+jedis.bitcount("stat2"));
        
        System.out.println("总活跃用户:"+jedis.bitcount("2017-01-11"));

相关文章

  • Redis-BitMap

    BitMap是什么通过一个bit位来表示某个元素对应的值或者状态,其中的key就是对应元素本身。Bitmaps 本...

  • Redis-Bitmap

    基础概念 “a”ASCll码是97,二进制是0110 0001,每个数“1”,“0”叫做位(bit),每8位叫做一...

  • redis-bitmap

    redis-bitmap redis位图 实现原理: 就是字符串,字符数组 优点 1.节省空间,按位存的,比如记录...

网友评论

      本文标题:redis-bitmap

      本文链接:https://www.haomeiwen.com/subject/zifulqtx.html