Redis第12章 事件

  • 前言:Redis服务端是一个事件驱动程序,需要处理的事件分为两种:
    • 通过套接字和客户端的通讯称为文件事件
    • 自身的定时任务,前面提到过的serverCorn函数,称为时间事件

12.1 文件事件

  • Redis基于Reactor模式(https://www.jianshu.com/p/764067af8039)开发了自己的网络事件处理器,称为文件事件处理器
    • I/O多路复用监听多个套接字,并关联不同的事件处理器事件处理器就是一个个函数,Reactor模式文章中也提到了
    • 套接字准备好执行连接应答(accept)、读取(read)、写入(write)、关闭(close)等操作时,相关事件就会产生,然后执行相应事件处理器
  • 事件处理器以单线程执行,但因为Reactor模式所以可以同时监听多个套接字。
12.1.1 文件事件处理器构成
redis文件事件处理器.png
  • 上图和https://www.jianshu.com/p/764067af8039 中单线程reactor类似,I/O多路复用程序查询就绪事件放入队列,每次向文件事件分派器发送一个套接字,文件事件分派器调用事件处理器,执行结束后再发送下个套接字,直到单次队列就绪事件执行完毕,再次查询就绪事件一直循环,所以整体上说Redis是单线程执行的。
12.1.2 I/O多路复用程序实现
  • I/O多路复用功能通过包装select、epoll、evport、kqueue函数库实现,这些函数都是由系统内核自带的,Redis自动选择最佳的实现方式。
12.1.3 事件的类型
  • I/O多路复用可以监听多个套接字的ae.h/AE_READABLE事件和ae.h/AE_WRITEABLE事件:
    • 套接字可读时,客户端write操作、客户端close操作、接收新客户端可触发AE_READABLE
    • 套接字可写时,客户端read操作触发ae.h/AE_WRITEABLE
    • 同时有两种事件,优先处理ae.h/AE_READABLE
12.1.4 API
  • ae.c/aeCreateFileEvent:把套接字和指定事件加入到I/O多路复用程序监听,并关联事件和事件处理器。
  • ae.c/aeDeleteFileEvent:取消监听套接字的事件,并且取消事件和事件处理器关联。
  • ae.c/aeGetFileEvents:返回套接字的监听事件类型
  • ae.c/aeWait:传入套接字、事件和等待时间,给定时间内阻塞等待这个套接字的事件,事件发生或者超时后返回。
  • ae.c/aeApiPoll:指定时间内阻塞等待所有aeCreateFileEvent监听的套接字事件,产生至少一个或者超时返回。
  • ae.c/aeProcessEvents:这个函数就是文件事件分派器,调用aeApiPoll返回结果后串行调用事件处理器
  • ae.c/aeGetApiName:返回I/O多路复用的具体内核实现,如上面提到的的select、epoll、kqueue等等
12.1.5 文件事件处理器
  • Redis为文件事件编写了多个处理器,例如:
    • 服务端对连接的客户端应答时的连接应答处理器
    • 接收客户端请求时的命令请求处理器
    • 返回客户端结果时的命令回复处理器
    • 主从服务器复制时的复制处理器
  • 连接应答处理器:
    • networking.c/acceptTcpHandler:用于对连接服务端的客户端应答的handler,服务器初始化时会关联AE_READABLE事件,当客户端用sys/socket.h/connect函数连接服务端时,会产生AE_READABLE事件
      acceptTcpHandler.png
  • 命令请求处理器
    • networking.c/readQueryFromClient:当客户端通过应答处理器接入成功后,服务端将客户端套接字和AE_READABLE事件和命令请求处理器关联,客户端发送请求时,会触发AE_READABLE事件,进而执行这个处理器。
      readQueryFromClient.png
  • 命令回复处理器
    • networking.c/sendReplyToClient:当服务端端有命令回复需要传送给客户端的时候,服务端将客户端套接字和AE_WRITEABLE事件和命令回复处理器关联,客户端准备好接收回复命令时触发AE_WRITEABLE事件,回复完成后解除事件和处理器关联。
      sendReplyToClient.png
  1. 一次完整的客户端与服务器连接事件示例:


    示例.png

12.2 时间事件

  • Redis时间事件分为两类(和文件事件一样都是函数):
    • 定时事件:指定时间后执行一次。
    • 周期性事件:每隔指定时间指定时间执行一次。
  • 时间事件由三部分组成:
    • id:从小到大排序,越大的事件越新
    • when:UNIX时间戳,记录事件到达的时间
    • timeProc:时间事件处理器,一个函数,到达时间后调用
  • 一个时间事件是定时事件还是周期性事件取决于函数返回值
    • 返回ae.h/AE_NOMORE:定时事件,执行一次后删除。
    • 返回非ae.h/AE_NOMORE整数:周期性事件,这个整数是下次再执行的间隔时间,这时把事件的when属性更新,到达指定时间就可以再次执行,以此类推形成周期性事件。
    • 书中版本Redis3.0暂时没有使用定时事件
12.2.1 实现
  • 服务器把所有时间事件放在无序链表里,执行时遍历到达执行时间的事件,调用处理器。
  • 正常模式下Redis只有serverCron一个时间事件
12.2.2 API
  • 创建:ae.c/aeCreateTimeEvent,接收一个毫秒数和事件处理器,到达时间后执行这个处理器。
  • 删除:ae.c/aeDeleteFileEvent,接收一个事件id
  • 查询:ae.c/aeSearchNearestTimer,查询一个最近的即将到达的事件
  • 遍历:ae.c/processTimeEvents,遍历所有事件,调用所有到达执行时间的事件处理器。
12.2.3 时间事件应用实例:
  • serverCron函数主要工作:
    • 更新统计信息,比如事件、内存占用,数据库占用情况等
    • 清理过期键值对
    • 关闭失效客户端
    • 尝试进行AOF或RDB持久化操作
    • 如果是主服务器,对从服务器的同步工作
    • 如果是集群模式定期同步和连接测试
  • serverCron函数默认每100ms执行一次,可配置

12.3 事件的调度与执行

  • 服务器同时存在时间事件和文件事件,需要决定什么时候处理时间事件,什么时候处理文件事件,处理多长时间等等,函数是ae.c/aeProcessEvents,主要流程就是aeSearchNearestTimer获取最近要发生的一个事件,如果时间已经到了就执行,否则就等待,先处理文件事件,再处理时间事件
  • Redis服务器主函数的构成就是初始化无限循环aeProcessEvents关闭执行清理
    服务器运行流程.png
  • 调度和执行规则:
    • 因为取离现在最近一次发生的事件并等待,避免了频繁的轮询
    • 文件事件和时间事件都是同步、有序、原子的,不会被中断和抢占,所以处理器内部有相应的任务拆分优化,或者用子线程、子进程执行,避免长时间执行导致后续处理器阻塞。

总结

  • Redis的事件分为文件事件和时间事件。
  • 文件事件就是Redis对reactor模式具体实现,以便单线程处理多客户端。
  • 时间事件就是定时函数和周期函数,时间事件主要关注serverCron函数。
  • 这两种事件包含了Redis服务端的主要工作,流程如上图“服务器运行流程”。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,470评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,393评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,577评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,176评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,189评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,155评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,041评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,903评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,319评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,539评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,703评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,417评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,013评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,664评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,818评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,711评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,601评论 2 353

推荐阅读更多精彩内容

  • Redis服务器是一个事件驱动程序,服务器需要处理以下两类事件: 文件事件(file event):Redis服务...
    猪大金阅读 567评论 0 1
  • 第二部分 单机数据库的实现 数据库 服务器中的数据库 Redis服务器的所有数据库都保存在redisServer...
    你的头发真的好长阅读 231评论 0 0
  • 一、事件 Redis服务器是一个事件驱动程序,服务器需要处理两类事件: 1)文件事件(file event)Red...
    稻壳_be03阅读 538评论 0 0
  • 1.Redis特性 1)速度快:数据存放在内存上、基于C语言实现、单线程架构预防多线程竞争问题;2)基于键值对的数...
    Sponge1128阅读 619评论 0 1
  • 我的忠实粉丝,嚷嚷着你为什么不更新了,是啊,何止不更新,还没有再写日记了,有时候在简书上写,有时候在日记上写,有时...
    覃格尔阅读 381评论 2 0