Redis中Set底层跟Java一样吗?

Redis 几种常见的数据类型底层原理,前面跟小伙伴们已经扒了 String 和 List 了,今天我们再来看看 Set。

一 Java 里的 Set

从体验上来说,Redis 里边的 Set 有点像 Java 里的 Set,使用感觉差不多也是这个样子。

都是唯一,都是无序。

不过小伙伴们知道,我们 Java 里边的 Set,几种不同类型的 Set 底层都不约而同的指向了 Map。

  1. HashSet

    • 底层使用的是HashMap(实际上是一个专门的 IdentityHashMap),其中元素作为 key,对应的 value 通常是一个固定的对象(例如,PRESENT 对象),以此来实现元素的去重。
    • HashSet 提供了非常快的插入、删除和查找操作,平均时间复杂度为 O(1),但不保证元素的顺序。
  2. TreeSet

    • 底层使用的是 TreeMap,它是一个红黑树实现的有序映射。TreeSet 中的元素会被排序,排序依据可以是自然顺序(通过实现 Comparable 接口),也可以是用户提供的 Comparator
    • TreeSet 保证了元素的排序,同时也提供了有序集合的操作,如 headSet(), tailSet(), subSet() 等,时间复杂度通常为O(logn)。
  3. LinkedHashSet

    • 底层使用的是 LinkedHashMap,它结合了 HashMap 的快速查找特性和 LinkedHashMap 的有序性。
    • LinkedHashSet 维护了元素的插入顺序,同时提供了快速的插入、删除和查找操作。时间复杂度通常为O(1)。
  4. EnumSet

    • 专为枚举类型的元素设计,底层使用位向量(bit vector)来存储元素,非常适合枚举类型的集合,提供了非常高效的存储和操作。
    • EnumSet 在枚举类型元素的数量较少时非常高效,时间复杂度通常为O(1)。

当然这是 Java 里的,Redis 中和这个并不相同。

二 Redis 的 Set

Redis 中 Set 的底层要分情况来看。

整体上来说有两种:

  • intset
  • hashtable

具体使用哪种取决于集合中元素的数量和类型。

2.1 intset

当集合中的所有元素都是整数,并且集合的大小不超过 512 个元素时,Redis 会使用 intset 数据结构来存储集合。

intset 是一个无序的整数数组,它使用紧凑的方式存储整数元素,以节省内存。intset 的特点包括:

  • 使用紧凑的存储方式,每个整数根据其大小占用最少的字节数(1 字节、2 字节、4 字节或 8 字节)。
  • 支持快速的插入和删除操作。
  • 不保证元素的顺序。

这里的 512 是咋来的呢?这个参数我们可以在 redis.conf 中进行配置,不配置的话默认是 512:

来看个简单的例子。

所有元素都是整数,且元素个数不超过 512:

有元素不是整数:

可以看到,此时就是另外一种 hashtable 类型了。

具体到 intset 内部,又分为不同的编码格式。

  • int16:这个是每两个字节表示一个整数,两个字节就是 16 位,表示的整数范围就是 (-2^15)~(2^15-1)
  • int32:这个是每四个字节表示一个整数,四个字节就是 32 位,表示的整数范围就是 (-2^31)~(2^31-1)
  • int64:这个是每八个字节表示一个整数,八个字节就是 64 位,表示的整数范围就是 (-2^63)~(2^63-1)

如果一开始使用的是 int16,后来存储的数据大小超了,那么 Redis 会自动将编码格式升级为 int32,并且将旧数据复制过来。

不过需要注意的是,编码格式可以从 int16 升级为 int32,但是并不会从 int32 降级为 int16,即使数据已经变为 1 了。

2.2 hashtable

当集合中的元素不是整数或者集合的大小超过了 512 时,Redis 会使用 hashtable(散列表)来存储集合。hashtable 是一种散列表实现,它可以高效地存储任意类型的数据,并提供快速的查找操作。hashtable 的特点包括:

  • 支持任意类型的数据。
  • 提供快速的插入、查找和删除操作。
  • 不保证元素的顺序。

当集合的元素发生变化时,Redis 会自动转换数据结构以适应新的需求。例如,如果一个原本使用 intset 的集合添加了非整数元素,Redis 会将数据结构从 intset 转换为 hashtable

Redis 如此煞费苦心,其实就一个目的,高效率的使用内存。


松哥最近抽空剪了一套 Redis 视频,是我五月份刚刚录的,先来给大伙看看目录:

视频总共是 166 集大约 22.7 个小时左右。从 Redis 的基本用法到高级用法,Redis 实现各种分布式锁以及相关的原理、Redis 限流、持久化、事务、集群、常见使用场景等等都有非常详细的介绍,最后还整理了 28 道常见面试题供小伙伴们学习。视频教程有完整的代码案例和笔记,并且有微信答疑群~

当然,视频课程是付费的,¥499,老用户有 ¥30 优惠哦,老用户可以私我领取优惠券。

下单的小伙伴记得私我加 Redis 答疑群哦(备注 Redis)~