Redis源码剖析与实战
蒋德钧
中科院计算所副研究员
新⼈⾸单¥59.9
2241 人已学习
课程目录
已更新 11 讲 / 共 33 讲
0/4登录后,你可以任选4讲全文学习。
课前导读 (2讲)
开篇词 | 阅读Redis源码能给你带来什么?
免费
01 | 带你快速攻略Redis源码的整体架构
数据结构模块 (6讲)
02 | 键值对中字符串的实现,用char*还是结构体?
03 | 如何实现一个性能优异的Hash表?
04 | 内存友好的数据结构该如何细化设计?
05 | 有序集合为何能同时支持点查询和范围查询?
06 | 从ziplist到quicklist,再到listpack的启发
07 | 为什么Stream使用了Radix Tree?
事件驱动框架和执行模型模块 (3讲)
08 | Redis server启动后会做哪些操作?
09 | Redis事件驱动框架(上):何时使用select、poll、epoll?
10 | Redis事件驱动框架(中):Redis实现了Reactor模型吗?
Redis源码剖析与实战
15
15
1.0x
00:00/00:00
登录|注册

10 | Redis事件驱动框架(中):Redis实现了Reactor模型吗?

你好,我是蒋德钧。今天,我们来聊聊 Redis 是如何实现 Reactor 模型的。
你在做 Redis 面试题的时候,或许经常会遇到这样一道经典的问题:Redis 的网络框架是实现了 Reactor 模型吗?这看起来像是一道简单的“是 / 否”问答题,但是,如果你想给出一个让面试官满意的答案,这就非常考验你的高性能网络编程基础和对 Redis 代码的掌握程度了。
如果让我来作答这道题,我会把它分成两部分来回答:一是介绍 Reactor 模型是什么,二是说明 Redis 代码实现是如何与 Reactor 模型相对应的。这样一来,就既体现了我对网络编程的理解,还能体现对 Redis 源码的深入探究,进而面试官也就会对我刮目相看了。
实际上,Reactor 模型是高性能网络系统实现高并发请求处理的一个重要技术方案。掌握 Reactor 模型的设计思想与实现方法,除了可以应对面试题,还可以指导你设计和实现自己的高并发系统。当你要处理成千上万的网络连接时,就不会一筹莫展了。
所以今天这节课,我会先带你了解下 Reactor 模型,然后一起来学习下如何实现 Reactor 模型。因为 Redis 的代码实现提供了很好的参考示例,所以我会通过 Redis 代码中的关键函数和流程,来给你展开介绍 Reactor 模型的实现。不过在学习 Reactor 模型前,你可以先回顾上节课我给你介绍的 IO 多路复用机制 epoll,因为这也是学习今天这节课的基础。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/1000字
划线
笔记
复制
该试读文章来自付费专栏《Redis源码剖析与实战》,如需阅读全部文章,
请订阅文章所属专栏新⼈⾸单¥59.9
立即订阅
登录 后留言

精选留言(5)

  • Darren
    Reactor模型可以分为3种:
    单线程Reactor模式
    一个线程:
    单线程:建立连接(Acceptor)、监听accept、read、write事件(Reactor)、处理事件(Handler)都只用一个单线程。

    多线程Reactor模式
    一个线程 + 一个线程池:
    单线程:建立连接(Acceptor)和 监听accept、read、write事件(Reactor),复用一个线程。
    工作线程池:处理事件(Handler),由一个工作线程池来执行业务逻辑,包括数据就绪后,用户态的数据读写。

    主从Reactor模式
    三个线程池:
    主线程池:建立连接(Acceptor),并且将accept事件注册到从线程池。
    从线程池:监听accept、read、write事件(Reactor),包括等待数据就绪时,内核态的数据I读写。
    工作线程池:处理事件(Handler),由一个工作线程池来执行业务逻辑,包括数据就绪后,用户态的数据读写

    具体的可以参考并发大神 doug lea 关于Reactor的文章。 http://gee.cs.oswego.edu/dl/cpjslides/nio.pdf

    再提一点,使用了多路复用,不一定是使用了Reacto模型,Mysql使用了select(为什么不使用epoll,因为Mysql的瓶颈不是网络,是磁盘IO),但是并不是Reactor模型

    回到问题,那些也是reactor

    nginx:nginx是多进程模型,master进程不处理网络IO,每个Wroker进程是一个独立的单Reacotr单线程模型。

    netty:通信绝对的王者,默认是多Reactor,主Reacotr只负责建立连接,然后把建立好的连接给到从Reactor,从Reactor负责IO读写。当然可以专门调整为单Reactor。

    kafka:kafka也是多Reactor,但是因为Kafka主要与磁盘IO交互,因此真正的读写数据不是从Reactor处理的,而是有一个worker线程池,专门处理磁盘IO,从Reactor负责网络IO,然后把任务交给worker线程池处理。
    2021-08-17
    6
  • Kaito
    1、为了高效处理网络 IO 的「连接事件」、「读事件」、「写事件」,演化出了 Reactor 模型

    2、Reactor 模型主要有 reactor、acceptor、handler 三类角色:

    - reactor:分配事件
    - acceptor:接收连接请求
    - handler:处理业务逻辑

    3、Reactor 模型又分为 3 类:

    - 单 Reactor 单线程:accept -> read -> 处理业务逻辑 -> write 都在一个线程
    - 单 Reactor 多线程:accept/read/write 在一个线程,处理业务逻辑在另一个线程
    - 多 Reactor 多线程 / 进程:accept 在一个线程/进程,read/处理业务逻辑/write 在另一个线程/进程

    4、Redis 6.0 以下版本,属于单 Reactor 单线程模型,监听请求、读取数据、处理请求、写回数据都在一个线程中执行,这样会有 3 个问题:

    - 单线程无法利用多核
    - 处理请求发生耗时,会阻塞整个线程,影响整体性能
    - 并发请求过高,读取/写回数据存在瓶颈

    5、针对问题 3,Redis 6.0 进行了优化,引入了 IO 多线程,把读写请求数据的逻辑,用多线程处理,提升并发性能,但处理请求的逻辑依旧是单线程处理

    课后题:除了 Redis,你还了解什么软件系统使用了 Reactor 模型吗?

    Netty、Memcached 采用多 Reactor 多线程模型。

    Nginx 采用多 Reactor 多进程模型,不过与标准的多 Reactor 多进程模型有些许差异。Nginx 的主进程只用来初始化 socket,不会 accept 连接,而是由子进程 accept 连接,之后这个连接的所有处理都在子进程中完成。
    2021-08-17
    5
  • 屈仁能
    只知道netty用过Reactor模型,看了评论学到了
    2021-08-18
  • 结冰的水滴
    kafka使用了Reactor编程模型,它使用一个Acceptor,多个Processor处理网络连接,读写请求,以及一个线程池处理消息读写
    2021-08-17
  • 末日,成欢
    我一直不明白的一点, while循环里使用aeApiPoll得到一些事件后,要对这些事件进行处理, 每个处理函数不耗时吗, 假设每个函数处理耗时1ms, 有1000个事件, 那么下一次循环不得1s后了。
    2021-08-17
    1
收起评论
5
返回
顶部