Redis 源码剖析与实战
蒋德钧
中科院计算所副研究员
17747 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 47 讲
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/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

Redis事件驱动框架实现了Reactor模型,该模型处理高并发网络IO请求,包括连接事件、写事件、读事件,以及reactor、acceptor、handler三个关键角色。文章深入浅出地介绍了Reactor模型的工作机制和Redis对Reactor模型的实现,对于网络编程和高并发系统的设计与实现提供了有益的参考。主要介绍了aeMain函数的主循环逻辑、aeProcessEvents函数的事件捕获与分发功能,以及aeCreateFileEvent函数的事件注册功能。通过对这三个关键函数的介绍,读者可以了解Redis事件驱动框架的基本运行流程和实现细节。文章还提到了Redis基于Reactor模型实现高性能的网络框架,通过事件驱动框架,Redis可以使用一个循环来不断捕获、分发和处理客户端产生的网络连接、数据读写事件。总结了Redis事件驱动框架的主要函数和功能,并强调了事件驱动框架的基本运行流程。文章内容丰富,对于想要深入了解事件驱动框架的读者具有很高的参考价值。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《Redis 源码剖析与实战》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(16)

  • 最新
  • 精选
  • 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
    2
    70
  • 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
    2
    24
  • 飞龙
    main(server.c)->aeCreateEventLoop(aeApiCreate epoll_create)->aeCreateFileEvent(aeApiAddEvent epoll_ctl)->aeMain(server.c)->aeProcessEvents(aeApiPoll epoll_wait)
    2022-09-15归属地:广东
    1
  • 曾轼麟
    上篇文章回答的时候自己提到的-Redis基于多种IO复用实现了同一方法但是多套代码文件的思路,没想到这期老师就提到了。回答老师的问题:还有什么软件系统使用了Reactor模型? 答: 最典型的就是netty,java靠netty得以实现了高性能的服务 总结: 本篇文章老师主要介绍了Redis是如何实现Reactor模型,其本质上就是围绕三个事件的实现【连接请求,读事件,写事件】,而Redis为了方便实现,封装了事件驱动框架aeEventLoop,其本质上是一个不断处理事件的循环。能同时分发处理来自成百上千个客户端的读,写,连接等请求。
    2021-08-19
    1
  • 码小呆
    只知道netty用过Reactor模型,看了评论学到了
    2021-08-18
    1
  • 结冰的水滴
    kafka使用了Reactor编程模型,它使用一个Acceptor,多个Processor处理网络连接,读写请求,以及一个线程池处理消息读写
    2021-08-17
    1
  • kobe
    ae_epoll.c,对应 Linux 上的 IO 复用函数 epoll; ae_evport.c,对应 Solaris 上的 IO 复用函数 evport; ae_kqueue.c,对应 macOS 或 FreeBSD 上的 IO 复用函数 kqueue; ae_select.c,对应 Linux(或 Windows)的 IO 复用函数 select。 你好 我想问下 这个不同操作系统是不是在编译的时候就确定了对应的是哪一个实现?
    2023-08-24归属地:浙江
  • kobe
    ae_epoll.c,对应 Linux 上的 IO 复用函数 epoll;ae_evport.c,对应 Solaris 上的 IO 复用函数 evport;ae_kqueue.c,对应 macOS 或 FreeBSD 上的 IO 复用函数 kqueue;ae_select.c,对应 Linux(或 Windows)的 IO 复用函数 select。
    2023-08-24归属地:浙江
  • kobe
    ae_epoll.c,对应 Linux 上的 IO 复用函数 epoll; ae_evport.c,对应 Solaris 上的 IO 复用函数 evport; ae_kqueue.c,对应 macOS 或 FreeBSD 上的 IO 复用函数 kqueue; ae_select.c,对应 Linux(或 Windows)的 IO 复用函数 select。
    2023-08-24归属地:浙江
  • 柯江胜
    对于写事件还不是很理解,连接事件是客户端发来连接请求,读事件是客户端发来命令请求需要读取,那么写事件对应的是什么触发的?
    2022-09-10归属地:上海
    1
收起评论
显示
设置
留言
16
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部