文档章节

Redis——事件

nao
 nao
发布于 2016/05/18 19:46
字数 1842
阅读 140
收藏 10

问题:
    Redis 是单线程的,怎么实现的多个客户端的连接访问?

    Redis服务器是一个事件驱动程序,服务器需要处理一下两类事件:
    * 文件事件(file event): Redis服务器通过套接字与客户端(或者其他Redis服务器)进行连接,而文件事件就是服务器对套接字操作的抽象。服务器与客户端(或者其他服务器)的通信会产生相应的文件事件,而服务器则通过监听并处理这些事件来完成一系列网络通信操作。
    
    * 时间事件(time event):Redis服务器中的一些操作(比如 serverCon)函数需要在给定的时间点执行,而时间事件就是服务器对这类定时操作的抽象。


文件事件
    Redis基于Reactor模式开发了自己的网络事件处理器:这个处理器被称为文件事件处理器(five event handler)
    * 文件事件处理器使用I/O多路复用(multiplexing)程序来同时监听多个套接字,并根据套接字目前执行的任务来为套接字关联不同的事件处理器。
    * 当监听的套接字准备好执行连接应答(accept),读取(read),写入(write),关闭(close)等操作时,与操作相对应的文件事件就会产生,这时文件事件处理器就会调用套接字之前关联好的事件处理器来处理这些事件。
    虽然文件事件处理器以单线程方式运行,但通过使用I/O多路复用程序来监听多个套接字,文件事件处理器既实现了高性能的网络通信模型,又可以很好地与Redis服务器中其他同样以单线程方式运行的模块进行对接,这保持了Redis内部单线程设计的简单性。

文件事件处理器的构成

    文件事件处理器的四个组成部分,它们分别是套接字,I/O多路复用程序,文件事件分派器(dispatcher),以及事件处理器。

文件事件是对套接字操作的抽象,每当一个套接字准备好执行连接应答(accept),写入,读取,关闭等操作时,就会产生一个文件事件。因为一个服务器通常会连接多个套接字,所以多个文件事件有可能会并发地出现。

    I/O 多路复用程序负责监听多个套接字,并向文件事件分派器传送那些产生了事件的套接字。

    尽管多个文件事件可能会并发地出现,但I/O多路复用程序总是会将所有产生事件的套接字都放在一个队列里面,然后通过这个队列,以有序(sequentially)、同步(synchronoously)、每次一个套接字的方式向文件事件分派器传送套接字。当上一个套接字产生的事件处理完毕之后(该套接字为事件处理完毕),I/O多路复用程序才会继续向文件事件分派器传送下一个套接字。

文件事件分派器接收I/O多路复用程序传来的套接字,并根据套接字产生的事件的类型,调用相应的时间处理器。

 服务器会执行不同任务的套接字关联不同的事件处理器,这些处理器是一个个函数,它们定义了某个事件发生时,服务器应该执行的动作。

I/O多路复用程序的实现:


时间事件
 Redis的时间事件分为以下两类:
    * 定时事件:让一段程序在指定的时间之后执行一次。比如说:让程序X在当前时间的30毫秒之后执行一次。
    * 周期性事件:让一段程序每隔指定时间就执行一次。比如说:让程序Y每隔30毫秒就执行一次。
 一个时间事件主要由以下三个属性组成:
    * id: 服务器为时间事件创建的全局唯一ID(标识号)。ID号按从小到大的顺序递增,新事件ID号比旧事件的ID号要大。
    * when:毫秒精度的UNIX时间戳,记录了时间事件的到达(arrive)时间。
    * timeproc: 时间事件处理器,一个函数。当时间事件到达时,服务器就会调用相应的处理器  来处理事件。
一个时间事件是定时器事件还是周期性事件取决于时间事件处理器的返回值:
    * 如果事件处理器返回ae.h/AE_NOMORE,那么这个事件为定时事件:该事件在达到一次之后会被删除,之后不再到达。
    * 如果事件处理器返回一个非AE_NOMORE的整数值,那么这个事件为周期性事件:当一个时间事件到达之后,服务器会根据事件处理器返回的值,对时间事件的when属性进行更新,让这个事件在一段时间之后再次到达,并以这种方式一直更新并运行下去。比如说,如果一个时间事件的处理器函数返回整数值30,那么服务器应该对这个事件进行更新,让这个事件在30毫秒之后再次到达。


    实现:
    服务器将所有时间事件都放在一个无序链表中,每当时间事件执行器运行时,它就遍历整个链表,查找所有已到达的时间事件,并调用相应的事件处理器。

                               无序列表并不影响时间事件处理器的性能
    在目前版本中,正常模式下的Redis服务器只使用serverCron一个时间事件,而在benchmark模式下,服务器也只使用两个时间事件。这种情况下,服务器几乎是将无序链表退化成一个指针来使用,所以使用无序链表来保存时间事件,并不影响事件执行的性能。


