2019独角兽企业重金招聘Python工程师标准>>>

今天无意中看到了redis的一些基本应用场景,记录一下bitmap的用法,觉得比较实用。

下面摘取看到的内容

位操作(大数据处理)

用于数据量上亿的场景下,例如几亿用户系统的签到,去重登录次数统计,某用户是否在线状态等等。

想想一下腾讯10亿用户,要几个毫秒内查询到某个用户是否在线,你能怎么做?千万别说给每个用户建立一个key,然后挨个记(你可以算一下需要的内存会很恐怖,而且这种类似的需求很多,腾讯光这个得多花多少钱。。)好吧。这里要用到位操作——使用setbit、getbit、bitcount命令。

原理是:

redis内构建一个足够长的数组,每个数组元素只能是0和1两个值,然后这个数组的下标index用来表示我们上面例子里面的用户id(必须是数字哈),那么很显然,这个几亿长的大数组就能通过下标和元素值(0和1)来构建一个记忆系统,上面我说的几个场景也就能够实现。用到的命令是:setbit、getbit、bitcount

通过这种方法,可以在redis服务器上迅速获取到想要的结果

先简单描述下bitmap用法

getbit 

字符串值指定偏移量上的位(bit)。

当偏移量 OFFSET 比字符串值的长度大,或者 key 不存在时,返回 0 。

# 对不存在的 key 或者不存在的 offset 进行 GETBIT, 返回 0redis> EXISTS bit
(integer) 0redis> GETBIT bit 10086
(integer) 0# 对已存在的 offset 进行 GETBITredis> SETBIT bit 10086 1
(integer) 0redis> GETBIT bit 10086
(integer) 1

setbit

Redis Setbit 命令用于对 key 所储存的字符串值,设置或清除指定偏移量上的位(bit)。

redis> SETBIT bit 10086 1
(integer) 0redis> GETBIT bit 10086
(integer) 1redis> GETBIT bit 100   # bit 默认被初始化为 0
(integer) 0

bitcount

BITCOUNT key [start] [end]

计算给定字符串中,被设置为 1 的比特位的数量。

一般情况下,给定的整个字符串都会被进行计数,通过指定额外的 start 或 end 参数,可以让计数只在特定的位上进行。

start 和 end 参数的设置和 GETRANGE 命令类似,都可以使用负数值: 比如 -1 表示最后一个字节, -2 表示倒数第二个字节,以此类推。

不存在的 key 被当成是空字符串来处理,因此对一个不存在的 key 进行 BITCOUNT 操作,结果为 0 。

redis> BITCOUNT bits
(integer) 0redis> SETBIT bits 0 1          # 0001
(integer) 0redis> BITCOUNT bits
(integer) 1redis> SETBIT bits 3 1          # 1001
(integer) 0redis> BITCOUNT bits
(integer) 2

具体用例:

模式:使用 bitmap 实现用户上线次数统计

Bitmap 对于一些特定类型的计算非常有效。

假设现在我们希望记录自己网站上的用户的上线频率,比如说,计算用户 A 上线了多少天,用户 B 上线了多少天,诸如此类,以此作为数据,从而决定让哪些用户参加 beta 测试等活动 —— 这个模式可以使用 SETBIT 和 BITCOUNT 来实现。

比如说,每当用户在某一天上线的时候,我们就使用 SETBIT ,以用户名作为 key ,将那天所代表的网站的上线日作为 offset 参数,并将这个 offset 上的为设置为 1 。

举个例子,如果今天是网站上线的第 100 天,而用户 peter 在今天阅览过网站,那么执行命令 SETBIT peter 100 1 ;如果明天 peter 也继续阅览网站,那么执行命令 SETBIT peter 101 1 ,以此类推。

当要计算 peter 总共以来的上线次数时,就使用 BITCOUNT 命令:执行 BITCOUNT peter ,得出的结果就是 peter 上线的总天数。

性能

前面的上线次数统计例子,即使运行 10 年,占用的空间也只是每个用户 10*365 比特位(bit),也即是每个用户 456 字节。对于这种大小的数据来说, BITCOUNT 的处理速度就像 GET 和 INCR 这种 O(1) 复杂度的操作一样快。

如果你的 bitmap 数据非常大,那么可以考虑使用以下两种方法:

将一个大的 bitmap 分散到不同的 key 中,作为小的 bitmap 来处理。使用 Lua 脚本可以很方便地完成这一工作。
使用 BITCOUNT 的 start 和 end 参数,每次只对所需的部分位进行计算,将位的累积工作(accumulating)放到客户端进行,并且对结果进行缓存 (caching)。

更详细的实现可以参考博文(墙外) Fast, easy, realtime metrics using Redis bitmaps 。

假若统计一天的活跃用户

