Redis源码分析:服务器编程模型
来源:互联网 发布:oracle数据迁移工具 编辑:程序博客网 时间:2024/06/02 20:08
Base:redis 2.4.4
Update : redis 2.8.7
Reids基于事件驱动(Event-driven)构建服务。
Event-driven,提到这个,很容易想到如雷贯耳的libevent库(libeven封装了以下三种事件的响应:IO事件,定时器事件,信号事件)。
Redis的没有采用庞大的libevent库,而是自己写了一个,牺牲了一些平台通用性,但是性能非常强劲。memcache采用了libevent,有人认为这是redis的优于性能比memcache性能。没有系统性的测试过,此处保留意见。
其中ae_epoll.c中封装了epoll的实现
多路IO封装:
aeApiCreate:创建句柄(epoll_create)
aeApiFree:关闭句柄(close)
aeApiAddEvent:事件添加(epoll_ctl)
aeApiDelEvent:事件删除(epoll_ctl)
aeApiPoll:等待事件发生(epoll_wait)
服务处理:
1. 初始化server, 等待客户端连接,并注册事件,回调函数acceptTcpHandler/acceptUnixHandler
在监听到新连接请求时,接收连接,创建redisClient对象,并注册事件(回调函数readQueryFromClient)
在接收到客户端请求数据后,首先对请求进行分析,解析完成后反馈请求
在请求处理完成后,反馈结果.
Redis执行完客户端请求后,会调用addReply,在addReply中调用installWriteEvent来注册一个事件,并绑定事件处理函数sendReplyToClient,用来把响应发送到client。
4.主循环
处理定时事件和注册事件
rfileProc和wfileProc即注册事件时定义的回调函数
Update : redis 2.8.7
Reids基于事件驱动(Event-driven)构建服务。
Event-driven,提到这个,很容易想到如雷贯耳的libevent库(libeven封装了以下三种事件的响应:IO事件,定时器事件,信号事件)。
Redis的没有采用庞大的libevent库,而是自己写了一个,牺牲了一些平台通用性,但是性能非常强劲。memcache采用了libevent,有人认为这是redis的优于性能比memcache性能。没有系统性的测试过,此处保留意见。
x相关源码:ae.h ae.c networking.c anet.c net.h ae_epoll.c ae_select.c ae_kqueue.c
ae.h、ae.c :event library具体实现
networking.c : 与客户端的交互
anet.h anet.c : 网络通信
ae_epoll.c ae_select.c ae_kqueue.c : 不同系统多路IO封装
ae_epoll.c : linux平台
ae_select.c :unix平台
ae_kqueue.c : BSD、APPLE
根据操作系统进行多路IO类型选择,linux系统选择为epoll:
#ifdef __linux__#define HAVE_EPOLL 1#endif#if (defined(__APPLE__) && defined(MAC_OS_X_VERSION_10_6)) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined (__NetBSD__)#define HAVE_KQUEUE 1#endif#ifdef __sun#include <sys/feature_tests.h>#ifdef _DTRACE_VERSION#define HAVE_EVPORT 1#endif#endif
#ifdef HAVE_EVPORT#include "ae_evport.c"#else #ifdef HAVE_EPOLL #include "ae_epoll.c" #else #ifdef HAVE_KQUEUE #include "ae_kqueue.c" #else #include "ae_select.c" #endif #endif#endif
其中ae_epoll.c中封装了epoll的实现
多路IO封装:
aeApiCreate:创建句柄(epoll_create)
aeApiFree:关闭句柄(close)
aeApiAddEvent:事件添加(epoll_ctl)
aeApiDelEvent:事件删除(epoll_ctl)
aeApiPoll:等待事件发生(epoll_wait)
服务处理:
1. 初始化server, 等待客户端连接,并注册事件,回调函数acceptTcpHandler/acceptUnixHandler
if (server.ipfd > 0 && aeCreateFileEvent(server.el,server.ipfd,AE_READABLE, acceptTcpHandler,NULL) == AE_ERR) oom("creating file event"); if (server.sofd > 0 && aeCreateFileEvent(server.el,server.sofd,AE_READABLE, acceptUnixHandler,NULL) == AE_ERR) oom("creating file event");2. 回调函数acceptTcpHandler/acceptUnixHandler
在监听到新连接请求时,接收连接,创建redisClient对象,并注册事件(回调函数readQueryFromClient)
void readQueryFromClient(aeEventLoop *el, int fd, void *privdata, int mask) { ...... nread = read(fd, c->querybuf+qblen, readlen); ...... if (nread) { sdsIncrLen(c->querybuf,nread); c->lastinteraction = server.unixtime; if (c->flags & REDIS_MASTER) c->reploff += nread; } else { server.current_client = NULL; return; } ......}3. 客户端请求处理:
在接收到客户端请求数据后,首先对请求进行分析,解析完成后反馈请求
void processInputBuffer(redisClient *c) { while(sdslen(c->querybuf)) { ...... //分析请求 if (c->argc == 0) { resetClient(c); } else { if (processCommand(c) == REDIS_OK) resetClient(c); } }}
在请求处理完成后,反馈结果.
Redis执行完客户端请求后,会调用addReply,在addReply中调用installWriteEvent来注册一个事件,并绑定事件处理函数sendReplyToClient,用来把响应发送到client。
4.主循环
处理定时事件和注册事件
void aeMain(aeEventLoop *eventLoop) { eventLoop->stop = 0; while (!eventLoop->stop) { if (eventLoop->beforesleep != NULL) eventLoop->beforesleep(eventLoop); aeProcessEvents(eventLoop, AE_ALL_EVENTS); }}beforesleep通过aeSetBeforeSleepProc定义,主要是特殊处理vm和aof相关的请求
rfileProc和wfileProc即注册事件时定义的回调函数
- Redis源码分析:服务器编程模型
- Redis源码分析:服务器编程模型
- redis服务器模型分析
- redis服务器模型分析
- redis服务器模型分析
- redis服务器模型分析
- redis服务器模型分析
- redis源码分析 -- cs结构之服务器
- redis源码分析(1) 服务端网络链接模型
- redis服务器模型
- redis源码分析:主从模式中从服务器同步策略
- Redis网络库源码分析(2)之启动服务器
- nginx源码分析--高性能服务器开发 常见进程模型
- nginx源码分析--高性能服务器开发 常见进程模型
- Redis源码分析:AOF
- Redis源码分析:snapshot
- redis源码分析----序言
- Redis源码分析-TCMalloc
- 一个document.documentElement.clientWidth为0的问题
- Linux hostname
- 关于keil c51里面的 printf 函数
- 定时关机程序(恶搞版)---通过VC6.0+C语言+windows API实现
- 使用相对布局实现梅花图案的实例
- Redis源码分析:服务器编程模型
- Ext Js 3.2中Record的使用方法
- win7下设置音频设备实现录音的方法
- Struts2.0配置文件(web.xml)
- stringstream的用法
- tar命令的妙用
- 情商高的人比智商高的可怕多了
- Win32::IEAutomation包的认识
- 正则表达式基础字符匹配