Redis-线程IO模型

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zanpengfei/article/details/83691994

我们都知道redis是单线程,Node.js、Nginx同样也是单线程,redis所有的数据都是基于单线程运算的,但是redis可以处理高并发。

一、redis可以处理高并发的原因:

1、基于多路复用(事件轮询)、非阻塞。

2、非阻塞IO:非阻塞IO在套接字对象上提供一个Non_Blocking选项,打开该选项,读写不再阻塞,读写瞬间完成后,可以干别的事。能读多少取决于内核为套接字分配的读缓冲区内部的数据字节数,能写多少取决于内核为套接字分配的写缓冲区的空闲空间字节数,如下图所示:

3、事件轮询(多路复用):非阻塞IO存在个问题,读了一部分就返回,线程如何知道何时在继续读。写的时候,如果缓冲区满了,写不完,线程何时应该继续写,现在应该得到通知,事件轮询API就是解决该问题。我们通过select。现代操作系统的多路复用 API 已经不再使用select系统调用,而改用epoll(linux)和kqueue(freebsd & macosx)系统调用同时处理多个通道描述符的读写事件,因此我们将这类系统调用称为多路复用 API,如下图所示:

4、输入是读写描述符列表read_fds & write_fds,输出是与之对应的可读可写事件。

4、事件轮询API就是Java中的NIO技术。

5、redis将每个客户端套接字关联到一个指令队列,通过队列排队来顺序处理。

6、响应队列:Redis 同样也会为每个客户端套接字关联一个响应队列。Redis 服务器通过响应队列来将指令的返回结果回复给客户端。

7、定时任务:Redis 的定时任务会记录在一个称为最小堆的数据结构中。这个堆中,最快要执行的任务排在堆的最上方。在每个循环周期,Redis 都会将最小堆里面已经到点的任务立即进行处理。处理完毕后,将最快要执行的任务还需要的时间记录下来,这个时间就是select系统调用的timeout参数。因为 Redis 知道未来timeout时间内,没有其它定时任务需要处理,所以可以安心睡眠timeout的时间。

猜你喜欢

转载自blog.csdn.net/zanpengfei/article/details/83691994