【Redis】Redis中BitMap(位图)

BitMap介绍

  BitMap就是位图,其实也就是字节数组(byte array),用二进制表示,只有 0 和 1 两个数字,位图就是用每一个二进制位来存放或者标记某个元素对应的值。通常是用来判断某个数据存不存在的,因为是用bit为单位来存储所以Bitmap本身会极大的节省储存空间。

  如下图字符串在计算机里是由二进制的形式保存的。

   

我们可以在Redis中设置(SET)一个字符串,可以获取(GET),当然除了获取一个完整的字符串,在Redis中也可以对字符串二进制位进行操作。

Redis Getbit 命令用于对 key 所储存的字符串值,获取指定偏移量上的位(bit)。

返回值

  字符串值指定偏移量上的位(bit)。

  当偏移量 OFFSET 比字符串值的长度大,或者 key 不存在时,返回 0 。

  下面一个案例

127.0.0.1:6379> set key1 big
OK
127.0.0.1:6379> getbit key1 0    #获取第一个字母的第一个偏移量
(integer) 0
127.0.0.1:6379> getbit key1 1    #获取第一个字母的第二个偏移量
(integer) 1

 

BitMap相关操作命令

  1. getbit key offset : 对key所存储的字符串值,获取指定偏移量上的位(bit)。

    2. setbit key offset value:对key所存储的字符串值,设置或清除指定偏移量上的位(bit):

                 1)  返回值为该位在setbit之前的值
               2)  value只能取0或1
               3)  offset从0开始,即使原位图只能10位,offset可以取1000
    

 

 案例操作

127.0.0.1:6379> setbit key1 7 1  #将key1第一个字母的最后一个位设置为1
(integer) 0
127.0.0.1:6379> get key1
"cig"

    3. bitcount key [start end]:获取位图指定范围中位值为1的个数如果不指定start与end则取所有。
 
      通过在线工具查看cig字符串的二进制。 在线地址:https://www.qqxiuzi.cn/bianma/erjinzhi.php
        

    使用bitcount命令查看二进制为1的个数就是13

127.0.0.1:6379> get key1
"cig"
127.0.0.1:6379> bitcount key1
(integer) 13
    4. bitop op destKey key1 [key2...]:做多个BitMap的and(交集)、or(并集)、not(非)、xor(异或)操作并将结果保存在destKey中。
    5. bitpos key tartgetBit [start end]:计算位图指定范围第一个偏移量对应的的值等于targetBit的位置:
               1)  找不到返回-1。
               2)  start与end没有设置,则取全部。
               3)  targetBit只能取0或者1。

 

 

BitMap应用场景

  1. 用户在线状态。

  2. 用户签到。

  3. 统计独立用户。

    有1亿用户,5千万登陆用户,那么统计每日用户的登录数。每一位标识一个用户ID,当某个用户访问我们的网站就在Bitmap中把标识此用户的位设置为1。

    这里做了一个使用set集合和BitMap存储的对比。

数据类型 每个 userid 占用空间 需要存储的用户量 全部占用内存量
set(集合) 32位也就是4个字节(假设userid用的是整型,实际很多网站用的是长整型) 50,000,000 32位 * 50,000,000 = 200 MB
BitMap 1 位(bit) 100,000,000 1 位 * 100,000,000 = 12.5 MB

    时间在拉长一点

  一天 一个月 一年
set(集合) 200M 6G 72G
BitMap 12.5M 375M 4.5G

     计算后发现随着时间的增加,要记录数据量的增加,对比更加明显了,BitMap所占的空间比set(集合)更少。

     在看另一个场景假如只有只有100万独立用户,在对比看看。

数据类型 每个 userid 占用空间 需要存储的用户量 全部占用内存量
set(集合) 32位也就是4个字节(假设userid用的是整型,实际很多网站用的是长整型) 1,000,000 32位 * 1,000,000 = 4 MB
BitMap 1 位(bit) 100,000,000 1 位 * 100,000,000 = 12.5 MB

    发现BitMap也不是绝对的好,因为Bitmap本身要额外占用了空间。

 

posted @ 2018-08-08 16:49  songguojun  阅读(3975)  评论(0编辑  收藏  举报