五、事件

alt

alt

五、事件

redis服务器实际是一个事件循环,事件分为文件事件和时间事件。

文件事件

文件事件就是服务器对套接字操作的抽象,服务器与客户端的通信产生文件事件,服务器通过监听并处理这些文件事件完成一系列网络通信操作;

文件事件处理器以单线程方式运行,但是通过IO多路复用程序同时监听多个套接字,既实现了高性能的网络通信模型,又能与redis服务器中其他同样以单线程方式运行的模块进行对接,保证了redis内部单线程设计的简单性;

文件事件分类

读事件

客户端对连接到服务器的套接字执行write操作或close操作,会生成读事件;
客户端对服务器监听套接字执行connect操作,会生成读事件;

写事件

客户端对连接到服务器的套接字执行read操作,会生成写事件;

文件事件处理器

套接字

每个客户端与服务器对应一个套接字;

IO多路复用程序

通过包装常见的IO多路复用函数库实现;
IO多路复用程序将产生文件事件的所有套接字保存在一个队列中,以有序、每次一个的方式向文件事件分排器传送套接字;
只有在上一个套接字处理完毕之后,才会继续发送下一个套接字;
如果同一个套接字同时产生了读事件和写事件,IO多路复用程序优先发送读事件,然后发送写事件;

文件事件分派器

负责接收IO多路复用程序发送的套接字,并按照不同的事件类型调用相应的事件处理器;

事件处理器

连接应答处理器
负责对连接服务器监听套接字的客户端进行应答;
命令请求处理器
负责从套接字接收客户端发送的命令请求;
命令回复处理器
负责处理命令请求并将得到的结果通过套接字返回给客户端;

时间事件

时间事件分类

定时事件

一段时间后执行一次;

周期性事件

每隔一段时间执行一次;

事件事件的属性组成

id

事件事件id;

when

时间事件的到达时间;

timeProcess

时间事件处理器;

redis服务器中只有serverCron函数一个周期性时间事件,默认每100毫秒执行一次,用于对正在运行的服务器进行维护;

redis服务器会将所有的时间事件放在一个无序链表中,每当时间事件执行器开始运行时,就会遍历无序链表,找到所有已到达的时间事件,然后调用对应的时间事件处理器;

无序链表大多数情况下只有一个时间事件,即使在benchMark模式下,也只有两个时间事件,所以无序链表几乎退化成一个链表使用;

serverCron

更新服务器时间缓存unixtime、mstime;

服务器只有在执行输出打印日志、更新lrulock、决定是否执行持久化操作这类对时间精度要求不高的任务时,才会使用到unixtime、mstime;
服务器在执行添加慢查询日志、为键设置过期时间这类对时间精度要求更高的任务时,仍然会再次执行系统调用,获取最精确的时间戳;

更新服务器lruLock;

默认每十秒更新一次,结合对象redisObject结构中的lru属性计算对象的空转时长;结合客户端redisClient结构中的last_instersection_time计算客户端空转时长;

更新服务器最近一秒执行命令次数;

按照一定的算法抽样估算服务器最近一秒执行命令的次数;

更新服务器内存峰值记录;

处理SIGTERM信号;

redis服务器在启动时,为服务器进程SIGTERM信号关联信号处理器sigtermHandler函数,该函数的作用是在接收到服务器发送的SIGTERM信号时,将服务器状态redisServer结构中的shutdown_asap标识设置为1;
serverCron函数每次执行时,都会检查shutdown_asap标识的值;如果为0,不做任何操作;如果为1,立即关闭这个服务器;

管理客户端资源;

serverCron函数执行时,会调用clientsCron函数对连接到服务器的所有客户端进行两项检查:
1.如果服务器与客户端的连接已经超时,则断开与客户端的连接;
2.如果服务器在处理客户端上一个命令请求时生成的输入缓冲区过大,将输入缓冲区释放,并重新创建一个固定大小的空白缓冲区分配给该客户端;

