Redis数据结构(二)-List、Hash、Set及Sorted Set的结构实现

大神们在线求帮请说下,Redis数据结构(二)-List、Hash、Set及Sorted Set的结构实现
最新回答
夏日梧桐雨

2025-02-25 09:34:53

List类型通常被用作异步消息队列、文章列表查询等;存储有序可重复数据或作为简单的消息推送机制时,可以使用Redis的List类型。这类数据的存储通常会使用链表或者数组作为存储结构。如果能够将链表和数组的特点结合起来,就能够很好地处理List类型的数据存储。


Redis在早期使用了ZipList作为List类型的存储结构。ZipList是一个连续的内存块,由表头、若干个entry节点和压缩列表尾部标识符zlend组成。通过一系列编码规则,提高了内存的利用率,适用于存储整数和短字符串。每次增加和删除数据时,所有数据都在同一个ZipList中进行搬移操作。如果将一个组数据按阈值进行拆分出多个数据,就能保证每次只操作某一个ZipList。3.2之后,Redis开始使用QuickList作为更有效的List实现。


QuickList维护了一种宏观上的双端链表,每个节点为对ZipList的包装,即quicklistNode。每个quicklistNode都会通过前后指针相互指向,QuickList包含头、尾quicklistNode的指针。QuickList使用每个ziplist的最大容量、数据压缩范围和单个ziplist节点最大存储量来提升数据存取效率。通过设置这些参数,可以调整数据压缩的程度,以优化性能。例如,-5表示最大容量为64KB,适用于非正常工作负载;-4表示最大容量为32KB,不推荐;-3表示最大容量为16KB,可能不推荐;-2表示最大容量为8KB,较好;-1表示最大容量为4KB,较好。


Redis的链表实现具有以下特性:


1. 通过快速增加或减少节点,链表可以自动调整大小,以适应存储的数据量变化。
2. QuickList允许在链表的头部和尾部进行高效插入和删除操作。
3. 通过链表的结构,可以实现快速的数据访问,尤其是对于需要频繁访问数据的场景。


Hash


Hash数据结构在存储一个对象时,可以直接将该对象进行序列化后使用String类型存储,然后通过反序列化获取对象。对于只需要获取对象的某个属性的场景,可以将每个属性分别存储,但这样会导致Redis的dict中存在大量key,影响键的生命周期管理效率。使用Map结构可以将属性与值关联起来,减少存储空间,提高效率。


Redis的Hash数据结构也是使用dict实现的。当数据量较小或单个元素较小时,底层使用ZipList存储。配置如下:



  • ziplist元素个数超过512时,将改为hashtable编码。

  • 单个元素大小超过64字节时,将改为hashtable编码。


Set


Set类型适合用于对不重复集合的操作,可以判断元素是否存在于集合中。Set数据结构底层实现为value为null的dict,当数据可以使用整型表示时,Set集合将被编码为intset结构。整数集合是一个有序的、存储整型数据的结构,可以保存大范围的整型数据,并保证集合中不会有重复数据。


Sorted Set


Sorted Set是一种有序集合,连续空间存储数据,每次增加数据都会对全量数据进行搬运。对于有序链表查找指定元素,只能通过头、尾节点遍历方式进行查找。如果将每个数据增加不定层数的索引,索引之间相互关联,就可以通过遍历层级的索引来确定元素所处范围,减少空间复杂度。跳跃表是一种可以对有序链表进行近似二分查找的数据结构,Redis在两个地方使用了跳跃表,一个是实现有序集合,另一个是在集群节点中用作内部数据结构。


ZSet数据结构底层实现为字典(dict) + 跳跃表(skiplist)。跳跃表通过在每个节点中维持多个指向其他节点的指针,实现快速访问节点的目的。它支持平均O(logN)、最坏O(N)复杂度的节点查找,并且还可以通过顺序性操作来批量处理节点。数据量较少时,使用ziplist编码结构存储;数据量较多或有序集合中元素是较长字符串时,Redis使用跳跃表作为有序集合键的底层实现。


配置如下:



  • 元素个数超过128时,用skiplist编码。

  • 单个元素大小超过64字节时,用skiplist编码。


总结


Redis提供了多种数据结构,包括List、Hash、Set和Sorted Set。这些数据结构在不同的应用场景中具有独特的优点,能够高效地处理不同类型的数据操作。通过合理选择和配置存储结构,可以优化Redis的性能,满足各种业务场景的需求。


京东云开发者社区提供了丰富的学习资源和交流平台,欢迎开发者们积极参与学习和讨论,共同提升技术水平。更多关于Redis数据结构的知识和实践,可以参考相关文档和社区讨论。