摘要:类似统计最近天连续登陆的人的个数这类场景就可以使用来实现。对于的操作要注意,各个操作的时间复杂度,如果是则都是,等都是,在比较大的时候要注意,可能是潜在的慢查询
序
本文主要研究一下redis的bitset数据结构的用场
相关命令 SETBIT时间复杂度为O(1)
setbit login.20180906 102400000 0 setbit login.20180905 201400000 1GETBIT
时间复杂度为O(1)
getbit login.20180905 201400000BITOP
时间复杂度为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,-1BITCOUNT
时间复杂度为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 Rangepublic 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比较大的时候要注意,可能是潜在的慢查询
docsetbit
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
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/36825.html
摘要:应用之分布式会话的实战的实战的实战实战版本之购物车服务实战版本之投票服务聊聊在中的数据结构 序 本文主要研究一下redis的数据结构的应用 string 最常用的就是incr操作,比如可以用来维护用户在某个抽奖活动的剩余抽奖次数 setnx方法可以用来实现分布式锁 hashmap 可以用来存储session,作为分布式session的一个实现方案 可以用来存储用户购物车,valu...
摘要:前言该文章将通过一个小将讲述中的类型命令。直接根据功能方面进行讲述,穿插命令操作说明。就是对应的命令了,相关联的还有和。需要注意的是在版本提供了参数用于取代和,后续版本可能会移除和命令。通过每天的记录来统计用户连续上线的情况。 前言 该文章将通过一个小demo将讲述Redis中的string类型命令。demo将以springboot为后台框架快速开发,iview前端框架进行简单的页面设...
摘要:对于小或,不缓存。这样下次如果在有这个条件过来的时候,就不用重新扫描倒排索引,反复生成,可以大幅度提升性能。比好的原因除了不计算相关度分数以外还有这个。 下面详细讲一下为什么filter的性能很高,filter的底层原理究竟是什么? 通过一个搜索的场景来深入剖析一下,当一个filter搜索请求打到Elasticsearch的时候,ES会进行下面的操作: (1)在倒排索引中查找搜索串,获...
摘要:前言布隆过滤器是年由布隆提出的。布隆过滤器可以用于检索一个元素是否在一个集合中。而在中有个位向量,我们可以基于实现一个简单实用的布隆过滤器。实现代码布隆过滤器将元素加入到过滤器为时,索引为判断元素是否在过滤器中为存在,为不存在为时,索引为 前言 布隆过滤器(Bloom Filter)是1970年由布隆提出的。它实际上是一个很长的二进制向量和一系列随机映射函数。 布隆过滤器可以用于检索一...
阅读 2437·2023-04-25 15:22
阅读 2703·2021-11-22 09:34
阅读 2664·2021-10-11 10:58
阅读 851·2021-08-30 09:48
阅读 1626·2019-08-30 15:56
阅读 1584·2019-08-30 15:53
阅读 965·2019-08-29 11:16
阅读 913·2019-08-23 18:34