Redis中Set底层跟Java一样吗?
Redis 几种常见的数据类型底层原理,前面跟小伙伴们已经扒了 String 和 List 了,今天我们再来看看 Set。
一 Java 里的 Set
从体验上来说,Redis 里边的 Set 有点像 Java 里的 Set,使用感觉差不多也是这个样子。
都是唯一,都是无序。
不过小伙伴们知道,我们 Java 里边的 Set,几种不同类型的 Set 底层都不约而同的指向了 Map。
HashSet
- 底层使用的是
HashMap
(实际上是一个专门的IdentityHashMap
),其中元素作为 key,对应的 value 通常是一个固定的对象(例如,PRESENT
对象),以此来实现元素的去重。 HashSet
提供了非常快的插入、删除和查找操作,平均时间复杂度为 O(1),但不保证元素的顺序。
- 底层使用的是
TreeSet
- 底层使用的是
TreeMap
,它是一个红黑树实现的有序映射。TreeSet
中的元素会被排序,排序依据可以是自然顺序(通过实现Comparable
接口),也可以是用户提供的Comparator
。 TreeSet
保证了元素的排序,同时也提供了有序集合的操作,如headSet()
,tailSet()
,subSet()
等,时间复杂度通常为O(logn)。
- 底层使用的是
LinkedHashSet
- 底层使用的是
LinkedHashMap
,它结合了HashMap
的快速查找特性和LinkedHashMap
的有序性。 LinkedHashSet
维护了元素的插入顺序,同时提供了快速的插入、删除和查找操作。时间复杂度通常为O(1)。
- 底层使用的是
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)~