Redis单线程模型

参考:

《「面试突击」-Redis 篇》-Redis 的线程模型了解吗?为啥单线程效率还这么高? (juejin.cn)

石杉的架构笔记

Redis 内部使用 文件事件处理器file event handler)来处理客户端请求。

这个文件事件处理器是单线程的,因此 Redis 才叫做 单线程模型

文件事件处理器 采用 I/O多路复用机制,同时监听多个 socket,将产生事件的 socket 压入 内存队列 中,I/O多路复用程序 每次从 内存队列 取出一个 socket 交给 事件分派器事件分派器 根据 socket 上的事件类型来选择对应的 事件处理器 进行处理。

整个过程都是单线程的。一个 socket 的事件处理完成之后,I/O多路复用程序才会去处理队列中的下一个 socket。

文件事件处理器 的结构包括 4 部分:

  • I/O多路复用程序
  • 内存队列
  • 文件事件分派器
  • 事件处理器(连接应答处理器、命令请求处理器、命令回复处理器)

1 五个重点概念

(1)I/O多路复用程序

负责监听客户端请求,每个客户端请求都是一个 socket,并将多个产生事件的 socket 压入内存队列中。

(2)内存队列

多个 socket 产生多个不同的事件,I/O多路复用程序会将这些 socket 压入内存队列中,文件事件分派器会从内存队列中一个一个的去取 socket 并分派给对应的事件处理器处理。

(3)文件事件分派器

负责从内存队列取出绑定了事件的 socket,并分配给对应的事件处理器来处理。

(4)事件处理器

事件处理器就是匹配对应的事件并处理 socket 的。

事件处理器分类:

  • 连接应答处理器:处理 socket 连接的建立。
  • 命令请求处理器:从 socket 中获取 Redis 命令信息。
  • 命令回复处理器:向 socket 输出本次操作的结果。

(5)文件事件

  • 当 socket 变得 可读 的时候(比如客户端对 redis 执行 write 操作,或者 close 操作),或者有新的可以应答的 socket 出现时(客户端对 redis 执行 connect 操作),socket 就会产生一个 AE_READABLE 事件。

  • 当 socket 变得 可写 的时候(客户端对 redis 执行 read 操作),socket 会产生一个 AE_WRITABLE 事件。

I/O多路复用程序可以同时监听 AE_REABLE 和 AE_WRITABLE 两种事件,如果一个 Socket 同时产生了这两种事件,那么文件事件分派器优先处理 AE_READABLE 事件,然后才是 AE_WRITABLE 事件。

2 客户端与 Redis 通信的一次流程

如图(图片来源:石杉的架构笔记):

在这里插入图片描述

流程如下:

  1. ⾸先,redis 服务端进程初始化的时候,会将 server socket 的 AE_READABLE 事件与连接应答处理器关联。
  2. 客户端 socket01 向 redis 进程的 server socket 请求建⽴连接,此时 server socket 会产⽣⼀个 AE_READABLE 事件。IO 多路复⽤程序监听到 server socket 产⽣的事件后,将该 socket 压⼊队列中。⽂件事件分派器从队列中获取 socket,交给连接应答处理器。连接应答处理器会创建⼀个能与客户端通信的 socket01,并将该 socket01 的 AE_READABLE 事件与命令请求处理器关联。
  3. 假设此时客户端发送了⼀个 set key value 请求,此时 redis 中的 socket01 会产⽣AE_READABLE 事件,IO 多路复⽤程序将 socket01 压⼊队列,此时事件分派器从队列中获取到 socket01 产⽣的 AE_READABLE 事件,由于前⾯ socket01 的 AE_READABLE 事件已经与命令请求处理器关联,因此事件分派器将事件交给命令请求处理器来处理。命令请求处理器读取 socket01 的 key value 并在⾃⼰内存中完成 key value 的设置。操作完成后,它会将 socket01 的 AE_WRITABLE 事件与命令回复处理器关联。
  4. 如果此时客户端准备好接收返回结果了,那么 redis 中的 socket01 会产⽣⼀个 AE_WRITABLE 事件,同样压⼊队列中,事件分派器找到相关联的命令回复处理器,由命令回复处理器对 socket01 输出本次操作的⼀个结果,⽐如 ok ,之后解除 socket01 的 AE_WRITABLE 事件与命令回复处理器的关联。

3 为什么单线程模型的 Redis 也能有很高的效率?

主要有以下几个原因:

  • 纯内存操作,响应时间大约 100 纳秒,非常快。
  • 核心是基于 I/O多路复用机制,读写 I/O 不必再阻塞了,能够同时管理多个 socket 连接。
  • Redis 是 C 语言实现的,执行效率高。
  • 单线程模型避免了多线程模型中频繁的上下文切换问题,并且避免了多线程竞争资源产生的阻塞等待问题。

Redis 采用单线程模型,对于每个指令的执行时间是有要求的,如果某个指令执行时间过长,会造成其他指令阻塞,导致 Redis 服务器卡顿。所以 Redis 适合于那些需要快速执行操作的场景

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值