核心知识点:

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:> setbit unique:users:--
(integer)
127.0.0.1:> setbit unique:users:--
(integer)
127.0.0.1:> setbit unique:users:--
(integer)
127.0.0.1:> setbit unique:users:--
(integer)
127.0.0.1:> setbit unique:users:--
(integer)

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

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

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

(2)获取值

getbit key offset

获取键的第offset位的值(从0开始计算),如果返回0代表没有访问,返回1代表访问过。

127.0.0.1:> getbit unique:users:--
(integer)
127.0.0.1:> getbit unique:users:--
(integer)
127.0.0.1:> getbit unique:users:--
(integer)
#不存在1000,自然返回0

(3)获取Bitmaps指定范围值为1的个数

bitcount key [start] [end]
127.0.0.1:> bitcount unique:users:--
(integer)
127.0.0.1:> bitcount unique:users:--
(integer)
127.0.0.1:> bitcount unique:users:--
(integer)
#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:> bitop and unique:users:and:--03_04 unique:users:-- unique:users:--
(integer)
127.0.0.1:> bitcount unique:users:and:--03_04
(integer)

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

127.0.0.1:> bitop or unique:users:or:--03_04 unique:users:-- unique:users:--
(integer)
127.0.0.1:> bitcount unique:users:or:--03_04
(integer)

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

bitpos key targetBit [start] [end]

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

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

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

127.0.0.1:> bitpos unique:users:--
(integer)

3.Bitmaps性能分析

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

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

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

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

Bitmaps的更多相关文章

  1. Displaying Bitmaps Efficiently 显示图片相关

    http://developer.android.com/training/displaying-bitmaps/index.html .手机内存资源有限 .Bitmap占用的内存大 .App有时需要 ...

  2. 使用Redis bitmaps进行快速、简单、实时统计

    原文:Fast, easy, realtime metrics using Redis bitmaps (http://blog.getspool.com/2011/11/29/fast-easy-r ...

  3. 高效使用Bitmaps(三) 神奇的Cache

    转载:http://my.oschina.net/rengwuxian/blog/184650 应用的场景 假设你开发了一个聊天程序,它的好友列表中显示从网络获取的好友头像.可是如果用户发现每次进入好 ...

  4. 高效使用Bitmaps(一) 大Bitmap的加载

    转载:http://my.oschina.net/rengwuxian/blog/182885 高效使用Bitmaps有什么好处? 我们常常提到的“Android程序优化”,通常指的是性能和内存的优化 ...

  5. android 如何分析java.lang.IllegalArgumentException: Cannot draw recycled bitmaps异常

    这类问题的分析,通常你需要找到bitmap对象已经在那个位置recyle,然后检查代码. 如何定位的位置,其中代码具有对bitmap 目的recyle.能够 Bitmap.java的recycle方法 ...

  6. Android IllegalArgumentException: Cannot draw recycled bitmaps解决方法

    在编码图集过程中,出现了Android IllegalArgumentException: Cannot draw recycled bitmaps错误. 大致意思是:不能使用已经被回收的bitmap ...

  7. Tkinter Bitmaps

       Tkinter Bitmaps: 你会使用这个属性显示一个位图.有以下类型的可用位图. 你会使用这个属性显示一个位图.有以下类型的可用位图.: "error" "g ...

  8. 在UI线程之外,多线程处理Bitmaps

    多线程处理Bitmaps     上一篇,我们讨论了:Android有效的处理Bitmap,降低内存 ,可是最好不要运行在主线程(UI线程),假设图片是本地的或者网络的又或者是其它地方的. 图片载入的 ...

  9. Loading Large Bitmaps Efficiently

    有效地加载大位图文件-Loading Large Bitmaps Efficiently 图像有各种不同的形状和大小.在许多情况下,他们往往比一个典型应用程序的用户界面(UI)所需要的资源更大.例如, ...

随机推荐

  1. ios界面笔记(一)

    基于一个简单视图的view解析

  2. EasyMvc入门教程-高级控件说明(17)对话框控件

    上一节我们说到的信息框比较简单,如果我们想简单实现用户用户交互,比如常用的锁屏界面,应该如何实现呢?首先看效果: 当用户输入"mxd",后,界面显示如下: 以上效果的实现代码为: ...

  3. 一张图,关于 Bayes error rate,贝叶斯错误率等的分析

    造轮子是那帮搞研究的“科学家”干的事情(类似E&E里的explore),“工程师”的职责是利用已有的东西解决问题(类似E&E里的exploit). 其次,即使以工程师的角色解决业务问题 ...

  4. AutoCAD如何设置A0A1图纸

    可以从网上下载相应的图纸模板,下载之后可以发现有相应的文字和模板文件   随后我们新建并找到这个dwt文件模板(比如要做一个A1的模板)   随后即可发现模板的样式,包括每种颜色的粗细,颜色和明细栏等 ...

  5. Android设计中的尺寸问题

    Android把屏幕大小分成四种:small, normal, large, xlarge; 屏幕密度分成:low(ldpi), medium(mdpi), high(hdpi), extra hig ...

  6. HTTP基础(整理)

    前一段时间看了有关这个协议的相关文档,对这个协议有了新的理解,这里整理一下. http是应用层面向对象的协议. 它有以下几个特点: 1.  支持客户服务器模式(这是废话,不支持这个模式怎么工作) 2. ...

  7. sql 查询 一张表里面的数据 在另一张表中是否存在 和 比对两个集合中的差集和交集(原创)

    这两天在搞一个修复的小功能 需求: A表,B表,C表,日志文件 先筛选出A表和B表中都符合条件的数据,然后检查这些数据在C表中是否存在.如果不存在,就从日志中读取数据,存入C表中,如果存在,则不做操作 ...

  8. 广告banner:手动滑动切换,自动切换,点击跳转,异步加载网络图片

    效果图: 该banner功能有自动切换图片,点击图片可以自定义事件,手动滑动切换,异步加载图片 代码说话: 布局文件: <!-- 广告位 --> <FrameLayout andro ...

  9. 常见的CPU訪问引起的内存保护问题为什么仅仅用event_122上报 - 举例2

    还有一个样例.通过以下的log看,CPU在訪问reserved的地址0x53611EFD.非法訪问时该地址会在L1D内存控制器的L1DMPFSR寄存器中记录. ** FATAL EXCEPTION N ...

  10. android开发系列之ContentObserver

    在这篇博客里面我想要分享一下自己最近在项目里面遇到一个比较好的数据同步解决方案,首先让我们先来看看该方案的应用场景:我们在客户端本地利用数据库缓存了一些数据,当我们检测到数据库里面的数据发生变化的时候 ...