本文已参与「新人创作礼」活动,一起开启掘金创作之路。
五大基本数据类型
| keys | 查看当前库所有key (匹配:keys *1) |
|---|---|
| exists key | 判断某个key是否存在 |
| type key | 查看你的key是什么类型 |
| del key | 删除指定的key数据 |
| unlink key | 根据value选择非阻塞删除(仅将keys从keyspace元数据中删除,真正的删除会在后续异步操作) |
| expire key 10 | 10秒钟:为给定的key设置过期时间 |
| ttl key | 查看还有多少秒过期,-1表示永不过期,-2表示已过期 |
全局哈希表
为了实现从键到值的快速访问,Redis 使用了一个哈希表来保存所有键值对。
这个哈希表保存了所有的键值对,所以,我也把它称为全局哈希表。哈希表的最大好处很明显,就是让我们可以用 O(1) 的时间复杂度来快速查找到键值对。
当发送哈希冲突时,Redis采用链式哈希,所以当数据过量时,Redis的速率也会下降。
所以,当链式冲突严重时,Redis 会对哈希表做 rehash 操作。rehash 也就是增加现有的哈希桶数量,让逐渐增多的 entry 元素能在更多的桶之间分散保存,减少单个桶中的元素数量,从而减少单个桶中的冲突。
Rehash操作
就是Redis会采用两个全局hash表,当第一个满了,就copy到第二个,此时第二个会初始化成第一个的两倍大小。
这其中会涉及大量的数据拷贝,如果一次性迁移,会造成 Redis 线程阻塞,怎么办呢?
Redis采用了渐进式rehash。
渐进式rehash: 简单来说就是每处理一个请求,会逐步拷贝一个位置上的索引。
集合数据操作效率
Redis高效的存储与底层数据结构强相关,而String(字符串)、List(列表)、Hash(哈希)、Set(集合)和 Sorted Set(有序集合)的底层实现又不相同。
除去 String 类型,另外四种集合的值,第一步是通过全局哈希表找到对应的哈希桶位置,第二步是在集合中再增删改查。
底层数据结构一共有 6 种,分别是简单动态字符串、双向链表、压缩列表、哈希表、跳表和整数数组
底层实现:
- 记住每个数据类型其底层实现,可以更好的使用在合适的场景。
压缩列表
压缩列表实际上类似于一个数组,和数组不同的是,压缩列表在表头有三个字段 zlbytes、zltail 和 zllen,分别表示列表长度、列表尾的偏移量和列表中的 entry 个数;压缩列表在表尾还有一个 zlend,表示列表结束。
- 与数组的区别仅仅是,压缩列表可以更快定位最后一个元素
- 查找数组中其他元素的复杂度是 O(N)
跳表
跳表在链表的基础上,增加了多级索引,通过索引位置的几个跳转,实现数据的快速定位。
跳表使用的前提是有序。
就是每N个数据建立一个索引,这些索引还可以互相嵌套。
- 跳表的查找复杂度是 O(logN)。