Redis源码解析--NET

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Tair(兼容Redis),内存型 2GB
全局流量管理 GTM,标准版 1个月
简介:     关于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 应用服务中间件
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
86 2
|
9天前
|
存储 设计模式 算法
【23种设计模式·全精解析 | 行为型模式篇】11种行为型模式的结构概述、案例实现、优缺点、扩展对比、使用场景、源码解析
行为型模式用于描述程序在运行时复杂的流程控制,即描述多个类或对象之间怎样相互协作共同完成单个对象都无法单独完成的任务,它涉及算法与对象间职责的分配。行为型模式分为类行为模式和对象行为模式,前者采用继承机制来在类间分派行为,后者采用组合或聚合在对象间分配行为。由于组合关系或聚合关系比继承关系耦合度低,满足“合成复用原则”,所以对象行为模式比类行为模式具有更大的灵活性。 行为型模式分为: • 模板方法模式 • 策略模式 • 命令模式 • 职责链模式 • 状态模式 • 观察者模式 • 中介者模式 • 迭代器模式 • 访问者模式 • 备忘录模式 • 解释器模式
【23种设计模式·全精解析 | 行为型模式篇】11种行为型模式的结构概述、案例实现、优缺点、扩展对比、使用场景、源码解析
|
9天前
|
设计模式 存储 安全
【23种设计模式·全精解析 | 创建型模式篇】5种创建型模式的结构概述、实现、优缺点、扩展、使用场景、源码解析
结构型模式描述如何将类或对象按某种布局组成更大的结构。它分为类结构型模式和对象结构型模式,前者采用继承机制来组织接口和类,后者釆用组合或聚合来组合对象。由于组合关系或聚合关系比继承关系耦合度低,满足“合成复用原则”,所以对象结构型模式比类结构型模式具有更大的灵活性。 结构型模式分为以下 7 种: • 代理模式 • 适配器模式 • 装饰者模式 • 桥接模式 • 外观模式 • 组合模式 • 享元模式
【23种设计模式·全精解析 | 创建型模式篇】5种创建型模式的结构概述、实现、优缺点、扩展、使用场景、源码解析
|
9天前
|
设计模式 存储 安全
【23种设计模式·全精解析 | 创建型模式篇】5种创建型模式的结构概述、实现、优缺点、扩展、使用场景、源码解析
创建型模式的主要关注点是“怎样创建对象?”,它的主要特点是"将对象的创建与使用分离”。这样可以降低系统的耦合度,使用者不需要关注对象的创建细节。创建型模式分为5种:单例模式、工厂方法模式抽象工厂式、原型模式、建造者模式。
【23种设计模式·全精解析 | 创建型模式篇】5种创建型模式的结构概述、实现、优缺点、扩展、使用场景、源码解析
|
2月前
|
缓存 监控 Java
Java线程池提交任务流程底层源码与源码解析
【11月更文挑战第30天】嘿,各位技术爱好者们,今天咱们来聊聊Java线程池提交任务的底层源码与源码解析。作为一个资深的Java开发者,我相信你一定对线程池并不陌生。线程池作为并发编程中的一大利器,其重要性不言而喻。今天,我将以对话的方式,带你一步步深入线程池的奥秘,从概述到功能点,再到背景和业务点,最后到底层原理和示例,让你对线程池有一个全新的认识。
57 12
|
28天前
|
PyTorch Shell API
Ascend Extension for PyTorch的源码解析
本文介绍了Ascend对PyTorch代码的适配过程,包括源码下载、编译步骤及常见问题,详细解析了torch-npu编译后的文件结构和三种实现昇腾NPU算子调用的方式:通过torch的register方式、定义算子方式和API重定向映射方式。这对于开发者理解和使用Ascend平台上的PyTorch具有重要指导意义。
|
10天前
|
安全 搜索推荐 数据挖掘
陪玩系统源码开发流程解析,成品陪玩系统源码的优点
我们自主开发的多客陪玩系统源码,整合了市面上主流陪玩APP功能,支持二次开发。该系统适用于线上游戏陪玩、语音视频聊天、心理咨询等场景,提供用户注册管理、陪玩者资料库、预约匹配、实时通讯、支付结算、安全隐私保护、客户服务及数据分析等功能,打造综合性社交平台。随着互联网技术发展,陪玩系统正成为游戏爱好者的新宠,改变游戏体验并带来新的商业模式。
|
2月前
|
存储 安全 Linux
Golang的GMP调度模型与源码解析
【11月更文挑战第11天】GMP 调度模型是 Go 语言运行时系统的核心部分,用于高效管理和调度大量协程(goroutine)。它通过少量的操作系统线程(M)和逻辑处理器(P)来调度大量的轻量级协程(G),从而实现高性能的并发处理。GMP 模型通过本地队列和全局队列来减少锁竞争,提高调度效率。在 Go 源码中,`runtime.h` 文件定义了关键数据结构,`schedule()` 和 `findrunnable()` 函数实现了核心调度逻辑。通过深入研究 GMP 模型,可以更好地理解 Go 语言的并发机制。
|
2月前
|
消息中间件 缓存 安全
Future与FutureTask源码解析,接口阻塞问题及解决方案
【11月更文挑战第5天】在Java开发中,多线程编程是提高系统并发性能和资源利用率的重要手段。然而,多线程编程也带来了诸如线程安全、死锁、接口阻塞等一系列复杂问题。本文将深度剖析多线程优化技巧、Future与FutureTask的源码、接口阻塞问题及解决方案,并通过具体业务场景和Java代码示例进行实战演示。
61 3
|
2月前
|
存储 消息中间件 NoSQL
Redis数据结构:List类型全面解析
Redis数据结构——List类型全面解析:存储多个有序的字符串,列表中每个字符串成为元素 Eelement,最多可以存储 2^32-1 个元素。可对列表两端插入(push)和弹出(pop)、获取指定范围的元素列表等,常见命令。 底层数据结构:3.2版本之前,底层采用**压缩链表ZipList**和**双向链表LinkedList**;3.2版本之后,底层数据结构为**快速链表QuickList** 列表是一种比较灵活的数据结构,可以充当栈、队列、阻塞队列,在实际开发中有很多应用场景。

推荐镜像

更多