开发者社区> nothingfinal> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

Redis源码解析--NET

简介:     关于Redis资料:     要看原滋原味的请点这里,要看有我参与的山寨货请点这里,当然我也不反对看这里。     在接下来的日子里,我会记录下我对Redis源码的一些认识,首先从Event driven programming library开始,没有理由,如果有:那就是redis.h包含的非系统头文件从#include "ae.h"开始,本系列文章以redis-2.6.0-rc3版源码为基准,言归正传吧。
+关注继续查看

    关于Redis资料:

    要看原滋原味的请点这里,要看有我参与的山寨货请点这里,当然我也不反对看这里

    在接下来的日子里,我会记录下我对Redis源码的一些认识,首先从Event driven programming library开始,没有理由,如果有:那就是redis.h包含的非系统头文件从#include "ae.h"开始,本系列文章以redis-2.6.0-rc3版源码为基准,言归正传吧。

 

一、NET分层

    Redis 网络部分主要分四层:

1 NET分层图

1、  TCP/Unix Socket层(Anet.h117)、Anet.c405))

1socket创建

    anetCreateSocket:创建TCP/Unix socket,设置socket SO_REUSEADDR

2socket属性设置

    anetTcpNoDelay:设置是否关闭Nagle算法,Nagle算法作用点这里

    anetNonBlock:设置阻塞还是非阻塞。

    anetTcpKeepAlive:设置是否开启协议栈心跳,协议栈心跳作用点这里

    anetSetSendBuffer:设置发送buffer大小。

3Connect

    anetTcpGenericConnectTCP Connect原始接口封装,输入IP地址和阻塞/非阻塞参数。

    anetTcpConnectTCP阻塞连接。

    anetTcpNonBlockConnectTCP非阻塞连接。

    anetUnixGenericConnectUnix Connect原始接口封装,输入IP地址和阻塞/非阻塞参数。

    anetUnixConnectUnix阻塞连接。

    anetUnixNonBlockConnectUnix非阻塞连接。

4Listen

    anetListenbindlisten511原因请查Nginx)封装。

    anetTcpServer:调用anetCreateSocketanetListen监听连接到来。

    anetUnixServer:调用anetCreateSocketanetListen监听连接到来。

5Accept

    anetGenericAcceptaccept封装,while直到accept成功或失败才返回。

    anetTcpAccept:调用anetGenericAccept,返回fd,带回IPPort(函数参数)或错误。    

    anetUnixAccept:调用anetGenericAccept,返回fd,或带回错误(函数参数)。

6IPhost互转

    anetPeerToString:由IPAddress->Host

    anetResolve:由Host->IPAddresss

7)格式化error

    anetSetError:变长参数格式化,函数参数带回格式化后error信息。

2、  I/O模型层(Ae_select.c72)、Ae_epoll.c101)、Ae_kqueue.c105))

    三者都有统一的接口,功能大体类似,但也有细节差别,以epoll(参看这里)为蓝本解析如下:

    aeApiState:包含epoll fd句柄和Event指针的structepollkqueue基本一致,而selectrfdswfds集合及副本,具体见Ae_select.c代码第7~12行。

    aeApiCreate:创建aeApiState,并以此初始化aeEventLoop(作用见后文)。epoll_create参数采用Linux kernelhint1024

    aeApiFreeclose epoll fd句柄,释放mallocaeApiStateaeEventLoop

    aeApiAddEvent:通过mask修改或者添加fd对应EventEPOLLINEPOLLOUTepoll_ctl)。

    aeApiDelEvent:通过mask修改或者删除fd对应EventEPOLLINEPOLLOUTepoll_ctl)。

    aeApiPollepoll_wait等待内核返回事件集合,填写fire事件集合用于回调AE_READABLEAE_WRITABLE对应函数。

    aeApiName:取得I/O模型字符串名称("select""epoll""kqueue")。

3、  EventLoop层(Ae.h117)、Ae.c405))

1)回调函数指针

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

    typedef int aeTimeProc(struct aeEventLoop *eventLoop, long long id, void *clientData);

    typedef void aeEventFinalizerProc(struct aeEventLoop *eventLoop, void *clientData);

    typedef void aeBeforeSleepProc(struct aeEventLoop *eventLoop);

2Event Struct

    aeFileEvent:读写事件回调。

    aeTimeEvent:定时器事件回调。

    aeFiredEvent:触发事件回调。

    aeEventLoop:主事件,包含读写事件、定时器事件、触发事件列表。

