redis的bitset实战
序
本文主要研究一下redis的bitset数据结构的用场
相关命令
SETBIT
时间复杂度为O(1)
setbit login.20180906 102400000 0
setbit login.20180905 201400000 1
复制代码
GETBIT
时间复杂度为O(1)
getbit login.20180905 201400000
复制代码
BITOP
时间复杂度为O(N)
bitop or login.9m.week1or login.20180905 login.20180906
getbit login.9m.week1or 201400000
复制代码
主要做bitset的and、or、xor、not操作,结果存在新的bitset中,注意时间复杂度为O(N)
BITPOS
时间复杂度为O(N)
bitpos login.20180905 1
复制代码
返回指定bitset中在指定起始位置中第一个出现指定值的offset,不传start,end默认估计是0,-1
BITCOUNT
时间复杂度为O(N)
bitcount login.20180905
复制代码
统计bitset中出现1的个数
使用场景
假设有个签到的需求,要实现的功能如下:
- 展示当天是否已经签到,签到了不能再签到了
- 展示最近一周的或者最近一个月的签到情况/历史(可以只不详细记录到每天的签到时间,只记录每天是否签到)
- 判断是否连续签到,若本周连续签到,则给予抽奖机会
这里我们就可以使用redis的bitset来实现:
签到
boolean originValue = redisTemplate.opsForValue().setBit(uidYearKey,dayIndx,true);
复制代码
- 这里的key由uid,year构成,然后offset采用day的index
- 每个uid每个year一个key的话,如果用户数过多可能造成redis的key太多
获取签到数据
BitSet bitSet = fromByteArrayReverse(redisTemplate.opsForValue().get(uidYearKey).getBytes());public static BitSet fromByteArrayReverse(final byte[] bytes) {final BitSet bits = new BitSet();for (int i = 0; i < bytes.length * 8; i++) {if ((bytes[i / 8] & (1 << (7 - (i % 8)))) != 0) {bits.set(i);}}return bits;}
复制代码
- 这里有个注意事项,java读取bytes从小到大是从右往左读(
大端
),而redis存储的bytes从小到大是从左往右(小端
),因而这里读取bytes转为BitSet需要逆向一下
BitSet Range
public BitSet get(int fromIndex, int toIndex) {//......
}
复制代码
- BitSet有个方法,可以根据index来进行range,之后就可以用新的BitSet进行相关统计,比如BitSet的cardinality
小结
- 对于bitset来说,其优点就是节省内存,如果直接把用户id作为offset来存储相应的值,这个相比hash来说,节省了很多空间。类似统计最近N天连续登陆的人的个数这类场景就可以使用bitset来实现。
- 对于bitset的操作要注意,各个操作的时间复杂度,如果是getbit、setbit则都是O(1),bitop、bitcount、bitpos等都是O(N),在N比较大的时候要注意,可能是潜在的慢查询
doc
- setbit
- getbit
- bitop
- bitpos
- bitcount
- Efficient analytics with Redis bitmaps
- Be Careful With your Redis BitSets and Java
- REDIS BITMAPS – FAST, EASY, REALTIME METRICS
- Bitmaps vs. Sets to track Monthly Active Users in Redis
- storing-hundreds-of-millions-of-simple-keys-in-282-mb-with-redis
redis的bitset实战相关推荐
- 《Redis核心技术与实战》学习总结(1)
[Redis]| 总结/Edison Zhou 0写在开头 作为Key/Value键值数据库,Redis的应用非常广泛.在之前多年的工作生涯中,我也只是关注了零散的技术点,没有对Redis建立起一套整 ...
- 《Redis核心技术与实战》学习总结(2)
[Redis]| 总结/Edison Zhou 1上一篇的遗留问题 上一篇总结了一个KV数据库的基本架构 和 Redis的底层数据结构概览,重点总结了Sorted Set的两个数据结构的切换,但没有介 ...
- 极客时间 Redis核心技术与实战 笔记(基础篇)
Redis 概览 Redis 知识全景图 Redis 问题画像图 基础篇 基本架构 数据结构 数据类型和底层数据结构映射关系 全局哈希表 链式哈希解决哈希冲突 渐进式 rehash 不同数据结构查找操 ...
- 火影专场:Redis分布式锁实战
火影专场:Redis分布式锁实战 我们学习 Java 都知道锁的概念,例如基于 JVM 实现的同步锁 synchronized,以及 jdk 提供的一套代码级别的锁机制 lock,我们在并发编程中会经 ...
- 网易有道 | REDIS 云原生实战
REDIS 云原生实战 摘要 本次以Redis为范例,阐述了有道基础架构团队在基础设施容器化道路上的实践,主要将从声明式管理,Operator工作原理,容器编排,主从模式,集群模式,高可用策略,集群扩 ...
- Redis入门到实战
redis入门与实战 一.Nosql概述 1.为什么要用Nosql 1.1 单机 MySQL 的美好时代 来源博客(https://www.cnblogs.com/lukelook/p/1113520 ...
- 四.redis的基础+实战
四.redis的基础+实战 1.redis是什么? 2.redis常用于什么? 3.docker安装redis 4.java连接redis进行缓存 5.操作redis数据库的类 6.redis结合js ...
- Redis核心技术与实战-蒋德钧-课程笔记
一.Redis知识全景图 二.Redis问题画像图 参考资料: 极客时间<Redis核心技术与实战>课程
- Redis学习笔记②实战篇_黑马点评项目
若文章内容或图片失效,请留言反馈.部分素材来自网络,若不小心影响到您的利益,请联系博主删除. 资料链接:https://pan.baidu.com/s/1189u6u4icQYHg_9_7ovWmA( ...
最新文章
- linux下必看的60个命令
- 如何获取真实的执行计划
- 前端传数据到后台部分接收成功,部分接收失败
- 1-1:网络初识之了解什么是协议以及TCP/IP协议
- Java基础---File类,就是这么简单
- 用VBA下载google图片
- 9860计算机测量程序,卡西欧9860测量放样程序-绘星
- 目标检测中region proposal的作用?
- 输入一串字符串 字符串长度不超过100
- spring cloud gateway filters学习
- 计算机网络教室财产登记表,固定资产清查登记表-资产管理.DOC
- 一副好的平面设计作品,来自优秀的字体
- 传奇世界最好的版本:
- 接上一篇的正点原子战舰读取sd卡文本文件的主程序。
- js格式化时间(YYYY-MM-DD)
- 矿产行业智能采购管理系统开发,采购平台提升矿企核心竞争力
- 腾讯游戏助手运行闪退日志查看
- echarts saveAsImage提示字显示不全
- 基于SpringBoot实现文件上传功能(前端使用postman检查request)
- 友情链接作用与方法详解