Redis 数据库介绍
Redis是一种键值(Key-Value)数据库。相对于关系型数据库(MySQL、Oracle),Redis也被叫做非关系型数据库。
Redis中只包含“键”和“值”两部分,只能通过“键”来查询“值”。存储结构简单,读写效率高。Redis主要作为内存数据库使用,数据存储在内存中,同时支持将数据存储在硬盘中。
Redis键的数据类型是字符串,值得数据类型包括字符串、列表、字典、集合、有序集合。
字符串(string)
对应数据结构的字符串。
列表(list)
列表数据类型支持存储一组数据,两种实现方法:压缩列表(ziplist)、双向循环链表。
- 压缩列表
列表中存储数据量比较小
列表中保存的单个数据(可以是字符串类型)小于64字节;
列表中数据个数小于512个。
压缩列表不是基础数据结构。类似数组,通过一片连续的内存空间来存储数据。允许存储的数据大小不同。但压缩列表不支持随笔访问,类似链表。
Redis一般通过key获取整个value的值—整个压缩列表的数据,并不需要随机访问。访问某个元素的时候需要从头开始遍历。压缩列表一方面比较节省内存,另一方面可以支持不同类型数据的存储。
双向循环链表
链表的一种。list-Redis1
2
3
4
5
6
7
8
9
10
11
12
13
14//额外定义了一个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)
字典类型用来存储一组数据对。每个数据对又包含键值两部分。两种实现方法:压缩列表、散列表。
- 压缩列表
存储的数据量比较小
- 字典中保存的键和值的大小都要小于64字节;
- 字典中键值对的个数要小于512个。
- 散列表
Redis使用MurmurHash2这种运行速度快、随机性好的哈希算法作为哈希函数。
Redis使用链表法解决哈希冲突问题。
Redis支持散列表的动态扩容(装载因子大于1,散列表扩大为原来的2倍左右)、缩容(装载因子小于0.1,缩小为字典中数据个数的大约2倍大小)。
采用渐进式扩容缩容策略,将数据的搬移分批进行,避免大量数据一次性搬移导致的服务停顿。
集合(set)
集合类型用来存储一组不重复的数据。两种实现方法:有序数组、散列表。
- 有序数组
- 存储的数据都是整数;
- 存储的数据元素个数不超过512个。
- 散列表
有序集合(sortedset)
有序集合用来存储一组数据。两种实现方式:压缩列表、跳表。
- 压缩列表
- 所有数据的大小都要小于64字节;
- 元素个数要小于128个。
- 跳表
每个数据会附带一个得分。通过得分的大小,将数据组织成跳表这样的数据结构,以支持快速的按照得分值、得分区间获取数据。
数据结构持久化(对象持久化)
Redis常被用作内存数据库,也支持数据落盘,将内存中的数据存储到磁盘中。
Redis的数据格式由“键”和“值”两部分组成。“值”支持很多数据类型。两种持久化思路:
清除原有的存储结构,只将数据存储到磁盘中。当需要从磁盘还原数据到内存的时候,再重新将数据组织成原来的数据结构。数据从硬盘还原到内存的过程,会耗用比较多的时间。(重新构建散列表时,需要重新计算每个数据的哈希值。)
保留原来的存储格式,将数据按照原有的格式存储在磁盘中。将散列表的大小、每个数据被散列到的槽的编号等信息,都保存在磁盘中。从磁盘中将数据还原到内存中的时候,可以避免重新计算哈希值。