redis中bitmap的相關方法php
對
key
所儲存的字符串值,設置或清除指定偏移量上的位(bit)。
offset是下標,value是0或者1,複雜度爲O(1)linux
對
key
所儲存的字符串值,獲取指定偏移量上的位(bit)。
得到offset上的值,0或者1,複雜度爲O(1)redis
計算給定字符串中,被設置爲
1
的比特位的數量。
例如這個key保存的字符串二進制爲101011,則返回結果4。數據庫
對一個或多個保存二進制位的字符串key
進行位元操做,並將結果保存到destkey
上。
operation
能夠是AND
、OR
、NOT
、XOR
這四種操做中的任意一種windows
對兩個二進制串進行操做用的方法。測試
3.2版本新加入的方法,功能很複雜。這裏不作討論
用帶有日期的字符串當key
,拿用戶的uid
看成offset,當天登陸了就執行一次下面的代碼ui
$redis->setBit('20170323_au',123,1);
這樣,全部登陸過的用戶,會組成這個key
爲「20170323_au」的二進制字符串中spa
而後再使用code
$redis->bitCount('20170323_au');
就能夠拿到今天上線人數的統計了。blog
若是你想拿到最近三天的活躍人數怎麼辦?一樣簡單:
$redis->bitOp('OR','last_3_au','20170321_au','20170322_au','20170323_au'); $result = $redis->bitCount('last_3_au');
用BITOP
將三天的結果作OR
操做
獲得的結果在bitCount
一下就是最近三天的活躍人數了。
關於效率,有人統計了128million用戶的表現。
PERIOD | TIME (MS) |
---|---|
Daily | 50.2 |
Weekly | 392.0 |
Monthly | 1624.8 |
對比傳統的數據庫,實現起來的難易度和效率簡直不可同日而語。
下面是我本身的測試數據
<?php require_once dirname(__FILE__) . '/../config/autoload.php'; $t1 = microtime(true); $redis = RedisManage::getRedisForShare(); //makeTestData('20161221'); //makeTestData('20161222'); //makeTestData('20161223'); $redis->bitOp('OR', 'stat_3_day_3m', '20161221', '20161222', '20161223'); echo $redis->bitCount('stat_3_day_3m') . "\n"; echo "time taken: " . (microtime(true) - $t1); function makeTestData($key) { $redis = RedisManage::getRedisForShare(); for ($i = 0; $i < 3000000; $i++) { $redis->setBit($key, $i, mt_rand(0, 1)); } }
先建立了3條3million的數據。
最後顯示結果:
並且這是windows環境下的測試結果。linux應該會更快。
這要比傳統的關係型數據庫使用count,group by要效率不少。
並且,由於是bitmap的緣由,300萬個用戶的數據佔用的長度爲3000000/8=375000字節,也就是45kb不到。
1年也就是16.3Mb的數據。
以前遊戲的經驗,是經過數據庫中的一個column來記錄上一次登陸的時間戳,再用當前時間跟數據庫(MySQL)中記錄的時間作對比來判斷是不是同一天登陸。比較傳統的作法。
這裏能夠一樣利用上面的方法,
$login_status = $redis->getBit('20170323', $uid); if($login_status == 0){ // first login today and send login gifts }
一樣,用來作連續登錄的判斷也很方便,只須要將以前幾天的登陸記錄作一下and
操做,在作判斷就能夠了。
$redis->bitOp('AND', 'stat_3_day_continue', '20161221', '20161222', '20161223'); $is_3_day_continue = $redis->getBit('stat_3_day_continue', $uid); if($is_3_day_continue){ // three days login gifts send }
只要是涉及到相似簽到功能的記錄,不管是以什麼時間間隔爲單位(最終就是反應在key的不一樣),均可以使用Redis的bitmap數據類型。不管是從效率上,仍是資源上,都有很大的優點。