算法实战(一):剖析Redis常用数据类型对应的数据结构

算法实战(一):剖析Redis常用数据类型对应的数据结构

数据库Redis中的常用数据类型,底层都是哪种数据结构实现的?

Redis数据库介绍

Redis是一种键值(Key-Value)数据库,非关系型数据库,相对于关系型数据库比如MySQL,MySQL表的结构比较复杂,包含很多字段,可以通过SQL语句,实现非常复杂度查询需求,Redis中只包含“键”“值”两部分,且只能通过键来查询值,所以Redis的读写效率非常高

Redis主要是作为内存数据库使用,即数据是存储在内存中,也支持将数据存储在硬盘中

Redis中,键的数据类型是字符串,为了丰富数据存储的方式,值的数据类型很多,字符串、列表、字典、集合、有序集合

列表list

列表支持存储一组数据,列表对应两种实现方法,一种是压缩列表ziplist,另一种是双向循环链表

当列表中存储的数据量少的时候,采用压缩列表的方式,但是需要同时满足两个条件: 列表中保存的单个数据小于64字节,列表中数据个数少于512个。压缩列表是Redis自己设计的一种数据存储结构,类似数组,通过一片连续的内存空间来存储数据,允许存储的数据大小不同。压缩列表节省内存,又支持不同类型数据的存储,而且因为数据存储在一片连续的内存空间,通过键来获取值为列表类型的数据效率很高

当列表中存储的数据量比较大的时候,需要通过双向循环链表来实现,额外定义一个list结构体来组织链表的首、尾指针,还有长度等信息

typedef struct listnode{
	struct listNode *prev;
	struct listNode *next;
	void *value;
}listNode;

typedef struct list{
	listNode *head;
	listNode *tail;
	unsigned long len;
	//……
}list;

字典(hash)

字典类型用来存储一组数据对,每个数据对又包含键值两部分,字典类型也有两种实现方式,一是压缩列表二是散列表。

当存储的数据量比较小的时候Redis才使用压缩列表来实现字典类型,同时需要满足两个条件:一是字典中保存的键和值的大小都小于64字节,二是字典中键值对的个数要小于512个,否则就要使用散列表来实现字典类型,Redis使用MurmurHash2哈希算法作为哈希函数,对于哈希冲突问题,Redis使用链表法来解决,还支持散列表的动态扩容、缩容

当数据动态增加之后,散列表的装载因子会增大,当装载因子大于1的时候,Redis会触发扩容,将散列表扩大为原来大小的2倍,数据减少之后,装载因子小于0.1的时候,Redis会触发缩容,缩小为字典中数据个数的2倍大小。使用渐进式扩容缩容策略,将数据的搬移分批进行,避免大量数据一次性搬移导致的服务停顿

集合(set)

用来存储一组不重复的数据,数据类型有两种实现方法,一是基于有序数组,二是基于散列表,当要存储的数据同时满足下面两个条件的时候,Redis就采用有序数组来实现集合数据类型,否则Redis就使用散列表来存储集合中的数据

  • 存储的数据都是整数
  • 存储的数据元素个数不超过512个

有序集合sortedset

有序集合用来存储一组数据,并且每个数据会附带一个得分,通过得分的大小将数据组织成跳表,以支持快速按照得分值、得分区间获取数据

当数据量较小的时候,Redis会用压缩列表来实现有序集合,使用压缩列表来实现有序集合的前提有

  • 所有数据大小小于64字节
  • 元素个数小于128个

数据结构持久化

Redis被当做内存数据库,但也支持数据落盘,即将内存中数据存储到硬盘中,如果断电的时候,数据也不会丢失,重启之后,Redis只需要再将存储在硬盘中的数据重新读取到内存就可以继续工作,Redis的数据格式由“键”和“值”两部分组成,而值支持很多数据类型,比如字符串、列表、集合、有序集合。像字典、集合等类型,底层用到散列表,散列表中有指针的概念,指针指向的是内存中的存储地址,Redis如何将一个跟具体内存地址有关的数据结构存储到磁盘中?

叫做数据结构的持久化问题,或者对象的持久化问题,持久化=存储到磁盘

如何将数据结构持久化磁盘?

一是清除原有的存储结构,只将数据存储到磁盘中,当我们需要从磁盘还原数据到内存的时候,再重新将数据组织成原来的数据结构,Redis采用的就是这种思路,但是数据从硬盘还原到内存的过程,耗用比较多的时间

二是保留原来的存储格式,将数据按照原有的格式存储在磁盘中。我们可以将散列表的大小、每个数据被散列到的槽的编号等信息,都保存在磁盘中,有了这些信息可以避免重新计算哈希值

发布了75 篇原创文章 · 获赞 9 · 访问量 9163

猜你喜欢

转载自blog.csdn.net/ywangjiyl/article/details/104893053