zoukankan      html  css  js  c++  java
  • 【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本身要额外占用了空间。

  • 相关阅读:
    接口实际上是定义一个规范、标准
    类必须实现接口中的方法,否则其为一抽象类
    JAVA的核心概念:接口(interface)
    子类的方法必须覆盖父类的抽象方法
    Abstract可以将子类的共性最大限度的抽取出来,放在父类中,以提高程序的简洁性
    如果将一个类设置为abstract,则此类必须被继承使用
    在JAVA中利用public static final的组合方式对常量进行标识
    final可以修饰类、属性、方法
    覆盖不适用于静态方法
    静态方法不需要有对象,可以使用类名调用
  • 原文地址:https://www.cnblogs.com/songgj/p/9443860.html
Copyright © 2011-2022 走看看