原创网站设计,举报网站建设情况总结,网络优化大师app,建筑工程网站搭建目录
引言
Zset 集合命令
ZINTERSTORE
ZUNIONSTORE
Zset 编码方式
Zset 应用场景
排行榜系统 引言 在 Redis 中集合间操作无非就是 交集、并集、差集 Set 类型与之相对应的操作命令为 sinter、sunion、sdiff 注意#xff1a; 从 Redis 6.2 版本开始#xff0c;Zset 命…目录
引言
Zset 集合命令
ZINTERSTORE
ZUNIONSTORE
Zset 编码方式
Zset 应用场景
排行榜系统 引言 在 Redis 中集合间操作无非就是 交集、并集、差集 Set 类型与之相对应的操作命令为 sinter、sunion、sdiff 注意 从 Redis 6.2 版本开始Zset 命令才开始支持 zinter、zunion、zdiff 这几个命令但是此处我们使用的是 Redis 5 版本所以下文不涉及介绍这三个命令 Zset 集合命令 ZINTERSTORE 用于求出给定有序集合中元素的交集并将其保存进目标有序集合中合并过程中以元素为单位进行合并元素对应的分数按照不同的聚合方式和权重得到新的分数 语法 zinterstore destination numkeys key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE sum | min | max] destination表示要把结果存储到哪个 key 对应的 zset 中numkeys描述了后续有几个 key 参与交集运算因此该变量需为整型weight可理解为 权重此处指定的权重相当于一个系数会乘以当前的分数aggregate指定 当前给定的有序集合 应采用哪种聚合方式来得出新的分数 注意 前面介绍的命令也是支持多个 key 的如mget、mset 等但这些命令却不涉及到类似于此处的设定即需手动指出 key 的个数 官方文档解释 主要是为了避免 zinterstore 命令的 选项 和 keys 弄混淆即通过 numkeys 描述出 key 的个数后便可明确知道后面的 选项 是从哪里开始的 总结 正因为 mget、mset 等命令在指定 keys 后无复杂的选项所以无需采用 numkeys 来手动指出 key 的个数以便知道 key 和 选项 之间的分界处 时间复杂度 O(N) O(M * logM)N 为 所有输入命令中总的 有序集合 元素个数M 为 结果集 的元素个数 实例理解 此处我们可以指定 权重 我们还可以指定 聚合方式 ZUNIONSTORE 用于求出给定有序集合的并集并将其保存到目标有序集合中合并过程中以元素为单位进行合并元素对应的分数按照不同的聚合方式和权重得到新的分数 语法 zunionstore destination numkeys key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE sum | min | max] zunionstore 和 zinterstore 命令的用法大致相同 时间复杂度 O(N) O(M * logM)N 为 所有输入命令中总的 有序集合 元素个数M 为 结果集 的元素个数 实例理解 此处我们可以指定 权重 我们还可以指定 聚合方式 Zset 编码方式 有序集合的内部编码有 两种 ziplist压缩列表skiplist跳表 注意点一 如果有序集合中的元素个数较少或者单个元素体积较小时使用 ziplist 来存储以达到 节省空间 的效果 注意点二 如果有序集合中的元素个数较多或者单个元素体积非常大时使用 skiplist 来存储 两个配置项 zset-max-ziplist-entries单位为元素个数zset-max-ziplist-value单位为字节 当有序集合的元素个数小于 1号配置项当每个元素的值都小于 2号配置项时Redis 会使用 ziplist 来作为有序集合的内部编码 关于跳表 简单来说跳表是一个 复杂链表其查询元素的时间复杂度为 O(logN)相比于树形结构更适合按照范围获取元素B 树 Zset 应用场景 排行榜系统 微博热搜、游戏天梯排行、成绩排行等 关键要点 用来排行的分数为实时变化的虽然是实时变化的却也能够高效的更新排行 重点理解 有序集合zset 能很好的满足上述需求和关键要点 实例理解 比如游戏天梯排行只需要将 玩家信息和该玩家所对应的分数给放到有序集合中即可从而便能 自动就形成一个排行榜我们也能 随时按照排行下标、按照分数 来进行范围查询随着分数发生改变也可以比较方便的使用 zincrby 命令来修改分数且排行榜顺序也能自动进行调整该操作的时间复杂度为 O(logN) 问题 游戏玩家这么多此时都用这个 zset 来存内存能否存下 举例 假设此时我们有 1亿 个玩家约定 userId 4个字节score 8个字节即一个玩家需要 12 个字节来表示12亿 字节 —— 1.2 GB对于当今计算机来说绰绰有余 实例理解二 相较于游戏排行榜其排序依据很容易确定仅需根据玩家积分即可微博的排行榜其排序依据评估起来更为复杂因为 微博热度是一个综合数值其参考方面包含 浏览量、点赞量、转发量、评论量等上述各方面具有不同 权重 weight进而计算得到综合数值热度 重点理解 此时可以借助 zinterstore / zunionstore 命令按照加权方式进行处理可以把上述每个维度的数值均放到一个有序集合中member 为 微博的idscore 为各自维度的数值通过 zinterstore / zunionstore 命令将上述有序集合按照约定好的权重进行集合间运算即可最终得到结果集合其分数便为热度且 排行榜也顺带着出来了 总结 上述应用场景Redis 中的 zset 是一个选择但不是说非得用 Reids 中的 zset 不可有些场景下确实可以使用到有序集合但又不方便使用 Redis 时可以考虑使用其他方式的有序集合