1
icql 2023-07-08 12:38:22 +08:00
看场景为啥不考虑直接用 bitmap 呢,zset 这场景看着不大合适
|
2
zpfhbyx 2023-07-08 13:03:24 +08:00
在加个 bitmap 就好了. 反正都是个粗略的数字或者单独维护一个 key 来进行统计, 用 lua 脚本 zadd 或者 zdel 的时候 对这个 key 进行加或者减 .
|
3
skyemin 2023-07-08 13:06:30 +08:00
一个 zset 里存储百万用户有可能变成 bigkey,分片存储又增加了聚合查询的成本,建议一个 key 一个 bitmap,更省空间,同时也满足用户是否订阅该活动的状态查询
|
5
ben548 OP @icql 而且 bitmap 如果存用户的 uid 的话,uid 是雪花算法生成的的 32 位的数字,用 bitmap 其实非常占内存,本质上用 bitmap 基本上就是为了省内存,不过感觉这种场景下也完全没有节省到内存,甚至比用 zset 占用更多
|
6
fkdtz 2023-07-08 14:41:38 +08:00
这是一个典型的大 key 热 key 场景,不管是否存在推送慢的情况,可能分片都是应该做的。
楼主的思路我感觉没啥问题,成本也是最低的。 至于考虑到订阅计数器的单独维护问题,我觉得这点成本是应该的,毕竟你分片之后对于热门活动不可能在线上实时 zcount 1024 个分片吧,那也太慢了。 尽量保持线上业务快速响应,很多活可以异步处理,比如这个计数器就可以异步执行,不需要实时增加,不影响线上业务响应。 实际上我理解最好是特殊情况特殊处理,不需要一视同仁给所有活动都分片,可以动态地给大 key 做分片,不过一旦涉及到动态就会引入更多复杂的逻辑例如 rehash 或是引入哈希环等等,展开来就有更多东西可以讨论了,这个场景下有点舍本逐末就算了吧。 另外我觉得这个场景用 bitmap 不太合适,用户量级在百万级,那么单个 bitmap 的大小至少要上 M ,也算是大 key 了,而且很多绝大部分的活动都是冷门的,意味着 bitmap 中绝大部分都是非常稀疏的,这么搞不太划算。 我认知里 bitmap 更适合全体用户都参与的场景,例如是否活跃、是否在线等等吧。 一些临时的想法可能有不太合适的地方,可以一起讨论 |
7
ben123321 2023-07-08 17:13:43 +08:00
随便解答下,看看是否能满足条件:
1. 增加一个大活动的 list ,用于存储哪些活动是大活动,只有进入了该 list ,才会走分片逻辑。这样其实已经保证了只有「非常小」一部分的活动需要做分片。 2. 针对大活动的 list ,维护一个 count key 。 3. 把大活动 list 推到 local cache 中,让判断损耗下降为 0 。 4. 如何从小活动转换成大活动?异步任务写分片数据,然后再加入到大 list 中。 5. 大活动如何变成小活动?不支持,因为这个概率实在太小。 以上。 |
8
dusu 2023-07-08 18:05:07 +08:00 via iPhone
1. bitmap 也可以分片的
每片 id 从 1 开始 分成若干个 bitmap 拿出来的时候算下偏移就能拿到最终 id 分片越多越省内存 但是 key 不好维护 但是至少能解决内存太大问题 2. 冷数据过期后从内存里剔除 直接数据库里查归档结果就行了 当数据穿透超过阈值就回 redis |
9
dusu 2023-07-08 18:06:30 +08:00 via iPhone
@dusu redis 的 bitmap 可以 dump 出来自己解析的
那个执行性能应该可以满足你要快速 scan 的效果 |
10
xuanbg 2023-07-08 18:13:51 +08:00
没明白活动为什么要用 zset ?
|