博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
利用Redis BitMap 统计用户活跃指标
阅读量:6517 次
发布时间:2019-06-24

本文共 3995 字,大约阅读时间需要 13 分钟。

hot3.png

    bitMap原理 :

    如下: index 从 0 到 9 ,依次对应到一个bit位上,如果index 代表用户id,bit位上的0 1分表 代表用户是否登录;

1 0 1 1 0 1 1 0 1 1

0 1 2 3 4 5 6 7 8 9

   

   redis数据结构中 string 类型,包含了对bitmap的实现;在redis-cli中,可以通过setbit getbit 来对bit进行操作;本文通过jedis来对redis进行操作; 

BitSet工具类:实现对通过jedis.get(key)取出的byte[]值与BitSet的转换

public class BitSetUtils {    /**     * 将BitSet对象转化为ByteArray     * @param bitSet     * @return     */    public static byte[] bitSet2ByteArray(BitSet bitSet) {        byte[] bytes = new byte[bitSet.size() / 8];        for (int i = 0; i < bitSet.size(); i++) {            int index = i / 8;            int offset = 7 - i % 8;            bytes[index] |= (bitSet.get(i) ? 1 : 0) << offset;        }        return bytes;    }    /**     *      * @param bytes     * @return     */    public static BitSet byteArray2BitSet(byte[] bytes) {        BitSet bitSet = new BitSet(bytes.length * 8);        int index = 0;        for (int i = 0; i < bytes.length; i++) {            for (int j = 7; j >= 0; j--) {                bitSet.set(index++, (bytes[i] & (1 << j)) >> j == 1 ? true                        : false);            }        }        return bitSet;    }}

    具体对java中BitSet操作,见 ,该篇对bitSet用法介绍很详细;

redis工具类:

public class RedisUtil {    static {        initPool();    }    private static volatile JedisPool jedisPool;    private static ResourceBundle resourceBundle;    public static Jedis getResource() {        return jedisPool.getResource();    }    public static void returnResource(Jedis jedis) {        jedisPool.returnResource(jedis);    }    public static void initPool() {            if(jedisPool != null){                return;            }            loadProperties();            String host = resourceBundle.getString("redis.host");            String passwd= resourceBundle.getString("redis.passwd");            int port = Integer.parseInt(resourceBundle.getString("redis.port"));            JedisPoolConfig config = config();            jedisPool = new JedisPool(config,host,port,60,passwd);    }    private static void loadProperties() {        resourceBundle = ResourceBundle.getBundle("config/redis-config");    }    private static JedisPoolConfig config() {        JedisPoolConfig config = new JedisPoolConfig();        return config;    }    public static void main(String[]args){       Jedis jedis= RedisUtil.getResource();       RedisUtil.returnResource(jedis);    }}

 1 统计系统中某天用户登录的情况:以当天日期做为key ,比如 ‘20150410’ ,对应的 bitMap 的 index 用userId来标示,UserId这里用  long 型表示,如果id不是以0开头,可以加上相应的偏移量就OK了;如果该天用户登录,调用activeUser方法,来更改bitMap相应index上的标示;

public void activeUser(long userId, String dateKey) {    Jedis jedis= RedisUtil.getResource();    try{        jedis.setbit(dateKey,userId,true);    }finally {        RedisUtil.returnResource(jedis);    }}

如果我们想统计该天用户登录的数量,及登录的用户id,可以通过如下方法实现:

//该天用户总数public long totalCount(String dateKey) {    Jedis jedis= RedisUtil.getResource();    try{        return jedis.bitcount(dateKey);    }finally {        RedisUtil.returnResource(jedis);    }}//该天登录所有的用户idpublic List
 activeUserIds(String  dateKey) {    Jedis jedis= RedisUtil.getResource();    try{                if(jedis.get(key)==null){                 return null;         }        BitSet set= BitSetUtils.byteArray2BitSet(jedis.get(key).getBytes());              List
list=new ArrayList
();        for (long i=0;i

   2 如果我们想统计n天,连续登录的用户数,及UserId:

public List
 continueActiveUserCount(String... dateKeys) {    Jedis jedis= RedisUtil.getResource();    try{        BitSet all = null;        for (String key:dateKeys){             if(jedis.get(key)==null){                 continue;             }             BitSet set= BitSetUtils.byteArray2BitSet(jedis.get(key).getBytes());             if(all==null){                 all=set;             }             System.out.println(set.size());             all.and(set);        }        List
list=new ArrayList
();        for (long i=0;i

 

转载请注明来源:

转载于:https://my.oschina.net/robinyao/blog/398808

你可能感兴趣的文章
C#与PHP通信压缩
查看>>
关于 Linux
查看>>
ios开发之导航控制器的原理
查看>>
《Netkiller Blockchain 手札》Hyperledger Fabric Java SDK Demo
查看>>
Linux系统_Centos7下安装Nginx
查看>>
《PHP和MySQL Web 开发》 第12章 MySQL高级管理
查看>>
数据库设计 Step by Step (6) —— 提取业务规则
查看>>
Redis客户端redisson实战
查看>>
连接到 JasperReports Server
查看>>
java处理高并发高负载类网站问题
查看>>
使用C#生成随机密码(纯数字或字母)和随机卡号(数字与字母组合)
查看>>
CAS服务器端集群
查看>>
JAVA Collections框架
查看>>
进制转换
查看>>
ASCII码
查看>>
java常用四种排序源代码
查看>>
win7 下硬盘安装Redhat7
查看>>
Redis 分布式锁的正确实现方式
查看>>
程序猿知道英语词汇
查看>>
数据存储(两)--SAX发动机XML记忆(附Demo)
查看>>