• redis的文件事件处理器


    前言
        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驱动允许同时监听可读和可写事件,同时发生时先处理可读事件,再处理可写事件。
  • 相关阅读:
    【全过程详解】如何恢复联想隐藏的内存(分区教程)
    【全过程详解】如何安装最纯净、稳定、无更新的win10系统(下载+U盘制作+安装+win10激活+驱动更新)
    第一次博客
    Spring boot 直接访问templates中html文件
    Spring boot + mybatis + orcale
    Spring boot+ maven + thymeleaf + HTML 实现简单的web项目
    HTML 中点击<a>标签,页面跳转执行过程
    orcale 使用创建日期排序然后分页每次取排序后的固定条数
    JSON语法规则
    Windows idea 搜狗输入法输入中文只显示英文
  • 原文地址:https://www.cnblogs.com/learn-my-life/p/5636438.html
Copyright © 2020-2023  润新知