先贊後看,養成習慣❤️php
登陸時間
, 一、二、3...表明 用戶idkey | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
---|---|---|---|---|---|---|---|---|
login20191230 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 |
login20191231 | 0 | 1 | 0 | 0 | 1 | 0 | 0 | 0 |
login20200101 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 |
那麼根據上面位圖能夠得出:
用戶id:1 在 20191231 登陸過
用戶id:2 在 20191230,20200101 登陸過
用戶id:4 在 20191231 登陸過
其他沒有登陸
redis
已是源於 2.2.0 版本的 "新技術"。我以爲你會看到那個 雙引號 不會當真的
新增了setbit
,getbit
,bitcount
等幾個 bitmap 相關命令。但其實 setbit
等命令只不過是在 set
上的擴展而已。算法
指令 SETBIT key offset value
複雜度 O(1)
設置或者清空 key 的 value(字符串)在 offset 處的 bit 值(只能只 0 或者 1)。數組
在一臺 2010MacBook Pro 上網絡
($offset/8/1024/1024)MB
使用時間做爲 cacheKey,而後用戶 ID 爲 offset,若是當日活躍過就設置爲 1
那麼我該若是計算某幾天/月/年的活躍用戶呢(暫且約定,統計時間內只有有一天在線就稱爲活躍),有請下一個 redis 的命令
命令 BITOP operation destkey key [key ...]
說明:對一個或多個保存二進制位的字符串 key 進行位元操做,並將結果保存到 destkey 上。
說明:BITOP 命令支持 AND 、 OR 、 NOT 、 XOR 這四種操做中的任意一種參數ui
//日期對應的活躍用戶
$data = array(
'2020-01-10' => array(1,2,3,4,5,6,7,8,9,10),
'2020-01-11' => array(1,2,3,4,5,6,7,8),
'2020-01-12' => array(1,2,3,4,5,6),
'2020-01-13' => array(1,2,3,4),
'2020-01-14' => array(1,2)
);
//批量設置活躍狀態
foreach($data as $date=>$uids) {
$cacheKey = sprintf("stat_%s", $date);
foreach($uids as $uid) {
$redis->setBit($cacheKey, $uid, 1);
}
}
$redis->bitOp('AND', 'stat', 'stat_2020-01-10', 'stat_2020-01-11', 'stat_2020-01-12');
//總活躍用戶:6
echo "總活躍用戶:" . $redis->bitCount('stat') . PHP_EOL;
$redis->bitOp('AND', 'stat1', 'stat_2020-01-10', 'stat_2020-01-11', 'stat_2020-01-14') . PHP_EOL;
//總活躍用戶:2
echo "總活躍用戶:" . $redis->bitCount('stat1') . PHP_EOL;
$redis->bitOp('AND', 'stat2', 'stat_2020-01-10', 'stat_2020-01-11') . PHP_EOL;
//總活躍用戶:8
echo "總活躍用戶:" . $redis->bitCount('stat2') . PHP_EOL;
複製代碼
假設當前站點有 5000W 用戶,那麼一天的數據大約爲 50000000/8/1024/1024=6MB
spa
這些都大同小異我就不,慢性謀殺大家的時間了。Peace&Love
code
我以爲 人對事物的認知,得通過
懵懂但美好憧憬
->被欺騙(坑)感情
->再次審視本身和事物
才能創建起一個客觀正確
的認知 -- 越欣賞越懂欣賞ip
Redis Bitmap 的好在於 ta 壓縮存儲空間。在平常用法中,這種壓縮的代價是要通過 CPU 運算的。文檔
大量數據的 setBit 會形成大量的網絡請求。因此通常是 程序中 把 id 數組 pack()
設進位圖變成一個 String。再一次性 set 進 Redis。
這就意味着 取出來的時候須要 unpack()
把 String 解壓成 id 數組。不過得益於算法,這一步並不算太複雜
另外ta 存儲的數據至關有限,舉個例子:
// 正常狀況的 用戶 id:一、3 登陸數組:
'login20191230' => array(
1 => array(
'user_id' => 1,
'login_ip' => 'x.x.x.x',
'usage_agent' => 'xxx'
),
3 => array(
'user_id' => 3,
'login_ip' => 'x.x.x.x',
'usage_agent' => 'xxx'
),
)
// bitmap 的 登陸數組
'login20191230' => array(
0 => 0,
1 => 1,
2 => 0,
3 => 1,
)
複製代碼
能夠用的的地方只有
'login20191230' 和 數組裏的 key
你會問 數組裏的 value 不是看起來也能改麼 我給你個表情本身領會😑。硬要折騰是能夠的,只是收支不平衡就是了