• 基于redis AE异步网络架构


    最近的研究已redis源代码,redis高效率是令人钦佩。

    在我们的linux那个机器,cpu型号, 

    Intel(R) Pentium(R) CPU G630 @ 2.70GHz
     Intel(R) Pentium(R) CPU G630 @ 2.70GHz


    上 set,get 都能达到每秒钟15W的请求处理量,真是佩服这代码的效率。

    前几篇文章。主要是介绍了主要的代码。比方字符串处理,链表处理。hash等。

    这篇文章介绍网络的核心,基于事件反映的异步网络框架。


    异步网络处理。是基于epoll的。epoll的分为两种模式。水平触发和边缘触发。ae使用了水平触发,就是一旦有数据,epoll会一直通知,直到就读取完毕。而边缘触发则仅仅通知一次。

    等到状态改变才会去通知。

    详细能够到网上查阅。

    1.结构体源代码解析

    1.1读写事件结构体

    /* File event structure */
    typedef struct aeFileEvent {
        int mask; /* one of AE_(READABLE|WRITABLE) */
        aeFileProc *rfileProc;
        aeFileProc *wfileProc;
        void *clientData;
    } aeFileEvent;
    

    该结构体表示一个fd相应的事件处理函数和私有数据。当我们要注冊一个fd时间时。就会填充该结构体。

    1.2 时间事件狗狗提

    /* Time event structure */
    typedef struct aeTimeEvent {
        long long id; /* time event identifier. */
        long when_sec; /* seconds */
        long when_ms; /* milliseconds */
        aeTimeProc *timeProc;
        aeEventFinalizerProc *finalizerProc;
        void *clientData;
        struct aeTimeEvent *next;
    } aeTimeEvent;
    

    当我们注冊定时处理事件。会填充对应结构体,加入到数组里

    1.3 触发的fd

    /* A fired event */
    typedef struct aeFiredEvent {
        int fd;
        int mask;
    } aeFiredEvent;
    

    该结构体表示一个fd相应的可读可写事件

    1.4 ae事件的总结构体

    /* State of an event based program */
    typedef struct aeEventLoop {
        int maxfd;   /* highest file descriptor currently registered */
        int setsize; /* max number of file descriptors tracked */
        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异步事件的基本数据,比方fd大小。时间事件id,注冊的时间指针等。


    2.ae_epoll 接口

    2.1 epoll 结构体

    typedef struct aeApiState {
        int epfd;
        struct epoll_event *events;
    } aeApiState;

    提供epoll的变量定义,

    epfd是通过epoll_create 创建。events表示epoll_wait同意监听的数量。

    填充aeApiState结构体。

    static int aeApiCreate(aeEventLoop *eventLoop)


    调用epoll_wait ,获取我们关心的事件,

    static int aeApiPoll(aeEventLoop *eventLoop, struct timeval *tvp) 



    2、api接口


    1。创建eventloop

    aeEventLoop *aeCreateEventLoop(int setsize)

    2.加入事件

    int aeCreateFileEvent(aeEventLoop *eventLoop, int fd, int mask,
            aeFileProc *proc, void *clientData)

    3。

    删除事件,

    void aeDeleteFileEvent(aeEventLoop *eventLoop, int fd, int mask)

    4。

    创建时间事件

    long long aeCreateTimeEvent(aeEventLoop *eventLoop, long long milliseconds,
            aeTimeProc *proc, void *clientData,
            aeEventFinalizerProc *finalizerProc)

    5.删除时间事件

    int aeDeleteTimeEvent(aeEventLoop *eventLoop, long long id)




    使用演示样例


      //创建loop
        proxy.eventLoop = aeCreateEventLoop(DEFAULT_LOOP_SIZE);

    //创建事件事件

    if(aeCreateTimeEvent(proxy.eventLoop, 1, serverCron, NULL, NULL) == AE_ERR) 
    {
    printf("Can't create the serverCron time event ");
    exit(1);
    }


         /* server监听redisclient的连接 */
         aeCreateFileEvent(proxy.eventLoop, proxy.server_fd, AE_READABLE, on_client_connected, NULL);

       aeCreateFileEvent(proxy.eventLoop, proxy.evfd, AE_READABLE, reconnect_redis, NULL);



    以上就是一个简单的演示样例。

    我写了一个类redisprox的东西,待我上传给大家看看。









    版权声明:本文博主原创文章。博客,未经同意不得转载。

  • 相关阅读:
    通过this调用本类属性和本类方法
    使用构造方法接收引用数据类型
    JAVA回形数
    Bt(宝塔面板)忘记用户名密码的解决方案
    关于xshell远程连接密码呈现灰色无法填写的问题
    ubunt系统创建定时任务
    阿里云服务器如何初始化
    解决laravel 配置路由时除 “/”路由 以外 ,所有路由访问不到的情况
    laravel 5.2 使用 captcha 实现 验证码
    在laravel中如何使用事务
  • 原文地址:https://www.cnblogs.com/hrhguanli/p/4847247.html
Copyright © 2020-2023  润新知