【Redis分析 】之网络库分析

源码分析版本:4.0.1

文件结构

redis的网络通信模块由8个文件构成
在这里插入图片描述

作用如下

文件作用
ae.c统一epoll、evport、kqueue、select网络事件处理接口, 函数实现
ae.h统一epoll、evport、kqueue、select网络事件处理接口,函数原型,共享结构体定义
ae_epoll.c封装epoll网络事件处理库到统一的接口
ae_evport.c封装evport网络事件处理库到统一的接口
ae_kqueue.c封装kqueue网络事件处理库到统一的接口
ae_select.c封装select网络事件处理库到统一的接口

统一网络库底层接口

被统一的网络事件处理接口如下,参考:ae_epoll.c, ae_evport.c, ae_kqueue.c,ae_select.c

接口作用
aeApiState底层网络库需要的fd、事件等数据共享结构体
aeApiCreate创建网络句柄,比如epoll句柄,在这个基础上才能进行网络事件的监听处理
aeApiResize修改网络库存放事件的容器大小,就是修改aeApiState结构体的events数组的大小
aeApiFree删除aeApiState这个共享结构体
aeApiAddEvent将网络fd的读写操作交给网络库进行处理,比如给这个epoll进行处理
aeApiDelEvent从网络操作库中删除对某个fd的监听,一般服务器往客户端写完数据后,主动断开客户端连接时会使用
aeApiPoll轮询获取网络正在发生io读写事件的事件
aeApiName获取底层网络库的名字,比如epool,kqueue等

#统一网络库上层接口
参考 ae.h, ae.c,封装通用的结构体和函数

网络读写事件aeFileEvent结构体

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

这个结构体封装了网络数据读写事件的处理函数原型,和客户端传过来的数据。
aeFileProc是处理函数的原型的宏定义,宏定义参考如下:

typedef void aeFileProc(
    struct aeEventLoop *eventLoop,
    int fd,
    void *clientData,
    int mask
);

实际使用时,网络读写事件的函数处理需要自行编写

定时事件aeTimeEvent结构体

/* 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;

这个定时事件是redis用来处理后台定时任务使用的,比如处理客户端连接超时,服务端断开操作活跃的fd

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

就是正在等待读、正在等待写的网络fd,一般以一个数组出现
mask字段表示是等待读,还是等待写,对应的值如下

#define AE_READABLE 1
#define AE_WRITABLE 2

网络库上层接口核心结构体aeEventLoop

/* 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;
    aeBeforeSleepProc *aftersleep;
} aeEventLoop;

操作aeEventLoop相关函数

在这里插入图片描述

主要是对aeEventLoop结构体进行操作,这里拿几个核心的函数举例

aeCreateEventLoop()

这个函数主要是创建aeEventLoop结构体,并根据setsize参数给events, fired分配内容空间然后再调用aeApiCreate驱动底层的网络库,比如epoll的epoll_create(),然后保存到aeEventLoop的apidata属性上

aeMain()

主要是启动无限循环、轮询处理活跃的fd,如果epoll,底层则调用epoll_wait获取可读写的fd:ae.c::aeMain() -> ae.c::aeProcessEvents() -> ae_epoll.c::aeApiPool() -> ae_epoll.c::epoll_wait()

aeCeateFileEvent()

注册网络fd到底层网络库上,并注册当读写事件发生时,需要执行的业务回调函数拿epoll举例,调用到epoll经过的步骤:ae.c::aeCreateFileEvent() -> ae_epoll.c::aeApiAddEvent() -> epoll_ctl()

anet.h & anet.c

主要是封装socket操作,屏蔽系统底层socket操作的差异性,提供更好用的api,比如创建tcp server等

在这里插入图片描述
这里就拿创建tcp server来看看它的流程

anetTcpServer()

anet.c::anetTcpServer() -> anet.c::_anetTcpServer() -> <sys/socket.h>::socket() -> anet.c::anetListen() -> <sys/socket.h>::listen()
核心代码就是调用系统socket库的listen函数建立起了一个tcp的server
在这里插入图片描述

参考资料:

http://qiankunli.github.io/2018/06/15/redis.html
https://juejin.cn/post/6844903909387927560

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值