1、BitMap是什么html
经过一个bit位来表示某个元素对应的值或者状态,其中的key就是对应元素自己,value对应0或1,咱们知道8个bit能够组成一个Byte,因此bitmap自己会极大的节省储存空间。python
2、Redis中的BitMapredis
Redis从2.2.0版本开始新增了setbit、
getbit、
bitcount
等几个bitmap相关命令。虽然是新命令,可是并无新增新的数据类型,由于setbit
等命令只不过是在set
上的扩展。服务器
Redis的bitmap让咱们能够实时的进行统计,而且极其节省空间。在模拟1亿2千8百万用户的模拟环境下,在一台MacBookPro上,典型的统计如“日用户数”(dailyunique users) 的时间消耗小于50ms, 占用16MB内存。spa
Bitmap是一串连续的2进制数字(0或1),每一位所在的位置为偏移(offset),在bitmap上可执行AND,OR,XOR以及其它位操做。设计
3、Redis中的命令code
一、setbithtm
语法:setbit key offset valueblog
描述:内存
对key所储存的字符串值,设置或清除指定偏移量上的位(bit)。
位的设置或清除取决于 value
参数,能够是 0
也能够是 1
。
当 key
不存在时,自动生成一个新的字符串值。
字符串会进行伸展(grown)以确保它能够将 value
保存在指定的偏移量上。当字符串值进行伸展时,空白位置以 0
填充。
注意:
offset
参数必须大于或等于 0
,小于 2^32 (bit 映射被限制在 512 MB 以内)。
由于 Redis 字符串的大小被限制在 512 兆(megabytes)之内, 因此用户可以使用的最大偏移量为 2^29-1(536870911) , 若是你须要使用比这更大的空间, 请使用多个 key。
当生成一个很长的字符串时, Redis 须要分配内存空间, 该操做有时候可能会形成服务器阻塞(block)。 在2010年出产的Macbook Pro上, 设置偏移量为 536870911(512MB 内存分配)将耗费约 300 毫秒, 设置偏移量为 134217728(128MB 内存分配)将耗费约 80 毫秒, 设置偏移量 33554432(32MB 内存分配)将耗费约 30 毫秒, 设置偏移量为 8388608(8MB 内存分配)将耗费约 8 毫秒。
二、getbit
语法:getbit key offset
描述:
对 key
所储存的字符串值,获取指定偏移量上的位(bit)。
当 offset
比字符串值的长度大,或者 key
不存在时,返回 0
三、bitcount
语法:bitcount key [start] [end]
返回值:被设置为 1
的位的数量
描述:
计算给定字符串中,被设置为 1
的比特位的数量
通常状况下,给定的整个字符串都会被进行计数,经过指定额外的 start
或 end
参数,可让计数只在特定的位上进行。
start
和 end
参数的设置和 GETRANGE key start end 命令相似,均可以使用负数值: 好比 -1
表示最后一个字节, -2
表示倒数第二个字节,以此类推。
不存在的 key
被当成是空字符串来处理,所以对一个不存在的 key
进行 BITCOUNT
操做,结果为 0
。
四、bitpos
五、bitop
语法:bitop operation destkey key [key ...]
operation
能够是 AND
、 OR
、 NOT
、 XOR
这四种操做中的任意一种:
BITOP AND destkey key [key ...]
,对一个或多个 key
求逻辑并,并将结果保存到 destkey
。 BITOP OR destkey key [key ...]
,对一个或多个 key
求逻辑或,并将结果保存到 destkey
。 BITOP XOR destkey key [key ...]
,对一个或多个 key
求逻辑异或,并将结果保存到 destkey
。 BITOP NOT destkey key
,对给定 key
求逻辑非,并将结果保存到 destkey
。 除了 NOT
操做以外,其余操做均可以接受一个或多个 key
做为输入。
返回值:保存到 destkey
的字符串的长度,和输入 key
中最长的字符串长度相等
描述:
对一个或多个保存二进制位的字符串 key
进行位元操做,并将结果保存到 destkey
上。
注意:处理不一样长度的字符串
当 BITOP 处理不一样长度的字符串时,较短的那个字符串所缺乏的部分会被看做 0
。
空的 key
也被看做是包含 0
的字符串序列。
六、bitfield
4、应用场景
一、位图计数统计
位图计数统计的是bitmap中值为1的位的个数。位图计数的效率很高,例如,一个bitmap包含10亿个位,90%的位都置为1,在一台MacBook Pro上对其作位图计数须要21.1ms。
例子:日活跃用户
为了统计今日登陆的用户数,咱们创建了一个bitmap,每一位标识一个用户ID。当某个用户访问咱们的网页或执行了某个操做,就在bitmap中把标识此用户的位置为1。
每次用户登陆时会执行一次redis.setbit(daily_active_users, user_id, 1)。将bitmap中对应位置的位置为1,时间复杂度是O(1)。统计bitmap结果显示有今天有9个用户登陆。Bitmap的key是daily_active_users,它的值是1011110100100101。
由于日活跃用户天天都变化,因此须要天天建立一个新的bitmap。咱们简单地把日期添加到key后面,实现了这个功能。例如要统计某一天有多少个用户访问,能够把这个bitmap的key设计为daily_active_users:2019-03-27。当用户访问进来,咱们只是简单地在bitmap中把标识这个用户的位置为1,时间复杂度是O(1)。
备注:
Redis原生指令参考 http://redisdoc.com/index.html
Redis python客户端 方法参考 http://redis-py.readthedocs.io/en/latest/#indices-and-tables