前言
    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. PrintWriter的println问题

    今天发现一个奇怪的问题,同样的代码web server部署在windows自测机器上跟linux服务器上, 在通信上出现了不一样的换行结束符. Debug发现通过PrintWriter的println ...

  2. 【转】uboot移植(一)BootLoader基本概念

    原文网址:http://blog.chinaunix.net/uid-25445243-id-3869348.html 一.BootLoader简介1.1.嵌入式Linux软件结构与分布 在一般情况下 ...

  3. Lists

    List类主要提供了对List类的子类构造以及操作的静态方法.在类中支持构造ArrayList.LinkedList以及newCopyOnWriteArrayList对象的方法.其中提供了以下构造Ar ...

  4. Cocos2d-android (02) 添加一个精灵对象

    什么是精灵: 1.精灵就是游戏当中的一个元素,通常用于代表画面当前中的一个事物,例如主人公,NPC和背景元素等: 2.一个精灵对象通常都与一张图片关联 3.精灵对象可以通过动作对象(CCAction) ...

  5. vector容器总结.xml

    1 清空所有元素     m_itemVector.clear();   2 遍历     vector<ITEM_CHECK>::iterator iter=m_itemVector.b ...

  6. 大数据处理-bitmap是个神马东西

    1. Bit Map算法简介 所谓的Bit-map就是用一个bit位来标记某个元素对应的Value, 而Key即是该元素.由于采用了Bit为单位来存储数据,因此在存储空间方面,可以大大节省. 2. B ...

  7. PHP 解压zip文件的函数封装

    /** * zip文件解压 * * @param $zipFilePath zip文件的路径,可以不加zip文件后缀.如果其他类型的文件伪装成zip解压也会失败 * @param $directory ...

  8. linq数据使用

    取出数据库满足条件的记录的ID,把值放到list中 ) { int userid = Convert.ToInt32(Request.Cookies["id"].Value); v ...

  9. Java多线程学习总结--线程同步(2)

    线程同步是为了让多个线程在共享数据时,保持数据的一致性.举个例子,有两个人同时取钱,假设用户账户余额是1000,第一个用户取钱800,在第一个用户取钱的同时,第二个用户取钱600.银行规定,用户不允许 ...

  10. Jquery 遍历表单 AJAX提交

    function test(){ var arrayObj = new Array(); $("#contentTable tbody tr").each(function(){ ...