总结
    * Redis服务器是一个事件驱动程序,服务器处理的事件分为时间事件和文件事件两类。
    * 文件事件处理器是基于Reactor模式实现的网络通信程序。
    * 文件事件是对套接字操作的抽象:每次套接字变为可应答(acceptable),可写(writeable)或者可读(readable)时,相应的文件事件就会产生。
    * 文件事件分为AE_READABLE(读事件)和AE_WRITEABLE事件(写事件)两类。
    * 事件时间可以分为定时事件和周期性事件:定时事件只在指定的时间到达一次,而周期性事件则每隔一段时间到达一次。
    * 服务器在一般情况下只执行serverCorn函数一个时间事件,并且这个事件是周期性事件。
    * 文件事件和时间事件之间是合作关系,服务器会轮流处理这两种事件,并且处理事件的过程中也不会进行抢占。
    * 时间事件的实际处理时间通常会比设定的达到时间晚一些。

© 著作权归作者所有

上一篇: Redis——客户端
下一篇: Redis——复制
nao

nao

粉丝 27
博文 155
码字总数 108154
作品 0
成都
后端工程师
私信 提问
并发服务器:Redis案例研究分析

1.事件处理库 Redis 最初发布于 2009 年,它最牛逼的一件事情大概就是它的速度 —— 它能够处理大量的并发客户端连接。需要特别指出的是,它是用一个单线程来完成的,而且还不对保存在内存中...

问题终结者
2018/06/03
0
0
Node+Websocket之消息未读功能实战

前言 github.com/hua1995116/… 这个项目本来是我学生时代为了找工作的一个练手项目,但是没想到受到了很多的关注,star也快要破K了,这也激励着我不断去完善他,一方面是得对得起关注学习的...

蓝色的秋风
2018/11/19
0
0
Redisbook学习笔记(1)双端链表

双端链表作为一种通用的数据结构在Redis 内部使用得非常多它既是Redis 列表结构的底 层实现之一还被大量Redis 模块所使用用于构建Redis 的其他功能。 对列表类型的键进行操作——比如执行 RP...

技术小美
2017/11/17
0
0
太无奈!Redis 作者被迫修改 master-slave 架构的描述

相信在座各位的开发者都不会对 Redis 的主从模式(master-slave)感到陌生。Redis 中的主从模式事实上也是源自 MySQL 中同名的一个概念,是同步数据的一种手段。在这样的场景下,master-slave ...

局长
2018/09/10
0
59
Redis 总结精讲 看一篇成高手系统-4

本文围绕以下几点进行阐述 1、为什么使用redis 2、使用redis有什么缺点 3、单线程的redis为什么这么快 4、redis的数据类型,以及每种数据类型的使用场景 5、redis的过期策略以及内存淘汰机制...

kuchawyz
2018/07/02
0
0

没有更多内容

加载失败,请刷新页面

加载更多

在Javascript中Eval函数的使用

【eval()函数】 JavaScript有许多小窍门来使编程更加容易。 其中之一就是eval()函数,这个函数可以把一个字符串当作一个JavaScript表达式一样去执行它。 举个小例子: var the_unevaled_ans...

花漾年华
20分钟前
3
0
[日更-2019.5.22、23] Android 系统的分区和文件系统(二)--Android 文件系统中的文件

声明 Android系统中有很多分区,每个分区内的文件系统一般都不同的,使用ADB进入系统/目录下可发现挂载这很多的目录,不同的目录中可来自不同的分区及文件系统; 那么,就来分下这些目录里面...

小馬佩德罗
24分钟前
2
0
数组操作相关算法

/*数组的相关的算法操作:1、在数组中找最大值/最小值*/class Test11_FindMax{public static void main(String[] args){int[] array = {4,2,6,8,1};//在数组中找最大...

architect刘源源
今天
3
0
okhttp3 以上版本在安卓9.0无法请求数据的解决方案

应用官方的说明:在 Android 6.0 中,我们取消了对 Apache HTTP 客户端的支持。 从 Android 9 开始,默认情况下该内容库已从 bootclasspath 中移除且不可用于应用。且Android P 限制了明文流量...

chenhongjiang
今天
12
0
简单示例:NodeJs连接mysql数据库

开篇引用网上的说法: 简单的说 Node.js 就是运行在服务端的 JavaScript。Node.js 是一个基于Chrome JavaScript 运行时建立的一个平台。Node.js是一个事件驱动I/O服务端JavaScript环境,基于...

李朝强
今天
8
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部