setbit命令
语法:SETBIT key offset value
其中 offset 必须是数字,value 只能是 0 或者 1,感觉没啥用处,我们先来看看 bitmap 的具体表示,当我们使用命令 setbit key (0,2,5,9,12) 1后,它的具体表示为:
byte | bit0 | bit1 | bit2 | bit3 | bit4 | bit5 | bit6 | bit7 |
---|---|---|---|---|---|---|---|---|
byte0 | 1 | 0 | 1 | 0 | 0 | 1 | 0 | 0 |
byte1 | 0 | 1 | 0 | 0 | 1 | 0 | 0 | 0 |
可以看出 bit 的默认值是 0,那么 BitMap 在实际开发的运用呢?这里举一个例子:储存用户在线状态。这里只需要一个 key,然后把用户 ID 作为 offset,如果在线就设置为 1,不在线就设置为 0。实例代码:(bitcount:统计1的数量,可指定范围)
//设置在线状态
$redis->setBit('online', $uid, 1);
//设置离线状态
$redis->setBit('online', $uid, 0);
//获取状态
$isOnline = $redis->getBit('online', $uid);
//获取在线人数
$isOnline = $redis->bitCount('online');
//获取都为1的用户
l例如:
具体操作过程如下,unique:users:2016-04-05代表2016-04-05这天的独立访问用户的Bitmaps:
127.0.0.1:6379> setbit unique:users:2016-04-05 0 1
(integer) 0
127.0.0.1:6379> setbit unique:users:2016-04-05 5 1
(integer) 0
127.0.0.1:6379> setbit unique:users:2016-04-05 11 1
(integer) 0
127.0.0.1:6379> setbit unique:users:2016-04-05 15 1
(integer) 0
127.0.0.1:6379> setbit unique:users:2016-04-05 19 1
(integer) 0
获取键的第offset位的值(从0开始计算),如果返回0代表没有访问,返回1代表访问过。
127.0.0.1:6379> getbit unique:users:2016-04-05 8
(integer) 0
127.0.0.1:6379> getbit unique:users:2016-04-05 5
(integer) 1
127.0.0.1:6379> getbit unique:users:2016-04-05 1000
(integer) 0
#不存在1000,自然返回0
(3)获取Bitmaps指定范围值为1的个数
127.0.0.1:6379> bitcount unique:users:2016-04-05
(integer) 5
127.0.0.1:6379> bitcount unique:users:2016-04-05 10 20
(integer) 0
127.0.0.1:6379> bitcount unique:users:2016-04-05 1 3
(integer) 3
#start和and代表字节数,一个字节8位,1到3个字节就是索引在8到23之间
Bitmaps性能
假设网站有1亿用户,每天独立访问的用户是5000万,如果每天用集合类型和Bitmaps分别存储活跃用户。
很容易看出,在这种情况下Bitmaps能节省很多内存空间,尤其随着时间推移比较客观。
但是Bitmaps并不是万金油,当该网站每天访问的用户很少时,Bitmaps就有点不合时宜了。