采用redis的优点也不用多说 计算方便 省时高效 节约空间
采用的java实现
用 bitmap 记录每一天的用户活跃情况(上线记为1,默认为0 )
setbit(String key, long offset, boolean value)
key 为键 ,offset为偏移量 ,我将其与用户id向对应,value=true 记为上线过
key的表现形式根据实际情况 如果要记录每一天的可以用采用日期的形式,我这里的标准是记录四天内都上过线的用户,所以是记为 firstDay,secondDay,thirdDay,today。today记录今天上过线的用户,然后在12点时,将secondDay的信息赋给firstDay,thirdDay的信息赋给secondDay,today的信息赋给thirdDay,today的信息清空
public static void init() {
jedis.setbit("firstDay", 0, false);
jedis.setbit("secondDay", 0, false);
jedis.setbit("thirdDay", 0, false);
jedis.setbit("today", 0, false);
}
/**
* 每日更新
*/
public static void updActive() {
init();
jedis.set("firstDay".getBytes() , jedis.get("secondDay".getBytes()) );
jedis.set("secondDay".getBytes() , jedis.get("thirdDay".getBytes()) );
jedis.set("thirdDay".getBytes() , jedis.get("today".getBytes()) );
jedis.del("today");
jedis.setbit("today", 0, false);
}
此处0的位置不记录用户,用来创建key,防止为空的情况(一开始只有today)。
判定一个用户是否为活跃用户
bitop(BitOP op, String destKey, String... srcKeys)
op 运算符 destKey 运算结果存放的key srcKeys待计算的Key
public static boolean isActive( int index ){
jedis.bitop(BitOP.AND ,"nowActive", "firstDay","secondDay","thirdDay","today");
return jedis.getbit("nowActive", index);
}
这里会将 firstDay,secondDay,thirdDay,today 的值进行and运算(值全为1才得1),结果存到nowActive中,此时取nowActive对应位置的值,1即为活跃。
保存活跃用户
这里将nowAcitve的结果 再以list的形式存入redis,不用Pipeline会很慢...
public static void saveActiveUsers() {
if( jedis.exists("ActiveUsers") ) {
jedis.del("ActiveUsers");
}
jedis.bitop(BitOP.AND ,"nowActive","firstDay","secondDay","thirdDay","today");
int len = jedis.get("nowActive".getBytes()).length*8;
Pipeline p = jedis.pipelined();
HashMap> map = new HashMap>();
for(int i=1;i> entry : map.entrySet()) {
if( entry.getValue().get()) {
p.lpush("ActiveUsers", entry.getKey().toString() );
}
}
p.sync();
}
不是十分了解redis的使用...有很多不足,仅供参考...
windows版本的redis不支持bitop的方法(也可能是我版本的问题...),建议使用linux环境下的redis