|
本文來自Spool的開發(fā)者博客,描述了Spool利用Redis的bitmaps相關的操作,進行網(wǎng)站活躍用戶統(tǒng)計工作。 Redis支持對String類型的value進行基于二進制位的置位操作。通過將一個用戶的id對應value上的一位,通過對活躍用戶對應的位進行置位,就能夠用一個value記錄所有活躍用戶的信息。如下圖所未,下圖中的bitmap有9個位被置為1,表示這9個位上對應的用戶是今天的活躍用戶。其中第15位表示uid為15的用戶,第一位表示uid為0的用戶。(如果你的uid不是從1開始的,比如從100000開始,實際上你也可以相應的用uid減去初始值來表示其位數(shù),比如1000000用戶對應到bitmap的第一位)
具體的代碼類似下面這樣: redis.setbit(play:yyyy-mm-dd, user_id, 1) 這樣一次記錄的復雜度是O(1),在Redis中速度非???。 下面表格表示對應一天,一周,一個月統(tǒng)計時所花費的時間。
下面是具體的java代碼片斷: 1.算出一天的活躍用戶數(shù)量 import redis.clients.jedis.Jedis;
import java.util.BitSet;
...
Jedis redis = new Jedis("localhost");
...
public int uniqueCount(String action, String date) {
String key = action + ":" + date;
BitSet users = BitSet.valueOf(redis.get(key.getBytes()));
return users.cardinality();
}
2.計算某幾個內(nèi)活躍用戶的數(shù)量(某一天活躍就算,所以是取并集) import redis.clients.jedis.Jedis;
import java.util.BitSet;
...
Jedis redis = new Jedis("localhost");
...
public int uniqueCount(String action, String... dates) {
BitSet all = new BitSet();
for (String date : dates) {
String key = action + ":" + date;
BitSet users = BitSet.valueOf(redis.get(key.getBytes()));
all.or(users);
}
return all.cardinality();
}
具體的用法還很多,比如你還可以對獨特終端的用戶單獨記一個bitmap,這樣就可以統(tǒng)計不同終端用戶的活躍情況。有的同學會說用set也能實現(xiàn)同樣的效果。但使用set在內(nèi)存使用量上是會大很多的。 如果你還有其它Redis好玩的應用場景。也歡迎通過NoSQLFan分享給更多朋友。 來源:blog. |
|
|