Redis--位图BitMap
一、BitMap是什么
通过一个bit位来表示某个元素对应的值或者状态,其中的key就是对应元素本身,value对应0或1,我们知道8个bit可以组成一个Byte,所以bitmap本身会极大的节省储存空间。
二、Redis中的BitMap
Redis从2.2.0版本开始新增了setbit、
getbit、
bitcount
等几个bitmap相关命令。虽然是新命令,但是并没有新增新的数据类型,因为setbit
等命令只不过是在set
上的扩展。
Redis的bitmap让我们可以实时的进行统计,并且极其节省空间。在模拟1亿2千8百万用户的模拟环境下,在一台MacBookPro上,典型的统计如“日用户数”(dailyunique users) 的时间消耗小于50ms, 占用16MB内存。
Bitmap是一串连续的2进制数字(0或1),每一位所在的位置为偏移(offset),在bitmap上可执行AND,OR,XOR以及其它位操作。
三、Redis中的命令
1、setbit
语法:setbit key offset value
描述:
对key所储存的字符串值,设置或清除指定偏移量上的位(bit)。
位的设置或清除取决于 value
参数,可以是 0
也可以是 1
。
当 key
不存在时,自动生成一个新的字符串值。
字符串会进行伸展(grown)以确保它可以将 value
保存在指定的偏移量上。当字符串值进行伸展时,空白位置以 0
填充。
注意:
offset
参数必须大于或等于 0
,小于 2^32 (bit 映射被限制在 512 MB 之内)。
因为 Redis 字符串的大小被限制在 512 兆(megabytes)以内, 所以用户能够使用的最大偏移量为 2^29-1(536870911) , 如果你需要使用比这更大的空间, 请使用多个 key。
当生成一个很长的字符串时, Redis 需要分配内存空间, 该操作有时候可能会造成服务器阻塞(block)。 在2010年出产的Macbook Pro上, 设置偏移量为 536870911(512MB 内存分配)将耗费约 300 毫秒, 设置偏移量为 134217728(128MB 内存分配)将耗费约 80 毫秒, 设置偏移量 33554432(32MB 内存分配)将耗费约 30 毫秒, 设置偏移量为 8388608(8MB 内存分配)将耗费约 8 毫秒。
2、getbit
语法:getbit key offset
描述:
对 key
所储存的字符串值,获取指定偏移量上的位(bit)。
当 offset
比字符串值的长度大,或者 key
不存在时,返回 0
3、bitcount
语法:bitcount key [start] [end]
返回值:被设置为 1
的位的数量
描述:
计算给定字符串中,被设置为 1
的比特位的数量
一般情况下,给定的整个字符串都会被进行计数,通过指定额外的 start
或 end
参数,可以让计数只在特定的位上进行。
start
和 end
参数的设置和 GETRANGE key start end 命令类似,都可以使用负数值: 比如 -1
表示最后一个字节, -2
表示倒数第二个字节,以此类推。
不存在的 key
被当成是空字符串来处理,因此对一个不存在的 key
进行 BITCOUNT
操作,结果为 0
。
4、bitpos
5、bitop
语法:bitop operation destkey key [key ...]
operation
可以是 AND
、 OR
、 NOT
、 XOR
这四种操作中的任意一种:
BITOP AND destkey key [key ...]
,对一个或多个key
求逻辑并,并将结果保存到destkey
。BITOP OR destkey key [key ...]
,对一个或多个key
求逻辑或,并将结果保存到destkey
。BITOP XOR destkey key [key ...]
,对一个或多个key
求逻辑异或,并将结果保存到destkey
。BITOP NOT destkey key
,对给定key
求逻辑非,并将结果保存到destkey
。
除了 NOT
操作之外,其他操作都可以接受一个或多个 key
作为输入。
返回值:保存到 destkey
的字符串的长度,和输入 key
中最长的字符串长度相等
描述:
对一个或多个保存二进制位的字符串 key
进行位元操作,并将结果保存到 destkey
上。
注意:处理不同长度的字符串
当 BITOP 处理不同长度的字符串时,较短的那个字符串所缺少的部分会被看作 0
。
空的 key
也被看作是包含 0
的字符串序列。
6、bitfield
四、应用场景
1、位图计数统计
位图计数统计的是bitmap中值为1的位的个数。位图计数的效率很高,例如,一个bitmap包含10亿个位,90%的位都置为1,在一台MacBook Pro上对其做位图计数需要21.1ms。
例子:日活跃用户
为了统计今日登录的用户数,我们建立了一个bitmap,每一位标识一个用户ID。当某个用户访问我们的网页或执行了某个操作,就在bitmap中把标识此用户的位置为1。
每次用户登录时会执行一次redis.setbit(daily_active_users, user_id, 1)。将bitmap中对应位置的位置为1,时间复杂度是O(1)。统计bitmap结果显示有今天有9个用户登录。Bitmap的key是daily_active_users,它的值是1011110100100101。
因为日活跃用户每天都变化,所以需要每天创建一个新的bitmap。我们简单地把日期添加到key后面,实现了这个功能。例如要统计某一天有多少个用户访问,可以把这个bitmap的key设计为daily_active_users:2019-03-27。当用户访问进来,我们只是简单地在bitmap中把标识这个用户的位置为1,时间复杂度是O(1)。
备注:
Redis原生指令参考 http://redisdoc.com/index.html
Redis python客户端 方法参考 http://redis-py.readthedocs.io/en/latest/#indices-and-tables
Redis--位图BitMap的更多相关文章
- redis位图(bitmap)常用命令的解析
描述 bitmap是redis封装的用于针对位(bit)的操作,其特点是计算效率高,占用空间少,常被用来统计用户签到.登录等场景 常用命令及解析 常用命令 setbit key offset va ...
- 基于Redis位图实现系统用户登录统计
项目需求,试着写了一个简单登录统计,基本功能都实现了,日志数据量小.具体性能没有进行测试~ 记录下开发过程与代码,留着以后改进! 1. 需求 1. 实现记录用户哪天进行了登录,每天只记录是否登录过,重 ...
- Redis位图实现用户签到功能
场景需求 适用场景如签到送积分.签到领取奖励等,大致需求如下: 签到1天送1积分,连续签到2天送2积分,3天送3积分,3天以上均送3积分等. 如果连续签到中断,则重置计数,每月初重置计数. 当月签到满 ...
- 基于Redis位图实现用户签到功能
场景需求 适用场景如签到送积分.签到领取奖励等,大致需求如下: 签到1天送1积分,连续签到2天送2积分,3天送3积分,3天以上均送3积分等. 如果连续签到中断,则重置计数,每月初重置计数. 当月签到满 ...
- (算法)位图BitMap
题目: 给定一数组,大小为M,数组中的数字范围为1-N,如果某带宽有限,无法传输该大小的数组,该怎么办? 思路: 通过位图BitMap来压缩数组,将数组中每个数字在bit位上标志,这样就可以将数组大小 ...
- Redis位图法记录在线用户的状态
Redis位图法记录在线用户的状态 位图 Redis官方文档对于位图的介绍如下: 位图不是一个真实的数据类型,而是定义在字符串类型上的面向位的操作的集合.由于字符串类型是二进制安全的二进制大对象,并且 ...
- 巧用redis位图存储亿级数据与访问 - 简书
原文:巧用redis位图存储亿级数据与访问 - 简书 业务背景 现有一个业务需求,需要从一批很大的用户活跃数据(2亿+)中判断用户是否是活跃用户.由于此数据是基于用户的各种行为日志清洗才能得到,数据部 ...
- EmguCV从位图(Bitmap)加载Image<Gray,byte>速度慢的问题
先说背景.最近在用C#+EmguCV(其实就是用P/Invoke封闭了OpecCV,与OpenCVDotNet差不多) 做一个视频的东西.视频是由摄像头采集回来的1f/s,2048X1000大小,其实 ...
- 基于Redis分布式BitMap的应用
一.序言 在实际开发中常常遇到如下需求:判断当前元素是否存在于已知的集合中,将已知集合中的元素维护一个HashSet,使用时只需耗时O(1)的时间复杂度便可判断出结果,Java内部或者Redis均提供 ...
- redis位图命令
概述 redis 的位图就是01的数据格式,redis 主要做有写入,读取和统计.位图相关的命令 : 其中set和get就是 read 和writer , bitcount 统计相关,bitop 是对 ...
随机推荐
- Vue 框架-10-搭建脚手架 CLI
Vue 框架-10-搭建脚手架 CLI + 批处理快捷启动 脚手架是通过 webpack 搭建的开发环境 使用 ES6 语法 打包和压缩 JS 为一个文件 项目文件在环境中,而不是浏览器 实现页面自动 ...
- Pig sample用法举例
some = sample data 0.1 遍历整个数据集,获取指定比例的行数的数据,获取的数据不确定,条数也不准确. 内部重写为filter data by random() <= ...
- Sink Prosessor - Flume的可靠性保证:故障转移、负载均衡
Flume的一些组件(如Spooling Directory Source.File Channel)能够保证agent挂掉后不丢失数据. 1.负载均衡 1)Load balancing Sink P ...
- 签署您的应用--手动签署 APK
签署您的应用 本文内容 证书和密钥库 签署您的调试构建 调试证书的有效期 管理您的密钥 使用 Google Play 应用签名 自行管理您的密钥和密钥库 签署 APK 生成密钥和密钥库 手动签署 AP ...
- zTree设置异步加载后展开
//不能直接配置展开属性 因为没有数据,需要添加回调函数,异步加载成功展开 callback: { onAsyncSuccess: zTreeOnAsyncSuccess } //异步加载成功回调函数 ...
- SQLServer 查询使用键查找时锁申请及释放顺序
最近看了高兄的一篇文章,Sql Server 高频,高并发访问中的键查找死锁解析,很有收获,里面讲到了键查找引起的死锁问题. 当然看的过程中,其实自己有个疑问: 对于键查找这类查询,会申请哪些锁,锁申 ...
- ORACLE数据泵还原(IMPDP命令)
Oracle数据库还原IMPDP命令是相对于EXPDP命令的,方向是反向的.即对于数据库备份进行还原操作.一.知晓IMPDP命令 C:\>impdp -help Import: Release ...
- 分别用C/C++ 和 C#实现简单的观察者模式
网上找了很多关于观察者模式的代码例子和文章,都写的比较复杂,我个人还是喜欢从易到难,今天自己参考网上资料,也写了一个简单观察者模式的例子,简单的复习了一下Observer 模式,Observer 模式 ...
- linux克隆机器
首先你要先点击你的虚拟机点击克隆: 然后执行这个 vim /etc/sysconfig/network-scripts/ifcfg-eth0 去这里修改这两行 然后注释了 然后再执行这个 > / ...
- Linux装python3
记住下载的软件最好装在/opt下默认的 大家都这样做 linux装python3.7我们以安装最新的来做测试 先下载关联的包防止出错 安装python前的库环境,非常重要yum install gc ...