只需要setbit login_count user_id 1 这样就能快速解决问题。

几天的话就需要每天一个bitmap做交集

若时间过长 建议把数据累加出来、爬日志或者直接sql进行操作。

欢迎补充

参考:http://redisdoc.com/string/setbit.html

转载于:https://my.oschina.net/bo081220/blog/1563807

redis bitmap相关推荐

  1. Redis Bitmap 位图

    Redis Bitmap 并不是一个实际的数据类型,而是定义在String类型上的bitwise基于二进制位的一组操作. 因为String是二进制安全的,最大长度512MB,适合构建2的32方个不同的 ...

  2. Redis BitMap适应场景

    https://blog.csdn.net/paul_wei2008/article/details/53366588 Bitmap以及Redis Bitmaps快速入门(Crash Course o ...

  3. redis bitmap存储入门

    # 设置值,其中value只能是 0 和 1 setbit key offset value# 获取值 getbit key offset value只能是0和1,否则会报错 # value只能是0和 ...

  4. Redis BitMap结构实现签到、连续签到统计

    文章目录 一.利用BitMap结构实现签到功能 1.1 BitMap用法 1.2 代码实现签到功能 1.3 统计连续签到 1.3.1 如何得到本月到今天为止的所有签到数据 1.3.2 如何从后向前遍历 ...

  5. Redis bitmap数据格式优化 (RoaringBitmap)

    1. Key-Value 存储 尝试插入1kw条数据, key为设备MD5值, value为1, 此时Redis中存在1kw条key-value键值对. 通过info指令查看内存占用: 1kw数据ke ...

  6. Redis bitmap、hyperlog、布隆过滤器、RoaringBitmap原理应用场景与日活的统计的具体应用

    传统方案-mysql 缺点: 1.空间占用大 2.统计逻辑复杂,比如 统计最近 30 天用户的累计活跃天(每个用户在 30 天里有 N 天使用 app,N 为 1-30,然后将月活跃用户的 N 天加总 ...

  7. Redis bitmap使用场景示例

    bitmap两个应用场景: setbit命令: offset:是二进制位的偏移量,而不是字节数组.一个字节有8个二进制位 将k1的第一个(索引为0)二进制位设置为1: 在ASCII码表中,010000 ...

  8. 利用 Redis Bitmap 统计用户在线次数

    场景1:统计用户A在今年以来的上线次数 基础知识: setbit 用于设置某个key某个offset下面比特位的值,只能是0或1 bitcount 用于统计每个key中,比特位被标记为1的个数 如: ...

  9. BitMap算法应用:Redis队列滤重优化

    工作中有用到Redis滤重队列. 原来的方法如下: 方法一 为了保证操作原子性,使用Redis执行Lua脚本. 在脚本中的逻辑是,如果队列不超过某个数值,进行一次lrem操作(队列使用list结构), ...

最新文章

  1. “新内容 新交互”全球视频云创新挑战赛复赛启幕
  2. 超详细springboot热部署
  3. [转载] ASP.NET MVC4使用百度UEDITOR编辑器
  4. Android图片压缩
  5. HLSL Effect的vertex shader和pixel shader的参数传递
  6. python如何预测双色球信息_python预测下一期双色球号码【机器学习】
  7. 华为电脑管家PcManager多屏协同功能破解
  8. 一个完美网站的101项指标.第二部分.内容为王
  9. C语言揭秘二战德军的顶级加解密技术——恩格玛机!
  10. django中ModelForm多表单组合的解决方案
  11. slf4j日志门面担当
  12. java实现汉字转为拼音
  13. 51单片机精确延时设计
  14. javaSe探赜索隐IO--File
  15. 软件设计师---钉子户
  16. C++--数值的整数次方
  17. 怎么在线快速将多张CAD图纸转换成低版本DXF格式?
  18. java实现文件上传功能详解
  19. java设计奥运图标_15组优秀的奥运会、体育运动类图标系列网页素材
  20. 跟燕青学Redis-Redis集群安装

热门文章

  1. spring cloud gateway之服务注册与发现
  2. Spring Cloud第八篇:Spring Cloud Bus刷新配置
  3. 《如何高效学习》作者推荐!
  4. 6名学生返校后被判定为密接,高校紧急通知!
  5. PyTorch 51.BatchNorm和Dropout层的不协调现象
  6. 最新!2020世界一流大学学术排名出炉:北京大学、清华大学、中国人民大学表现卓越!...
  7. 光缆能预警地震?谷歌做到了!毫秒级反应速度,140万公里海缆有望成为报警器...
  8. 深度学习如何挑选GPU?
  9. Transformer, BERT, ALBERT, XLNet全面解析(ALBERT第一作者亲自讲解)
  10. linux定时任务简记