思路,搞一個集合,將當(dāng)天登陸過的用戶的id,存起來,用于統(tǒng)計日活;
目前,用Redis統(tǒng)計日活的方案有3種:
1.使用set集合;
2.使用bitset;
3.使用hyperLogLog;
第一種方案使用set,這種方案不推薦,因為在set里面存一個用戶id,就要使用32bit,1億用戶每天就要存3200M。
第二種方案:
先看代碼:
public String SimpleBitset(){
DateTime dt = new DateTime();
String strDate = dt.toString("yyyyMMdd");
RBitSet set = redisson.getBitSet("log_"+dt.toString("yyyyMMdd"));
set.set(0L,true);
set.set(1L,true);
// 如果一下子加到4294967295,那么在redis這個鍵就會達到500多MB
// 所以如果用戶數(shù)在百萬基本,可以用這種方式,而如果用戶數(shù)過億了,會比較消耗內(nèi)存
// 如果linux判斷redis是個危害,會把它干掉
// set.set(4294967295L,true);
// 超過4294967295L就會報錯
// set.set(4294967296L,true);
// 查詢有多少DAU
System.out.println(set.cardinality());
return "";
}
用這種方式,有一定限制條件:
1.用戶數(shù)不能超過4294967296(基本也沒幾個超得過的吧);
2.它占用的內(nèi)存大小,不在于存了多少,而在于最大的那個id是多少,比如今天第一個訪問的id是100000000,那么這個key的占用內(nèi)存就會是12M左右(1億個bit);
如果用戶數(shù)量也就1億左右,可以考慮這種方式。
第三種方案:
先看代碼:
public String HyperLogLog(){
RHyperLogLog<Long> log = redisson.getHyperLogLog("log");
log.add(1L);
log.add(2L);
log.add(3L);
log.add(3L);
log.add(3L);
log.add(3L);
log.add(3L);
log.add(3L);
log.add(3L);
log.add(3L);
log.add(10000000L);
// 得到的結(jié)果是4
System.out.println(log.count());
return "";
}
1.它統(tǒng)計1億用戶,大概要1M多點;
2.HyperLogLog的統(tǒng)計結(jié)果并不是一個精確的值,誤差在0.81%左右,但是對于統(tǒng)計用戶數(shù)這種場景來說足夠了。