暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

​Redis中的ZSet实际使用场景以及原理浅析

Java壹码平川 2021-08-23
1131

ZSet

常用操作命令:

  • ZADD 添加元素,并设置分值 ZADD key [NX|XX] [CH] [INCR] score member [score member ...]
    元素添加进去之后是升序排列的。score用于标识元素的摆放位置,越小越靠左,score相同则按照字符顺序排序。

  • ZRANGE:升序列举元素;ZRANGE key start stop [WITHSCORES]

ZADD testsort 4 zhangsan 1 lisi 2 zhaoliu
(integer) 3
# 列举元素(不显示分数)
ZRANGE testsort 0 -1
1) "lisi"
2) "zhaoliu"
3) "zhangsan"
# 列举元素,并附带分值一起查询出来
ZRANGE testsort 0 -1 withscores
1) "lisi"
2) "1"
3) "zhaoliu"
4) "2"
5) "zhangsan"
6) "4"
# 测试相同的分值
zadd num 1  1  1 2  1 0 1 3 1 9 1 4
ZRANGE num 0 -1
1) "0"
2) "1"
3) "2"
4) "3"
5) "4"
6) "9"


  • ZREVRANGE :降序列举元素 ZREVRANGE key start stop [WITHSCORES]
# 降序列举
ZREVRANGE testsort 0 -1 withscores

  • ZCOUNT:获取满足范围的数据个数 ZCOUNT key min max

  • BZPOPMAX:阻塞式去除一个分数最高的。BZPOPMAX key [key ...] timeout

ZSet使用场景:

  • 歌曲排行榜:歌曲的热度选取播放量维度排序,一首歌曲播放之后对播放量incrc操作。
  • 阻塞队列:高校录取填报了志愿的学生,分数从高往低取出,然后做一系列的资质分析,该生在高中阶段是不是有爬围墙外出上网的前科...【手动狗头】。

ZSet排序是怎么实现的?

Skip List(跳表)

假如就按照单链表存放属性有序的元素,最坏的结果得遍历一次整个链表,复杂度为O(N)。 

那么怎么优化?MySQL是通过索引加速,这么一想是不是会有异曲同工的解决方案?

通俗地研究一把跳表是个什么东西:为了加快链表索引速度,那么最先能想到的办法就是二分。怎么个二分法?跳跃性地有序维护!


此时,我们假设要查找节点8,我们可以先在索引层遍历,当遍历到索引层中值为 7 的结点时,发现下一个节点是9,那么要查找的节点8肯定就在这两个节点之间。我们下降到链表层继续遍历就找到了8这个节点。原先我们在单链表中找到8这个节点要遍历8个节点,而现在有了一级索引后只需要遍历五个节点。


下期规划:

Redis中的消息订阅以及pipeline,敬请期待。

文章转载自Java壹码平川,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论