Redis 介绍
Redis 是一种键值(Key-Value)数据库,叫做非关系数据库,只能通过键来查询值,改结构使得 Redis 读写效率很快。
用途: Redis 主要是内存数据库,数据是存储在内存中,虽然常被用作内存数据库,也支持将数据存储在硬盘中。
特点: Redis 的键数据类型是字符串,值得数据类型很多:字符串、列表、字典、集合、有序集合。
Redis 由多种数据结构来实现,主要出于时间和空间的考虑,当数据量小时使用压缩列表,当数据量大时使用链表,为了保证速度又要和数组结合就采用散列表。
列表
特点: 支持存储一组数据。
实现方式:
- 压缩列表(ziplist)
- 双向循环列表
压缩列表
当列表存储的 数据量比较小 ,就采用压缩列表的方式,需要满足两个条件:
- 列表保存的单个数据小于 64 字节;
- 列表中数据个数小于 512 个。
压缩列表: Redis 设计的一种数据存储结构,类似于数组,通过连续的内存空间,来存储数据。
与数组不同点: 数组要求每个数据大小相同,但是压缩列表允许存储不同长度的数据。
压缩列表优点:
- 比较节省内存,可以支持不同类型数据的存储;
- 数据存储在一片连续的内存空间,通过键来获取值为列表类型的数据,读取效率高。
双向循环列表
当 数据量比较大时 ,需要使用双向循环列表来实现存储数据。
单向链表: 单向链表只有一个方向,节点只有一个后继指针指向后面的节点。
双向链表: 双向链表,支持两个方向,每个节点不止有一个后继指针指向后面的节点,还有一个前驱指针指向前面的节点。
字典
特点: 用来存储一组数据对,每个数据对包含键值两部分。
实现方式:
- 压缩列表
- 散列表
压缩列表
存储的数据量比较小的情况下,Redis 才使用压缩列表来实现字典类型,满足两个条件:
- 字典中保存的键和值得大小都要小于64字节。
- 字典中键值对的个数要小于512个。
散列表
不满足以上两个条件,Redis 使用散列表来实现字典类型。
使用 MurmurHash 这种运行速度快、随机性好的哈希算法作为哈希函数,哈希冲突问题使用链表法来解决。
Redis 还支持散列表的动态扩容、缩容。
数据动态增加: 装载因子大于1,Redis 会触发扩容,将散列表扩大为原来的2倍左右。
数据动态减少: 装载因子小于0.1,Redis 会触发缩容,缩小为字典中数据个数的大约2倍左右。
扩容缩容需要做大量数据搬移和哈希值的运算,采用 渐进式扩容缩容策略 ,将数据搬移分批次进行,避免大量数据一次性搬移导致服务停顿。
集合
用来存储一组不重复的数据,有两种实现方式:
- 基于有序数组
- 散列表
有序数据
需要满足两个条件:
- 存储的数据都是整数;
- 存储的数据元素不超过512个。
散列表
不满足以上两个条件
有序集合
两种实现方式:
- 压缩列表
- 跳表
压缩列表
当数据量比较小,满足一下两个条件:
- 所有数据大小都小于64字节;
- 元素个数小于128。
跳表
用来存储一组数据,并且每个数据都会有一个得分,通过得分大小,将数据组织处跳表的数据结构,用来支持快速地按照得分、得分区间来获取数据。
数据结构持久化
将内存的数据存储到硬盘中,当断电时,存储在 Redis 中的数据也不会丢失。
- 清除原有的数据结构,只将数据存储到磁盘中,当需要从磁盘还原数据到内存时,再重新将数据组织成原来的数据结构。目前 Redis 采用的就是这种持久化思路,缺点是需要重构数据结构。
- 保留原来的存储格式,将数据按照原有格式存储在磁盘中。