Redis源码解析--NET

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介:     关于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数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
|
2月前
|
监控 网络协议 Java
Tomcat源码解析】整体架构组成及核心组件
Tomcat,原名Catalina,是一款优雅轻盈的Web服务器,自4.x版本起扩展了JSP、EL等功能,超越了单纯的Servlet容器范畴。Servlet是Sun公司为Java编程Web应用制定的规范,Tomcat作为Servlet容器,负责构建Request与Response对象,并执行业务逻辑。
Tomcat源码解析】整体架构组成及核心组件
|
2月前
|
缓存 NoSQL Java
Redis深度解析:解锁高性能缓存的终极武器,让你的应用飞起来
【8月更文挑战第29天】本文从基本概念入手,通过实战示例、原理解析和高级使用技巧,全面讲解Redis这一高性能键值对数据库。Redis基于内存存储,支持多种数据结构,如字符串、列表和哈希表等,常用于数据库、缓存及消息队列。文中详细介绍了如何在Spring Boot项目中集成Redis,并展示了其工作原理、缓存实现方法及高级特性,如事务、发布/订阅、Lua脚本和集群等,帮助读者从入门到精通Redis,大幅提升应用性能与可扩展性。
60 0
|
20天前
|
存储 缓存 Java
什么是线程池?从底层源码入手,深度解析线程池的工作原理
本文从底层源码入手,深度解析ThreadPoolExecutor底层源码,包括其核心字段、内部类和重要方法,另外对Executors工具类下的四种自带线程池源码进行解释。 阅读本文后,可以对线程池的工作原理、七大参数、生命周期、拒绝策略等内容拥有更深入的认识。
什么是线程池?从底层源码入手,深度解析线程池的工作原理
|
24天前
|
开发工具
Flutter-AnimatedWidget组件源码解析
Flutter-AnimatedWidget组件源码解析
|
20天前
|
设计模式 Java 关系型数据库
【Java笔记+踩坑汇总】Java基础+JavaWeb+SSM+SpringBoot+SpringCloud+瑞吉外卖/谷粒商城/学成在线+设计模式+面试题汇总+性能调优/架构设计+源码解析
本文是“Java学习路线”专栏的导航文章,目标是为Java初学者和初中高级工程师提供一套完整的Java学习路线。
174 37
|
12天前
|
编解码 开发工具 UED
QT Widgets模块源码解析与实践
【9月更文挑战第20天】Qt Widgets 模块是 Qt 开发中至关重要的部分,提供了丰富的 GUI 组件,如按钮、文本框等,并支持布局管理、事件处理和窗口管理。这些组件基于信号与槽机制,实现灵活交互。通过对源码的解析及实践应用,可深入了解其类结构、布局管理和事件处理机制,掌握创建复杂 UI 界面的方法,提升开发效率和用户体验。
56 12
|
4天前
|
存储 缓存 NoSQL
Redis 过期删除策略与内存淘汰策略的区别及常用命令解析
Redis 过期删除策略与内存淘汰策略的区别及常用命令解析
12 0
|
2月前
|
存储 NoSQL Redis
redis 6源码解析之 object
redis 6源码解析之 object
56 6
|
2月前
|
测试技术 Python
python自动化测试中装饰器@ddt与@data源码深入解析
综上所述,使用 `@ddt`和 `@data`可以大大简化写作测试用例的过程,让我们能专注于测试逻辑的本身,而无需编写重复的测试方法。通过讲解了 `@ddt`和 `@data`源码的关键部分,我们可以更深入地理解其背后的工作原理。
30 1
|
2月前
|
开发者 Python
深入解析Python `httpx`源码,探索现代HTTP客户端的秘密!
深入解析Python `httpx`源码,探索现代HTTP客户端的秘密!
72 1

推荐镜像

更多
下一篇
无影云桌面