前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Redis是单线程?

Redis是单线程?

作者头像
黑洞代码
发布2021-07-14 13:41:32
9620
发布2021-07-14 13:41:32
举报
文章被收录于专栏:落叶飞翔的蜗牛

如何理解Redis是单线程的?

单线程指的是Redis的网络请求模块使用了一个线程(所以不需考虑并发安全性),即一个线程处理所有网络请求,网络请求模块之外的其他模块仍用了多个线程。

单线程的Redis为何那么快?

(1) 绝大部分请求是纯粹的内存操作(非常快速)

(2) 采用单线程,避免了不必要的上下文切换和竞争条件

(3) 非阻塞IO —— IO多路复用,Redis采用epoll做为I/O多路复用技术的实现,再加上Redis自身的事件处理模型将epoll中的连接,读写,关闭都转换为了事件,不会在I/O上浪费过多的时间。

Redis处理流程分析简易版

Redis分客户端和服务端,一次完整的Redis请求事件有多个阶段(客户端到服务器的网络连接-->Redis读写事件发生-->Redis服务端的数据处理(单线程)-->数据返回)。平时所说的Redis单线程模型,本质上指的是服务端的数据处理阶段,不牵扯网络连接和数据返回,这是理解Redis单线程的第一步。

1:客户端到服务器的网络连接

首先,客户端和服务器是socket通信方式,socket服务端监听可同时接受多个客户端请求,这点很重要,如果不理解可先记住。注意这里可以理解为本质上与Redis无关,这里仅仅做网络连接,或者可以理解为,为Redis服务端提供网络交互API。

2:Redis读写事件发生并向服务端发送请求数据

首先确定一点,Redis的客户端与服务器端通信是基于TCP连接,第一阶段仅仅是建立了客户端到服务器的网络连接,然后才是发生第二阶段的读写事件。

完成了上一个阶段的网络连接,Redis客户端开始真正向服务器发起读写事件,假设是set(写)事件,此时Redis客户端开始向建立的网络流中发送数据,服务端接收客户端的请求数据。

3:Redis服务端的数据处理

服务端完成了第二阶段的数据接收,接下来开始依据接收到的数据做逻辑处理,然后得到处理后的数据。数据处理可以理解为一次方法调用,最终得到方法返回值。

4:数据返回

当Redis服务端数据处理完后就会立即返回处理后的数据。

Redis内部实现?

  1. 从Redis的内部结构设计原理进行考虑,Redis是基于Reactor模式开发了自己的网络事件处理器—— 这个处理器被称为文件事件处理器(file event handler)文件事件处理器是单线程的,所以才叫Redis的单线程模型,这也决定了Redis是单线程的。
  2. 采用了epoll+事件框架,将epoll中的读、写、关闭、连接都转化成了事件,然后利用epoll的多路复用特性,绝不在IO上浪费一点时间。

什么文件事件处理器?

Redis单线程模型中最为核心的就是文件事件处理器。文件事件处理器结构包含5个部分,其实真正包含为4个部分(不包含socket队列,加上主要方便后面理解):多个socket、IO多路复用程序、socket队列、文件事件分派器和事件处理器。而事件处理器又分为3个部分为:连接应答处理器、命令请求处理器、命令回复处理器。如图(逻辑概念):

I/O 多路复用程序(I/O Multiplexing Module)会把消息放入队列中,然后通过文件事件分派器(Fileevent Dispatcher),转发到不同的事件处理器中。上图将I/O 多路复用程序与socket队列分开便于理解,真实的I/O 多路复用程序如下图所示。

什么是IO多路复用?

有多个客户连接,sockfd1,sockfd2,sockfd3..sockfdn,服务的同时监听这n个客户,当其中有一个发来消息时就从阻塞中返回,然后就调用read读取收到消息的sockfd,然后又循环回阻塞;这样就不会因为阻塞在其中一个上而不能处理另一个客户的消息

Redis单线程模型的工作流程

1、首先在Redis启动初始化的时候,Redis会先将事件处理器中的连接应答处理器和AE_READABLE事件关联起来;

2、如果客户端向Redis发起连接,会产生AE_READABLE事件(步骤A),产生该事件后会被IO多路复用程序监听到(步骤B),然后IO多路复用程序会把监听到的socket信息放入到队列中(步骤C),事件分配器每次从队列中取出一个socket(步骤D),然后事件分派器把socket给对应的事件处理器(步骤E)。由于连接应答处理器和AE_READABLE事件在Redis初始化的时候已经关联起来,所以由连接应答处理器来处理跟客户端建立连接,然后通过ServerSocket创建一个与客户端一对一对应的socket,如叫socket01,同时将这个socket01的AE_READABLE事件和命令请求处理器关联起来。

3、当客户端向Redis发生请求时(读、写操作),首先就会在对应的socket如socket01上会产生AE_READABLE事件(步骤A),产生该事件后会被IO多路复用程序监听到(步骤B),然后IO多路复用程序会把监听到的socket信息放入到队列中(步骤C),事件分配器每次从队列中取出一个socket(步骤D),然后事件分派器把socket给对应的事件处理器(步骤E)。由于命令处理器和socket01的AE_READABLE事件关联起来了,然后对应的命令请求处理器来处理。这个命令请求处理器会从事件分配器传递过来的socket01上读取相关的数据,执行相应的读写处理。操作执行完之后,Redis就会准备好相应的响应数据(如你在Redis客户端输入命令:set a 123,回车后看到的响应结果:ok),并将socket01的AE_WRITABLE事件和命令回复处理器关联起来。

4、当客户端查询Redis是否完成相应的操作,就会在socket01上产生一个AE_WRITABLE事件,会由对应的命令回复处理器来处理,就是将准备好的响应结果数据写入socket01(由于socket连接是双向的),返回给客户端,如读操作,客户端会显示ok。

5、如果命令回复处理器执行完成后,就会删除这个socket01的AE_WRITABLE事件和命令回复处理器的关联。

6、这样客户端就和Redis进行了一次通信。由于连接应答处理器执行一次就够了,如果客户端再次进行操作就会由命令请求处理器来处理,反复执行。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-06-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 落叶飞翔的蜗牛 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1:客户端到服务器的网络连接
  • 2:Redis读写事件发生并向服务端发送请求数据
  • 3:Redis服务端的数据处理
  • 4:数据返回
相关产品与服务
云数据库 Redis
腾讯云数据库 Redis(TencentDB for Redis)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档