Redis有序集合原理

简介

有序集合是一个数据类型和集合和hash表很相似,数据是不重复的。由于集合中的元素是没有排序的,因此有序集合中的每个元素都和一个浮点型数字关联起来,这个浮点型数字叫做score(所以它和hash很像)。
有序集合内的元素是按照以下规则排序的。
① A和B是2个分数不同的元素。如果A的分数大于B的分数,那么A>B。
② 如果A和B分数相同,那么当A的字符串词典顺序比B的到时候,A>B(A和B的字符串不可能相等)。

有序集合实现

Redis有序集合中的元素的编码可以是 ziplist 或者 skiplist。ziplist和skiplist编码选择的标准在于Redis里的元素的数量以及元素成员的长度。当满足以下2个条件时,元素编码为ziplist:
① 有序集合保存的元素数量小于128个
② 有序集合保存的所有元素成员的长度小于64字节

同时当条件不满足的时候,ziplist可以向skiplist转换。

以下将具体介绍ziplist和skiplist编码的底层实现。
ziplist:
ziplist编码的有序集合对象使用压缩列表作为底层实现。每个集合使用2个紧挨在一起的压缩列表节点来保存,第一个保存元素的成员,第二个保存元素的分值。压缩列表内的集合按分值从小到大排序,分值较小的元素被放置在靠近表头的位置,分值较大的元素在靠近表尾的位置。

skiplist:
skiplist编码的有序集合对象使用 zset结构作为底层实现,zset结构同时包含一个字典和一个跳跃表。
zset结构的zsl跳跃表按分值从小到大保存了所有集合元素,每个跳跃表都保存了一个集合元素:跳跃表节点的object属性保存了元素的成员,而跳跃表节点的score属性保存了元素的分值。
从了zsl, zset里还保存了一个从成员到分值的映射。

思考

1 为什么有序集合需要同时使用跳跃表和字典来实现?
跳跃表利于执行范围操作(跳跃表是排好序的),而字典有利于执行分值查找操作。同时由于Redis里的跳跃表和字典元素很多都是用指针实现的,所以不会浪费内存。

2 压缩列表和跳跃表之间的区别?
压缩列表是Redis为了节约内存而开发的。是由一系列特殊编码的连续内存块组成的顺序型存储结构。当一个列表键只包含少量列表项,并且每个列表项要么是小整数值,要么是长度比较小的字符串,Redis就会用压缩列表作为其底层实现。
跳跃表是一种有序数据结构。它通过在每个节点中维持多个指向其它节点的指针,从而达到快速访问节点的目的。

参考文档:
redis官方文档
《redis设计与实现》

    原文作者:biggirl
    原文地址: https://segmentfault.com/a/1190000014842718
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