(3)Redis zset原理
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了(3)Redis zset原理相关的知识,希望对你有一定的参考价值。
参考技术A Sorted Set,和set相比,增加权重参数score(浮点数)有序排列。Redis唯一可 根据成员访问 ,又可以 根据分值排序 ,访问元素结构。场景:在线用户列表,各种礼物排行榜 ,弹幕消息(可以理解为 按消息维度的消息排行榜 )等信息,适合使用Redis中的SortedSet结构进行存储。
概要:原理(ziplist,skiplist,例子,操作)、 红黑树比较、 score相同,怎么排序
底层ziplist 或 HashMap和跳跃表(SkipList) 有序集合
元素数 <128个 ,所有成员长度 <64字节 。都可通过zset-max-ziplist-entries和zset-max-ziplist-value来修改。
紧凑 压缩 列表节点 来保存,第一个节点存 member ,第二个存score, 按score从小到大排序
底层是 zset(1字典,跳跃表) 和一个。
1) HashMap: 放 成员 到 score映射 O(1) ,共享相同元素member和score,因此不会浪费额外的内存
2) 跳跃表: 放所有成员,依据HashMap的score,查找效率高,链表增加跳跃功能,O(logN)
插入或查找:O(1)获得节点分值,遍历跳跃表,根据分值到合适位置
新链表,包含原来一半,沿新查。 遇大节点,回原查。 7比较,19比较,比26小,回原链),比22要大,23比26小,23不存在
再增加,第三层链表: 查快 。 插/删重新进行调整,退化O(n)。
解决办法: 不要求 上下 相邻 链表间,节点个数 严格对应 ,如,一个节点随机出 层数3 ,那么就把它链入到第1层到第3层这三层链表中。
插入, 不影响 其它节点 层数 。只 修改 插入节点 前后指针 ,降低插入复杂度。 插入性能 明显优于 平衡树
查: 若干层稀疏链表,先查高层, 逐层降低 ,最终降到第1层。跳一些节点,加快速度。实际 按key(score)排序
基本操作
1、 内存: 占更 小 ,更新 更节约、更灵活
2、ZRANGE或ZREVRANGE操作,跳表作为链表 遍历 ,和平衡树一样
3、简单: 易于实现,调试。
4、插入/删除,不需调整很多
(1)AVL 树 查询效率 严格 O(logN) ,插入需 多次旋转 ,导致插入 效率较低 ,才有更实用 红黑树 。
(2)红黑树 并发环境不方便, 更新 数据时, Skip更新较少,锁的也少 ,而红黑树有 平衡的过程 (涉及到较多节点), 锁住更多节点,降低并发性 。
(3)SkipList 优势 实现简单 ,红黑树2天,SkipList2个小时实现。
用字典排序,“ABCDEFG”,首字母相同,比较后面的
https://www.jianshu.com/p/cc379427ef9d
https://blog.csdn.net/liyuxing6639801/article/details/105252293
Redis之Zset
一、Redis之Zset简介
1. 有序集合Zset是String类型的有序集合。
2. Zset中每个元素都会关联一个double类型的分数值,redis通过分数值来为集合中所有成员进行从小到大排序。
3. Zset的成员是唯一的,但分数值可以重复。
4. Zset是通过hash表实现的,添加、删除、查找的复杂度都是O(1)。
5. Zset最大的成员数量为232-1(40多亿)个。
二、Redis之Zset命令行操作
Zadd:将一个或多个成员元素及其分数值加入到有序集当中。如果某个成员已经是有序集的成员,则更新这个成员的分数值,并通过重新插入这个成员元素,来保证该成员在正确的位置上。分数值可以是整数值或双精度浮点数。
Zrange:返回有序集中指定区间内的成员。成员按分数值递增排序,分数值相同的则按字典序来排序。查看Zset所有成员:zrange zset_name 0 -1。
Zrevrange:返回有序集中指定区间内的成员。成员按分数值递减排序,分数值相同的则按字典序的逆序来排序。
Zrangebyscore:返回有序集中指定分数区间的成员列表,按分数值递增排序,分数值相同的则按字典序来排序。默认使用闭区间。
Zrevrangebyscore:返回有序集中指定分数区间的成员列表,按分数值递减排序,分数值相同的则按字典序的逆序来排序。注意,区间表示的时候大值在前,小值在后,默认使用闭区间。
-inf表示负无限,+inf表示正无限。
Zrangebylex:通过字典区间返回有序集的成员列表。注意,只有有序集合中所有成员的分数值都相同的时候才会根据成员的字典序来排序,否则该命令返回的结果将是不可预知的。参数必须指明是开区间还是闭区间。+表示正无限,-表示负无限。
Zscan:迭代有序集合中的元素。
Zcard:返回指定有序集的元素数量。
Zcount:返回有序集中指定分数区间的成员数量。
Zlexcount:返回有序集中指定字典区间的成员数量。必须指定区间是开区间还是闭区间。
Zscore:返回有序集中指定成员的分数值。
Zrank:返回有序集中指定成员的排名,按分数值递增排序。分数值最小者排名为0。
Zrevrank:返回有序集中指定成员的排名,按分数值递减排序。分数值最大者排名为0。
Zrem:移除有序集中的一个或多个成员,忽略不存在的成员。
Zremrangebylex:移除有序集中指定字典区间的所有成员。注意,只有有序集合中所有成员的分数值都相同的时候才会根据成员的字典序来排序,否则该命令操作的结果将是不可预知的。
Zremrangebyrank:移除有序集中指定排名区间的所有成员。
Zremrangebyscore:移除有序集中指定分数值区间的所有成员。
Zincrby:对有序集中指定成员的分数值增加指定增量值。若为负数则做减法,若有序集不存在则先创建,若有序集中没有对应成员则先添加,最后再操作。
下面对交集和并集的计算将使用以下两个有序集合进行示例:
Zinterstore:计算给定一个或多个有序集的交集,并将其存储到一个目的有序集中。默认情况下。
Zunionstore:计算给定一个或多个有序集的并集,并将其存储到一个目的有序集中。
结果集中某个成员的分数值是所有给定集下该成员分数值之和。
以上是关于(3)Redis zset原理的主要内容,如果未能解决你的问题,请参考以下文章