在日常的开发中, redis的BitMap做过滤非常的方便, 但是存在一些坑, 所以记录下来, 给大家学习下:
1. Redis 的 bitmap 的key的长度会影响它的性能, 最大是2的32次方, 要是10位数就是10亿了, 必然比从0开始慢. 例如
bitmap set myBit 1 1, 必然会比bitmap set myBit 1000000 1 要快. 单个查询没啥影响, 但是查询的数量一旦大了性能差异就非常大了.
2. bitmap 在 redis 中按 string 来存储,因此上限是 512MB(2^32 bits).
setbit myBit 0 1
Setbit myBit 999999999 1
因此当我的第二个 setbit 值为 2^32-1=4294967295 时,由于 redis 没有采用压缩实现,就会直接申请到 512MB 内存空间来存储 2^32-1 bit 位置的值 1,中间的 bit 也会全填上 0.
而 guava 中 EWAHCompressedBitmap 是一种压缩的 bitmap 实现,将 64 bit 作为一个 word(一个 long 的长度),4个 word 作为一组,并在每一组的第一个 word 引入了 Running Length Word (携带跨度信息 word,类似路标)概念,其他三个 word 为 Literal Word(直接存储信息的 word)。在压缩 bitmap 实现下,本文的两个 setbit 操作就不会使 EWAHCompressedBitmap 内存占用暴涨,而是只会使用 2组 word,即 64 bytes.
不过即使通过压缩节省了空间,google 官方仍建议使用者从小到大来插入数据......
所以为了测试,给 redis bitmap 试了两个骚操作,结果证明 redis bitmap 没有用压缩结构实现.
这个问题解决方案:
https://blog.csdn.net/weixin_40721856/article/details/103112042
1、首先按天维护一个String值,就是将每天的最大id保存一下。我们叙述方便,将其记为 maxId。
2、每一天维护bitmap的时候,位置数值-昨天的maxid。
例如:昨天最大的id是10000,今天的id肯定是从10000以后开始的。
以我们要存储10005这个数值来计算,我们先拿到昨天的maxId(10000),然后用10005-10000 =5 来表示这个id,只需要将今天的bitmap的第五位设置成1就可以解决这个问题了。
3.使用命令 info memory ,查询redis的内存占用.
开始准备截图的, 后面又忘记截图了, 等以后再把截图补上.
宣布一件大事.
今天领了结婚照, 国家分配的对象已经到了, 已经建立了长期稳定的合作伙伴关系. 哈哈哈哈