管理数据库资源

serverCron函数执行时,会调用activeExpireCycle函数,该函数的作用是分多次遍历服务器中的各个数据库,按照算法抽取一部分数据库键进行过期检查,将过期键删除;

执行被延迟的BGREWRITEAOF命令;

服务器在执行BGSAVE命令期间,接收到客户端发送的BGREWRITEAOF命令会被阻塞挂起;

检查持久化操作的运行状态;

服务器状态redisServer结构中的rdb_child_pid、aof_child_pid分别表示执行BGSAVE、BGREWRITEAOF命令时生成的子进程id,用于检查BGSAVE命令或BGREWRITEAOF命令是否正在被执行;
如果rdb_child_pid、aof_child_pid中有一个属性的值不为-1,就会执行一次wait3函数,检查子进程是否有信号发送给当前服务器进程;
如果有信号到达,证明新的RDB文件或新的AOF文件已经生成,就需要用新文件代替旧文件;
如果没有信号到达,证明持久化操作尚未完成,则不做任何操作;
如果rdb_child_pid、aof_child_pid的值均为-1,则执行以下三项检查:
检查是否有被延迟的BGREWRITEAOF命令,如果有,触发该命令的执行;
检查save选项所设置的保存条件是否满足,如果满足且没有正在执行持久化操作,则触发BGSAVE命令的执行;
检查AOF重写条件是否满足,如果满足且没有正在执行持久化操作,则触发BGREWRITEAOF命令的执行;

关闭异步客户端;

服务器处理客户端发送的命令请求时生成的输出缓冲区超过硬性限制的大小,或在规定的时间内始终超出软性限制的大小,客户端会被关闭;

将redisServer结构中的aof_buf缓冲区中的内容写入并同步到AOF文件;

更新serverCron函数的执行次数;

#redis事件#
redis 文章被收录于专栏

redis20000字笔记(含思维导图版本-大纲版本)

全部评论

相关推荐

真tmd的恶心,1.面试开始先说我讲简历讲得不好,要怎样讲怎样讲,先讲背景,再讲技术,然后再讲提升多少多少,一顿说教。2.接着讲项目,我先把背景讲完,开始讲重点,面试官立即打断说讲一下重点,无语。3.接着聊到了项目的对比学习的正样本采样,说我正样本采样是错的,我解释了十几分钟,还是说我错的,我在上一家实习用这个方法能work,并经过市场的检验,并且是顶会论文的复现,再怎么不对也不可能是错的。4.面试官,说都没说面试结束就退出会议,把面试者晾在会议里面,丝毫不尊重面试者难受的点:1.一开始是讲得不好是欣然接受的,毕竟是学习。2.我按照面试官的要求,先讲背景,再讲技术。当我讲完背景再讲技术的时候(甚至已经开始蹦出了几个技术名词),凭什么打断我说讲重点,是不能听出人家重点开始了?这也能理解,每个人都有犯错,我也没放心上。3.我自己做过的项目,我了解得肯定比他多,他这样贬低我做过的项目,说我的工作是错误的,作为一个技术人员,我是完全不能接受的,因此我就和他解释,但无论怎么解释都说我错。凭什么,作为面试官自己不了解相关技术,别人用这个方式work,凭什么还认为这个方法是错的,不接受面试者的解释。4.这个无可厚非,作为面试官,不打招呼就退出会议,把面试者晾着,本身就是有问题。综上所述,我现在不觉得第一第二点也是我的问题,面试官有很大的问题,就是专门恶心人的,总结面试官说教,不尊重面试者,打击面试者,不接受好的面试者,技术一般的守旧固执分子。有这种人部门有这种人怎么发展啊。最后去查了一下,岗位关闭了。也有可能是招到人了来恶心人的,但是也很cs
牛客20646354...:招黑奴啊,算法工程师一天200?
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务