3Event接口API

    aeCreateEventLoop:创建EventLoop

    aeDeleteEventLoop:删除EventLoop

    aeStop:置EventLoop stop标志。

    aeCreateFileEvent:添加关注事件。

    aeDeleteFileEvent:删除关注事件。

    aeGetFileEvents:获取事件mask

    aeGetTime:获取当前时间。

    aeAddMillisecondsToNow:增加毫秒数当前时间的秒和毫秒上。

    aeCreateTimeEvent:添加定时器事件。

    aeDeleteTimeEvent:删除定时器事件。

    SearchNearestTimer:搜索最近的定时器。

    processTimeEvents:处理定时器事件,回调函数返回AE_NOMORE(-1)则删除定时器,否则更新定时器时间为回调函数返回的时间。

    aeProcessEvents:处理各种事件,用最近定时器即将到来的时间作为epoll_wait的超时间,非常巧妙,如果马上到就立即返回,否则超时间到再返回。

    aeMain:主mainwhile循环直到eventLoop->stop不为0,在调用aeProcessEvents前,先回调aeBeforeSleepProc

    aeGetApiName:获取I/O模型字符串名称("select""epoll""kqueue")。

    aeSetBeforeSleepProc:设置aeBeforeSleepProc回调函数。

4、  Networking层(Networking.c1334))

    暂不表与网络层无直接关系的接口函数。

    createClient:创建redisClient,有连接则设置fdnonblocking,设置TCP_NODELAY,设置AE_READABLE对应的回调函数readQueryFromClient

    prepareClientToWrite:在发送数据给客户端时的预处理,即可以发送数据时设置AE_WRITABLE对应的回调函数sendReplyToClient;是REDIS_LUA_CLIENT时返回REDIS_OK;是fake client或者slave或者setup write handler failed时返回REDIS_ERR

    acceptCommonHandler:调用createClient,校验是否达到最大客户端数。

    acceptTcpHandler:针对TCP依次调用anetTcpAcceptacceptCommonHandler

    acceptUnixHandler:针对Unix,作用同acceptTcpHandler

    freeClient:释放redisClient,删除AE_READABLEAE_WRITABLE,断开master/slave,清除MULTI/EXEC state等。

    sendReplyToClient:发送数据的回调函数,处理write逻辑。

    readQueryFromClient:接收数据的回调函数,处理read逻辑。

    还有一大票addReply…get…,在此略去。

 

二、NET流程

    以redis-cli 从redis-server get数据为例来描述整体流程。

图2 流程图

    

    打完收工,。。。



版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
Redis之集群环境搭建
前面文章介绍了Redis的主从复制,虽然该模式能够在一定程度上提高系统的稳定性,但是在数据访问量比较大的情况下,单个master应付起来还是比较吃力的,这时我们可以考虑将redis集群部署,本文就来重点给大家介绍下Redis的集群部署操作。
118 0
Redis简单集群配置
参考链接为:http://blog.csdn.net/u014230881/article/details/71123494 比较系统学习和熟练使用Redis命令可参考该教程:http://www.runoob.
991 0
redis 主从、sentinel、集群 搭建
redis 主从、sentinel、集群 搭建 编辑:王振威 日期:2018/07/09 ==前言:== 1、本文介绍redis 主从、哨兵、集群模式的linux(centos7.2)搭建。
3679 0
redis集群搭建
redis集群搭建 Redis集群的搭建Redis集群中至少应该有三个节点。要保证集群的高可用,需要每个节点有一个备份机。 Redis集群至少需要6台服务器。 搭建伪分布式。可以使用一台虚拟机运行6个redis实例。
1788 0
Redis集群搭建
Redis集群搭建
16710 0
redis集群搭建
  Redis 是一个开源的 key-value 存储系统,由于出众的性能,大部分互联网企业都用来做服务器端缓存。Redis 在3.0版本前只支持单实例模式,虽然支持主从模式、哨兵模式部署来解决单点故障,但是现在互联网企业动辄大几百G的数据,可完全是没法满足业务的需求,所以,Redis 在 3.0 版本以后就推出了集群模式。
2210 0
搭建Redis集群
为什么要有集群  上一篇随笔说了基本的主从概念以及搭建,一主可以有多从,如果同时访问的量过大(1000w)或者发生自然灾难,主服务肯定就会挂掉,数据服务就挂掉了 大公司都会有很多的服务器(华东地区、华南地区、华中地区、华北地区、西北地区、西南地区、东北地区、台港澳地区机房) 集群的概念 集群是一组相互独立的、通过高速网络互联的计算机,它们构成了一个组,并以单一系统的模式加以管理。
1520 0
Redis 复制与集群
<div class="markdown_views"> <h2 id="复制">复制</h2> <p>为提高高可用性,排除单点故障,redis支持主从复制功能。 <br> 其整体结构是一个有向无环图。</p> <h3 id="同步方式">同步方式</h3> <p>分为两种:</p> <ul> <li>全同步 <br> 全同步是第一次从机连主机是进行的同步,主机会生
2089 0
+关注
nothingfinal
软件开发,安全加密
1068
文章
341
问答
文章排行榜
最热
最新
相关电子书
更多
低代码开发师(初级)实战教程
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载
冬季实战营第三期:MySQL数据库进阶实战
立即下载