Redis: 单线程模型、I/O多路复用、影响性能的因素(为什么这么快)、性能与QPS(到底有多快)

1.单线程架构

Redis基于Reator模式开发了自己的网络事件处理器:文件事件处理器。其架构图如下:

文件事件处理器的四部分:套接字、I/O多路复用程序、文件事件分派器和事件处理器。

1.1.套接字Socket

  • 文件事件就是对套接字的抽象,每当一个套接字准备好执行连接、写入、读取、关闭等操作时,都会产生一个文件事件。
  • 因为一个Redis服务器会连接多个套接字,所以多个文件事件可能会并发出现。

1.2.I/O多路复用程序

  • I/O多路复用程序,负责监听多个套接字,按照处理顺序,将套接字存放在一个队列中。
  • 套接字队列以有序(sequentially)、同步(synchronously)、每次一个套接字的方式向文件事件分派器传送套接字。
  • 当上一个套接字产生的事件被处理完毕之后, I/O 多路复用程序才会继续向文件事件分派器传送下一个套接字。
  • 关于I/O多路复用的优势后续章节会细说。

1.3.文件事件分派器

文件事件分派器接受I/O多路复用程序传递的套接字,根据套接字的事件类型,调用相应的事件处理器进行处理。

1.4.文件事件处理器

本文不打算对文件事件处理器进行过多的描述,只是几类处理器进行简单的说明:

  • 连接应答处理器:对连接服务器的各个客户端进行应答。
  • 命令请求处理器:接收客户端传来的命令请求。
  • 命令回复处理器:向客户端返回命令的执行结果
  • 复制处理器:当主服务器和从服务器进行复制操作时, 主从服务器都需要关联此处理器。
  • 等等…

2.I/O多路复用

I/O多路复用是其中的一种高级I/O模型,英文为I/O multiplexingmultiplexing译为多路复用多路传输的意思。

作为高性能服务,Redis服务器,同时连接多个连接(Socket)是在正常不过的事情。

此时,如何处理多个连接呢?

  • 方式一:传统的多进程并发模型 ,每进来一个新的I/O流会分配一个新的进程管理。
  • 方式二:I/O多路复用 ,单个线程,通过记录跟踪每个I/O流的状态,来同时管理多个I/O流 。

对I/O多路复用的分词理解:

  • I/O: 这是一种处理I/O的高级模型。
  • 多路: 多个I/O流,多个Socket连接。
  • 复用:多个Socket连接共用单个线程。复用方式:单个线程,记录跟踪每个I/O流的状态,通过开关控制,每次处理一个I/O流。

I/O多路复用示例图:

在这里插入图片描述

select、poll、epoll

I/O多路复用模型是一种理论上的模型,select、poll和epoll都是这个模型的具体实现。

select是第一个实现 (1983 左右在BSD里面实现的),它存在很多问题:

  • 会修改传入的参数数组,这个对于一个需要调用很多次的函数,是非常不友好的。
  • select 只能监视1024个链接。
  • 任何一个I/O流出现了数据,select 仅仅会返回,但是并不会告诉哪个I/O流上有数据,需要自己去遍历查找。
  • select 不是线程安全的。

poll是14年以后(1997年)一帮人实现的,修复了select的很多问题:

  • 不再修改传入的参数数组。
  • 去掉了select只能监视1024个链接的限制。

epoll是5年以后, 在2002, 大神 Davide Libenzi 实现的,继续修复了selectpoll的绝大部分问题:

  • 不仅告诉sock组里面数据,还会告诉具体哪个sock有数据。
  • 线程安全的。

epoll本身还有一个致命的问题:只有linux支持。BSD(是Unix的衍生系统)上面对应的实现是kqueue。

下图给出了pollepoll的性能测试(横轴为连接数,纵轴为每秒处理请求的数量):

在这里插入图片描述

可以看到,epoll每秒处理请求的数量基本不会随着链接变多而下降的。

3.影响 Redis 性能的因素(Redis为什么这么快)

参考章节1和2,可以总结提升Redis性能的主要因素如下:

  • 完全基于内存:Redis是纯内存数据库,绝大部分请求都是纯内存操作。内存响应时间大约为百纳秒级别,每秒可进行几百万级别的操作。
  • 非阻塞多路复用IO:Redis使用epoll作为I/O多路复用技术的实现,通过单线程来处理多个链接请求,减少网络IO的耗时。
  • 事件处理模型:Redis自身的事件处理模型将epoll的连接、读写、关闭都转换为文件事件,进一步减少在网络IO上的耗时。
  • 单线程模型:Redis采用单线程模型,简化了数据结构和算法的实现,避免了线程切换、调度(锁)、竞争产生的消耗。
  • 数据结构与特殊处理:Redis数据结构简单,数据操作也简单,而且还专门针对数据指定了压缩、优化、跳表等特殊处理。

特别的,单线程会有一个问题:对于每个命令的执行时间是有要求的。如果某个命令执行过长,会造成其他命令的阻塞,对于Redis这种高性能的服务来说是致命的,所以Redis是面向快速执行场景的数据库。这一点非常关键。

4.Redis的性能(Redis到底有多快)

Redis 自带了一个叫 redis-benchmark 的工具来模拟 N 个客户端同时发出 M 个请求,即对QPS进行自测。

首先来看一张官方提供的测试结果:

在这里插入图片描述

上图中,横轴是连接数,纵轴是每秒处理的请求时。由图中可知:

  • Redis的最大QPS能够到达120000+q/s。
  • 当连接数在10000以下时,Redis的QPS超过100000q/s。
  • 当连接数达到60000时,Redis的QPS仍有50000q/s。

5.参考资料

  • 3
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值