前言
    C10K problem提出了一个问题,如果1w个客户端连接到server上,间歇性的发送消息,有哪些好的方案?
    其中的一种方案是,每个线程处理多个客户端,使用异步I/O和就绪通知机制,redis无疑是一个很好的榜样
redis的特点和C10K proble的契合点
    内存数据库;
    单线程支持上w个客户端连接;
    高并发,单机支持10w并发数;
    低时延,局域网内大多数时延低于3ms。
redis的文件事件处理器

四个关键组成
    套接字、I/O多路复用、文件事件分发器、事件处理器。
    这是一个典型的reactor设计模式,redis没有采用现有的事件驱动库,比如libev等,而是自己定义了一个ae驱动器。
    使用epoll同时监听多个套接字,并给不同套接字关联不同的处理程序。
    当被监听的套接字准备好连接应答、请求、应答、关闭等操作时,对应的文件事件就会产生,文件事件处理器会调用对应的处理程序。
I/O多路复用和文件事件分派器的实现
epollI/O多路复用的封装
ae_epoll.c
创建epoll实例和事件槽
aeApiCreate
释放epoll实例和事件槽
aeApiFree
给fd新增或者修改关注事件
aeApiAddEvent
删除fd关注的事件
aeApiDelEvent
获取可执行事件
aeApiPoll
ae.h
文件事件处理器的实例
typedef struct aeEventLoop {
    // 目前已注册的最大描述符
    int maxfd;   /* highest file descriptor currently registered */
    // 目前已追踪的最大描述符
    int setsize; /* max number of file descriptors tracked */
    // 用于生成时间事件 id
    long long timeEventNextId;
    // 最后一次执行时间事件的时间
    time_t lastTime;     /* Used to detect system clock skew */
    // 已注册的文件事件
    aeFileEvent *events; /* Registered events */
    // 已就绪的文件事件
    aeFiredEvent *fired; /* Fired events */
    // 时间事件
    aeTimeEvent *timeEventHead;
    // 事件处理器的开关
    int stop;
    // 多路复用库的私有数据
    void *apidata; /* This is used for polling API specific data */
    // 在处理事件前要执行的函数
    aeBeforeSleepProc *beforesleep;
} aeEventLoop;
文件事件处理器以及文件事件分派器的实现
ae.c
初始化文件事件处理器
aeCreateEventLoop
删除事件处理器
aeDeleteEventLoop
停止事件处理器
aeStop
创建文件事件处理器
aeCreateFileEvent
删除文件事件处理器
aeDeleteFileEvent
获取监听的事件类型
aeGetFileEvents
文件事件分派器,调用aePoll获取激活的事件,并调用事件对应的文件处理器来处理这些事件
aeProcessEvents

redis的I/O事件处理器
创建连接处理程序
aeCreateFileEvent(server.el, server.ipfd[j], AE_READABLE, acceptTcpHandler,NULL)
创建请求处理程序
aeCreateFileEvent(server.el,fd,AE_READABLE, readQueryFromClient, c)
创建应答处理程序,当命令回复完毕,解除套接字和事件的关联
aeCreateFileEvent(server.el, c->fd, AE_WRITABLE, sendReplyToClient, c)
ae驱动的事件类型
// 可读
#define AE_READABLE 1
// 可写
#define AE_WRITABLE 2
    当客户端发起连接、断开连接、发送请求时,套接字产生AE_READABLE事件
    当套接字变得可写(客户端调用read操作)时,套接字产生AE_WRITABLE事件。
ae驱动的事件处理顺序
    ae驱动允许同时监听可读和可写事件,同时发生时先处理可读事件,再处理可写事件。

