• Bitmaps


    核心知识点:

    1.Bitmaps是一种特殊的“数据结构”,实质上是一个字符串,操作单元是位。

    2.命令:

      a.setbit:设置值,只能存储0和1,适用二元判断类型

      b.getbit:获取值

      c.bitcount:统计1的数量,可指定范围

      d.bitop:可取交集、并集、非、异或

      e.bitpos:第一个获取某种状态的偏移量

    3.Bitmaps并不是任何场合都适合,在某些场合适用会有意想不到的效果。

    1.数据结构模型

    现代计算机用二进制(位)作为信息的基础单位,1个字节等位8位,例如“big”字符串是由3个字节组成,

    但实际在计算机存储时将其用二进制表示,“big”分别对应的ASCII码分别是98、105、103,

    对应的二进制分别是01100010、01101001和01100111,如下图:

    许多开发语言都提供了操作位功能,合理地使用位能够有效地提高内存使用率和开发效率。

    Redis提供了Bitmaps这个“数据结构”,可以实现对位的操作。把数据结构加上引号主要因为:

    (1)Bitmaps本身不是一种数据结构,实际上它就是字符串,,但它可以对字符串的位进行操作;

    (2)Bitmaps单独提供了一套命令,所以在Redis中使用Bitmaps和使用字符串的方法不太一样。

      可以把Bitmaps想象成一个以位为单位的数组,数组的每个单元只能存储0和1,数组的下标在Bitmaps中叫做偏移量。

    2.命令

    本节将每个独立用户是否访问过网站存放在Bitmaps中,将访问的用户记做1,没有访问的用户记做0,用偏移量作为用户的id。

    (1)设置值

    setbit key offset value

    设置键的第offset个位的值(从0算起),假设现在有20个用户,userid=0,5,11,15,19的用户对网站进行了访问,

    那么当前Bitmaps初始化结果如图:

    具体操作过程如下,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

    很多应用的用户id以一个指定的数字(例如10000)开头,直接将用户id和Birmaps的偏移量对应势必会造成一定的浪费,

    通常的做法是每次做setbit操作时将用户id减去这个指定数字。

    在第一次初始化Bitmaps时,如果偏移量非常大,那么整个初始化过程执行会比较慢,可能会造成Redis阻塞。

    (2)获取值

    getbit key offset

    获取键的第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的个数

    bitcount key [start] [end]
    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之间

    (4)Bitmaps间的运算

    bitop op destkey key [key ...]

    bitop是一个复合操作,它可以做多个Bitmaps的and(交集)、or(并集)、not(非)、xor(异或)操作,并将结果保存在destkey中。

    下面有该网站连续2天客户访问的Bitmaps记录:

    下面操作计算两天都访问网站的用户数:

    127.0.0.1:6379> bitop and unique:users:and:2016-04-03_04 unique:users:2016-04-03 unique:users:2016-04-04
    (integer) 2
    127.0.0.1:6379> bitcount unique:users:and:2016-04-03_04
    (integer) 2

    下面操作计算两天中至少有一天访问网站的用户数:

    127.0.0.1:6379> bitop or unique:users:or:2016-04-03_04 unique:users:2016-04-03 unique:users:2016-04-04
    (integer) 2
    127.0.0.1:6379> bitcount unique:users:or:2016-04-03_04
    (integer) 6

    (5)计算Bitmaps中第一个值为tergetBit的偏移量

    bitpos key targetBit [start] [end]

    下面操作计算2016-04-03这一天当前访问网站的最小用户id:

    127.0.0.1:6379> bitpos unique:users:2016-04-03 1
    (integer) 0  #索引为1的用户最先访问

    除此之外,bitpos还可以指定start和end,分别代表起始字节和结束字节:

    127.0.0.1:6379> bitpos unique:users:2016-04-04 1 1 2
    (integer) 9

    3.Bitmaps性能分析

    假设网站有1亿用户,每天独立访问的用户是5000万,如果每天用集合类型和Bitmaps分别存储活跃用户。

    很容易看出,在这种情况下Bitmaps能节省很多内存空间,尤其随着时间推移比较客观。

    但是Bitmaps并不是万金油,当该网站每天访问的用户很少时,Bitmaps就有点不合时宜了。

    注释:由于有5000万活跃用户,每个用户一个id,这就需要8位数字表示,每个数字一个字节因此就是64位。

  • 相关阅读:
    将所有程序设置XML集中到一个单独XML配置文件的方法:使用appSettings元素的configSource元素
    MVC中JQuery文件引入的路径问题,@Url.Content函数
    EF的表连接方法Include()
    在使用EFCodeFirst中出现类型“System.Data.Objects.ObjectContext”在未被引用的程序集中定义的解决方案
    总结下遇到的C#新语法
    MVC3下的layout页面
    C#委托初探
    WebBrowser Control
    Python之面向对象二
    Python之面向对象一
  • 原文地址:https://www.cnblogs.com/yangmingxianshen/p/8179865.html
Copyright © 2020-2023  润新知