Redis

Redis 快的原因

  1. 基于内存实现
  2. 高效的数据结构 : 简单动态字符串, 双端链表,压缩列表,字典,跳跃表
  3. 合理的数据编码
  4. 合适的线程模型 : I/O多路复用, 避免上下文切换,单线程模型
一. Redis是基于内存的数据库

Redis相对于磁盘数据库来说,省去了将数据I/O进内存的一个过程

二. 高效的数据结构

Redis有多种数据类型,每种数据类型的底层由一种或多种数据结构来支持。
在这里插入图片描述
1. 简单动态字符串SDS
在这里插入图片描述

在C语言中字符串的结尾以\0为结尾代表结束,如需获取字符串的全部信息就需要遍历。Redis中用一个len字段记录当前字符串的长度,获取长度直接获取len。时间为O(1)

内存重新分配

C语言设计修改字符串会重新分配内存,频繁修该,内存分配就会频繁。内存分配会消耗性能。
在Redis 中设计到字符串频繁修改操作,就会采取两种优化策略: 空间预分配, 惰性空间释放。

(1)空间预分配 :
当字符串进行阔容得时候,除了分配锁必须的空间外,还会多分配一些未使用的空间。动态字符串修改之后,如果len长度大于1M, 就会额外分配与len相同长度的未使用空间。如果修改后长度大于1M, 将分配1M的使用空间。

(2)惰性空间释放 :
当动态字符串缩短的时候,并不会回收多余的内存空间,而是使用free字段将多出来的空间记录下来,如果后续有变更操作,就直接使用free中记录的空间,减少实际内存的分配改动。实际相当于一个伪删除

二进制安全
按照动态字符串存储的SDS的len变量直接进行读取,多出来的标志位字符是不会被读取的。

2. 双端列表
在这里插入图片描述

Redis实现了一个双端列表的结构。

(1)前后节点
链表里每个节点都带有两个指针,prev和next,prev指向前节点,next指向后节点,时间复杂度O(1)可以前向获取和后向获取。
(2)头尾节点
有了头尾几点,对双端节点的处理时间复杂度可以降至O(1),可以在队前加入并且还可以向后端进行操作。
(3)链表长度
长度可以通过世界获取储存的变量len, 时间复杂度降低至O(1)

3. 压缩列表
在这里插入图片描述

当存储下数据的时候,不使用双端列表和额外的空间存储信息。用一个线性列表进行存储。压缩表的内存是连续分配的,遍历的速度非常快。在列表的头位置保存了

占用字节,偏移量(列表的长度), 节点的数量, 节点内容, 特殊标记符为结尾。

它是经过特殊编码,专门为了提升内存使用效率设计的。所有的操作都是通过指针与解码出来的偏移量进行的。

4. 字典
Redis 是 K-V型数据库,键值对是存在字典中的。
添加, 获取,删除都是O(1) 时间复杂度。

4. 跳表
在这里插入图片描述

Redis中的跳表在链表的基础上增加了索引,使得查询效率提升。查询的时间复杂度为O(logN)。在头节点中存储相关信息。

三. 合理的数据编码

对于每一种数据类型来说,底层的支持可能是多种数据结构,什么时候使用哪种数据结构,这就涉及到了编码转化的问题。

那我们就来看看,不同的数据类型是如何进行编码转化的:

String:存储数字的话,采用int类型的编码,如果是非数字的话,采用 raw 编码;

List:字符串长度及元素个数小于一定范围使用 ziplist 编码,任意条件不满足,则转化为 linkedlist 编码;

Hash:hash 对象保存的键值对内的键和值字符串长度小于一定值及键值对;

Set:保存元素为整数及元素个数小于一定范围使用 intset 编码,任意条件不满足,则使用 hashtable 编码;

Zset:zset 对象中保存的元素个数小于及成员长度小于一定值使用 ziplist 编码,任意条件不满足,则使用 skiplist 编码。

四. 线程模型

在这里插入图片描述
(1)I/O多路复用

  • I/O: 网络I/O
  • 多路:多个TCP连接
  • 复用:公用一个线程或进程

生产环境中的使用,通常是多个客户端连接 Redis,然后各自发送命令至 Redis 服务器,最后服务端处理这些请求返回结果。
应对大量的请求,Redis 中使用 I/O 多路复用程序同时监听多个套接字,并将这些事件推送到一个队列里,然后逐个被执行。最终将结果返回给客户端。
(2)使用单线程,减少上下文切换
不使用多线程,省去了上下文切换的过程。
(3)单线程
在这里插入图片描述
Redis使用Reactor单线程模型。

总结

基于内存实现
数据都存储在内存里,减少了一些不必要的 I/O 操作,操作速率很快。

高效的数据结构
底层多种数据结构支持不同的数据类型,支持 Redis 存储不同的数据;
不同数据结构的设计,使得数据存储时间复杂度降到最低。

合理的数据编码
根据字符串的长度及元素的个数适配不同的编码格式。

合适的线程模型
I/O 多路复用模型同时监听客户端连接;
单线程在执行过程中不需要进行上下文切换,减少了耗时。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值