数据结构:快速的Redis有哪些慢操作

127 阅读3分钟

redis的数据结构

string、list(列表)、hash(哈希)、set(集合)、sorted set(有序集合)、bitmap、geo

image.png

键和值用什么结构组织

redis使用一个哈希表来保存所有键值对。

一个哈希表,其实就是一个数组,数组的每个元素称为一个哈希桶。所以,我们常说哈希表是由多个哈希桶组成的,每个哈希桶中保存了键值对数据。

哈希桶中的元素保存的并不是值本身,而是指向具体值得指针。不管值是string,还是集合类型,哈希桶中的元素都是指向他得到的指针。

为什么哈希表操作变慢了?

哈希冲突:两个key的哈希值和哈希桶计算对应关系时,正好落在同一个哈希桶中。

解决哈希冲突的方式,就是链式哈希。链式哈希也很容易理解,就是指同一个hash中的多个元素用一个链表来保存,它们之间一次用指针链接。

Redis的渐进式rehash

集合数据操作效率

和string类型不同,一个集合类型的值,第一步是通过全局哈希表找到对应的哈希桶位置,第二部是在集合中在增删改查。

有哪些底层数据结构

压缩列表

压缩列表实际上类似于一个数组,数组中的每个元素都应保存一个数据,和数组不同的是,压缩列表在表头有三个字段 zlbytes、zltail和zllen,分别表示列表长度,列表尾部的偏移量和列表中的entry个数;压缩列表在表尾还有一个zlend,表示列表结束。

image.png

跳表

跳表在链表的基础上,增加了多级索引,通过索引的几个跳转,实现数据的快速定位。

image.png

不同操作的复杂度

四字口诀 单元素操作是基础

范围操作非常耗时

统计操作通常高效

例外情况只有几个

第一:单元素操作,是指每一种集合类型对单个数据实现的增删改查操作

第二: 范围操作,是指集合类型中遍历操作,可以返回集合中的所有数据。 比如hash类型的HGETALL和set类型的SMEMBERS,或者返回一个范围内的部分数据,比如list类型的Lrange和zset类型的zrange。这类操作的复杂度一般是o(n)比较耗时,我们应该尽量避免。

不过redis从2.8版本开始提供scan系统操作(比如HSCAN、SSCAN和ZSCAN),这类操作实现了渐进式遍历,每次只返回有限数量的数据。

第三:统计操作,是指集合类型对集合中所有元素个数的记录

第四:例外情况,是指某些数据结构的特殊记录,例如压缩列表和双向链表都会记录表头和表尾的偏移量。