0
点赞
收藏
分享

微信扫一扫

Redis Threaded I/O模型

1主流 I/O 模型

阻塞IO、非阻塞IO、异步 IO 。

1.1BIO 模型

同步阻塞模型,一个客户单对应一个链接的处理线程

Redis Threaded I/O模型_Redis

缺点:

1、IO 中如果进行 read 是阻塞操作,如果请求的链接操作不做任何操作,也会导致线程阻塞,浪费线程资源

2、如果线程很多,会导致服务器压力增加,比如 C10K问题

应用场景:

BIO 方式运用数目比较小且固定的架构,这种方式对服务器资源要求比较高,但是程序简单容易理解。

1.2NIO 模型

同步非阻塞,是服务器实现的模式是一个线程可以处理多个请求(链接),客户端发送的链接都会注册到多路复用器 selector 上,多路复用器轮训到介入的所有 IO 请求进行处理。

应用场景:

NIO方式适用于链接数目多(轻操作) 的架构,比如聊天服务器,弹幕系统,服务器间通讯,编程比较复杂。Java NIO 模型如下图所示:

Redis Threaded I/O模型_Redis_02

总结:

NIO 的三大核心组件:Channel(通道)、Buffer (缓冲区)、Selector (多路复用器)

1、Channel 类似流,每个 Channel 对应一个 buffer 缓冲区。

2、Channel 组册到 Selector 上,由 Selecotor 根据 Channel 读写事件发生时交给空闲线程处理。

3、NIO 中 Buffer 与 Channel 都是可读可写的。

NIO 模型实现

在 linux 系统中是通过调用系统内核函数来创建 socket ,selecotor 对应操作系统的 epoll 描述符。可以将 socket 的连接文件描述符绑定到 epoll 文件描述符上,进行事件的异步通知,实现一个线程处理,并且减少大量的无效遍历,事件处理交给了操作系统的内核,提升效率。

2Redis 线程模型

Redis 是一个典型的基于 epoll 的 nio 线程模型, epoll 实例手机所有的事件(连接与读事件)由一个服务线程处理所有命令。

Redis 底层相关的 epoll 的源码实现在 src/ae_epoll.c 文件中。

2.1AIO 模型

异步非阻塞、由于操作系统完成后回调通知程序启动线程去处理,一般适用于链接较多且链接时间较长的应用。

应用场景:

AIO 方式适用于链接数目多且比较长(重操作),比如设备每间隔 2秒上报状态。

2.2三种 I/O 模型对比


BIO

NIO

AIO



IO模型





同步阻塞





同步非阻塞(多路复用)





异步非阻塞





编程难度





简单





复杂





复杂





可靠性

















吞吐量















2.3 I/O问题与Threaded I/O的引入

如果要说Redis会有什么性能问题,那么从I/O角度,由于它没有像其他Database一样使用磁盘,所以不存在磁盘I/O的问题。在数据进入缓冲区前及从缓冲区写至Socket时,存在一定的网络I/O,特别是写I/O对性能影响比较大。以往我们会考虑做管道化来减小网络I/O的开销,或者将Redis部署成Redis集群来提升性能。

在Redis 6.0之后,由于Threaded I/O的引入,Redis开始支持对网络读写的线程化,让更多的线程参与进这部分动作中,同时保持命令的单线程执行。这样的改动从某种程度上说可以既提升性能,但又避免将命令执行线程化而需要引入锁或者其他方式解决并行执行的竞态问题。

2.4 Threaded I/O在做什么

在老版本的实现中,Redis将不同client的命令执行结果保存在各自的client.buf中,然后把待回复的client存放在一个列表里,最后在事件循环中逐个将buf的内容写至对应Socket。对应在新版本中,Redis使用多个线程完成这部分操作。

对读操作,Redis同样地为server对象新增了一个clients_pending_read属性,当读事件来临时,判断是否满足线程化读的条件,如果满足,那么执行延迟读操作,将这个client对象添加到server.clients_pending_read列表中。和写操作一样,留到下一次事件循环时使用多个线程完成读操作。

举报

相关推荐

0 条评论