• Redis中的位图结构


    【参考】
    《Redis深度历险 核心原理与应用实践》
    【位图的概念】
    对于一些bool类型的数据,如是否签到的场景,虽然单个记录简单,但是需要长期、固定地去记录且用户量很大的时候,那么存储空间是特别惊人的。我们可以利用位图的结构来进行处理,这样可以节省大量空间。
    位图,即在每一位上设置1或者0来标记bool类型的信息,一个字节有8位,所以对于一个需要记录一年365天的签到状态,只需要46个字节(46*8=368)就够了,如果按照2个字节一个字符的字符集格式,只需要23个字符就能够完整地记录下这个信息。
    【Redis中使用位图】
    我们试着把“JAVA”这个单词用位图的形式写入Redis中。“JAVA”用ASCII字符集进行转码,成为二进制后再拼接起来(注意位数组的顺序和字符的位顺序是相反的),如图:

    所以将二进制拼接起来就是:01001010010000010101011001000001,该二进制数组的第一位角标为0,那么需要设置为1的位的位置为:1 4 6 9 15 17 19 21 22 25 31,我们将这些位用setbit key 位标 1的命令设置到Redis中,最终能够用get key获取到字符串。

    这个可以被称为“零存整取”,当然我们也可以进行“零存零取”与“整存零取”,“零取”时使用getbit key 位标的命令。
    【Redis位图的统计与查找】
    上面说到的场景,如签到,到这里应该了解了如何利用位图来实现了。简单说就是每天根据实际的签到情况,setbit到今天对应的位标上。那么如果要查询这个人某一天有没有签到,我们只需要getbit key 日期对应的位标就能搞定;如果查询整个签到或者没有签到的情况,其实也可以“整取”出字符串,然后转为二进制再进行统计。
    但Redis已经提供了一对方便我们进行位图查询和统计的指令,bitcount与bitpos:
    bitcount key #统计整个位为1的总数
    bitcount key start end #这个start与end指第几个字符开始,第几个字符结束,统计整个位为1的总数

    bitpos key bit值 #返回整个key对应值二进制的第一个位值为bit值的位置
    bitpos key bit值 start end #从start到end个字符中,找到第1个出现bit位值的位,在整个二进制的位置

    【bitfield】
    对于setbit和getbit,只能进行一位一位的操作,比如要输入一个“JAVA”,需要setbit很多次才能够达到目的。使用管道可以帮助我们解决多次交互的问题,相当于一次性输入多个指令让redis服务器来处理,再将结果返回给客户端。但在Redis3.2之后,出现了一个bitfield指令,可以指定位进行批量操作,省去了多指令的麻烦。
    bitfield key get [u|i]n start #从第start个位开始,取n位来进行计数,u表示无符号位(所有的位都作为值来进行处理),i表示有符号位(第一位为符号位,后续作为值来处理)
    另外,我们还可以达到跳着执行多个指令的效果:
    bitfield key get u4 0 get u3 2 get O get i3 2

    set子指令也可以进行批量位的替换

    第三个子指令incrby,它用来对指定范围的位进行自增操作。自增就有可能出现溢出。如果增加了正数,会出现上溢出,如果增加的是负数,会出现下溢出。Redis 默认的处理是折返。如果出现了溢出,就将溢出的符号位丢掉。如果是8位无符号数255,加1后就会溢出,会全部变零。如果是8位有符号数127,加1后就会溢出变成-128。
    bitfield key incrby u4 2 1 #从第三个位开始,对接下来的无符号4个位加1
    bitfield指令提供了溢出策略子指令 overflow,用户可以选择溢出行为,默认是折返(wrap),还可以选择失败(fail)——报错不执行,以及饱和截断(sat)——超过了范围就停留在最大或最小值。overflow指令只影响接下来的第-条指令,这条指令执行完后溢出策略会变成默认值折返( wrap)。
    关于bitfield的描述,基本上与原书一样,可以按照参考的图书章节进行学习。对于这样一个不算直观与简单的指令,没有必要精确地记住每一个参数的具体含义,这里我们只需要记得bitfield可以进行批量取位,批量替换位值,以及进行自增,而自增又会出现overflow,Redis对这种overflow进行了哪些处理,即可。在合适的场景中,我们如果能想到有这么个功能,可以为我们提供便捷,即可,具体的参数可以在使用时仔细留意。

  • 相关阅读:
    Microjs: 超棒的迷你框架和迷你类库搜罗工具
    本周推荐7款CSS3实现的动态特效
    Bootstrap3.1开发的响应式个人简历模板
    10分钟,利用canvas画一个小的loading界面
    四款超棒的jQuery数字化签名插件
    搜索引擎优化网页设计:最佳实践
    推荐超实用的8款jQuery插件
    9款HTML5实现的超酷特效
    想成为程序猿?28个在线学习网站让你变身齐天大圣!
    推荐7款超棒的单页面网站设计模板。关键是!免费!!
  • 原文地址:https://www.cnblogs.com/bruceChan0018/p/15652359.html
Copyright © 2020-2023  润新知