redis的文件事件处理器的更多相关文章

  1. redis的文件事件

    redis的文件事件:即与io相关的事件. /* File event structure */ typedef struct aeFileEvent { int mask; /* one of AE ...

  2. Redis 源码简洁剖析 16 - 客户端

    整体概述 客户端属性 套接字描述符 标志 输入缓冲区 命名及命令参数 命令的实现函数 输出缓冲区 客户端的创建与关闭 创建普通客户端 关闭普通客户端 参考链接 Redis 源码简洁剖析系列 整体概述 ...

  3. Redis学习笔记二:单机数据库的实现

    1. 数据库 服务器中的数据库 Redis服务器将所有数据库都保存在服务器状态redis.h/redisServer结构的db数组中,db数组的每个项都是一个redis.h/redisDb结构,每个r ...

  4. Redis设计与实现-客户端服务端与事件

    事件 redis服务器是事件驱动的,事件分为文件事件与时间事件 文件事件是服务器通过套接字与客户端连接,两者之间的通信会产生相应的文件事件,服务器监听并处理这些事件完成网络操作: 时间事件是指redi ...

  5. redis主从 哨兵

    entinel是redis高可用的解决方案,sentinel系统(N个sentinel实例,N >= 1)可以监视一个或者多个redis master服务,以及这些master服务的所有从服务: ...

  6. Redis 数据结构与内存管理策略(下)

    Redis 数据结构与内存管理策略(下) 标签: Redis Redis数据结构 Redis内存管理策略 Redis数据类型 Redis类型映射 Redis 数据类型特点与使用场景 String.Li ...

  7. 深入学习Redis(3):主从复制

    前言 在前面的两篇文章中,分别介绍了Redis的内存模型和Redis的持久化. 在Redis的持久化中曾提到,Redis高可用的方案包括持久化.主从复制(及读写分离).哨兵和集群.其中持久化侧重解决的 ...

  8. 从零单排学Redis【黄金】

    前言 只有光头才能变强 好的,今天我们要上黄金段位了,如果还没经历过青铜和白银阶段的,可以先去蹭蹭经验再回来: 从零单排学Redis[青铜] 从零单排学Redis[白银] 看过相关Redis基础的同学 ...

  9. Redis 和 I/O 多路复用

    最近在看 UNIX 网络编程并研究了一下 Redis 的实现,感觉 Redis 的源代码十分适合阅读和分析,其中 I/O 多路复用(mutiplexing)部分的实现非常干净和优雅,在这里想对这部分的 ...

随机推荐

  1. linux下安装虚拟机qemu kqemu

    一,为什么要装虚拟机,为什么选择qemu 我的系统里面有3个linux系统,这些系统都是独立的,有的时候,我想一台电脑,能更真实的模拟二台,这个时候我们就可以装个虚拟机.其实如果真的很有钱的话,可能考 ...

  2. HDU 4627 The Unsolvable Problem 2013 Multi-University Training Contest 3

    给你一个数 n ( 2 <= n <= 109 ),现在需要你找到一对数a, b (a + b = n),并且使得LCM(a, b)尽可能的大,然后输出最大的 LCM(a, b). (为什 ...

  3. Python time mktime()方法

    描述 Python time mktime() 函数执行与gmtime(), localtime()相反的操作,它接收struct_time对象作为参数,返回用秒数来表示时间的浮点数. 如果输入的值不 ...

  4. MySQL与Oracle 差异比较之四条件循环语句

    循环语句 编号 类别 ORACLE MYSQL 注释 1 IF语句使用不同 IF iv_weekly_day = 'MON' THEN       ii_weekly_day := 'MON';ELS ...

  5. Java把长整型时间转成字符串日期

    数据库里存放的是timestamp格式,前端取得后是这种:1436255550710长整型时间截转换成"2015-07-07"这种格式呢? import java.io.IOExc ...

  6. DataTable反向模糊匹配查找语法

    正向写法: string filter = "code like '%"+sheetname+"%'"; filter值为: code like '%表F.3_ ...

  7. JSON和JSONP有哪些区别,PhoneGap跨域请求如何实现

    前言 由于Sencha Touch 2这种开发模式的特性,基本决定了它原生的数据交互行为几乎只能通过AJAX来实现. 当然了,通过调用强大的PhoneGap插件然后打包,你可以实现100%的Socke ...

  8. 嵌入式 C 语言的可变参数表函数的设计

    首先在介绍可变参数表函数的设计之前,我们先来介绍一下最经典的可变参数表printf函数的实现原理.一.printf函数的实现原理在C/C++中,对函数参数的扫描是从后向前的.C/C++的函数参数是通过 ...

  9. 把一个窗体嵌入到WinForm中进行显示,以CMD窗口为例

    1.添加引用 using System.Runtime.InteropServices; 2. 加入以下代码段 [DllImport("User32.dll ", EntryPoi ...

  10. 【LeetCode 236】Lowest Common Ancestor of a Binary Tree

    Given a binary tree, find the lowest common ancestor (LCA) of two given nodes in the tree. According ...