专栏首页源码阅读redis代码走读与编程实践——网络交互篇(上)
原创

redis代码走读与编程实践——网络交互篇(上)

导语

redis是一种内存数据存储系统,可被用作数据库、缓存、消息队列等;以高性能、高并发能力著称;本文分为上下两篇,其中上篇主要着眼于最简单的单机数据库&非事务命令场景,对网络框架相关代码进行走读,阐述redis服务器如何接收来自客户端的连接请求,建立连接并与响应客户端的指令,找到对应的处理代码;下篇主要是尝试编写简单的redis客户端,从最简单的建立连接开始,到和redis-server进行交互,借此加深对上篇阅读代码的理解,并在最后模仿redis-server的连接管理模型,实现一个简单的server demo。更多内容移步作者个人博客

概述

redis是基于事件驱动的单线程应用;事件收集器收集事件(这里主要是网络事件和定时事件)之后,分发到各个模块进行处理(在redis中是找到对应事件的注册回调函数);如下图所示:

配置相关

本文主要关注于网络事件模块的代码走读,为便于分析,会略过无关的代码和配置。

1. 服务端相关配置

因为后续需要通过修改相关的redis配置信息来配合一些实验,所以先介绍redis相关的一些配置信息:

a) redis通过启动命令redis-server [conf-file-path]命令指定配置文件

b) 若是不指定,则默认使用同目录下redis.conf文件作为配置文件

Redis.conf中和网络相关的配置包括:

a) port:指定监听端口号

b) bind: bind用于配置redis进程监听的IP地址;若是没有配置的话,redis进程会监听机器上的所有的IP

c) protected-mode no/yes: 配置保护模式是否开启

  1. 保护模式是redis的一个安全措施,用于避免redis被暴露到外网
  2. 保护模式开启,则只有本机的客户端可以连接到redis的服务进程
  3. 为使得redis服务可以被其他机器访问,需要关闭保护模式&bind非回环地址(现网场景下,需要配置密码requirepass)

d) timeout::配置client闲置多少秒之后,断开链接;0表示不启用, 为便于调试,实验环境我们不启用这个机制

e) logfile/loglevel: 配置日志文件的路径和等级

f) Maxclients: 表示redis服务器端,能接收的最大链接数

g) requirepass: 配置redis服务的密码

启动阶段

redis-server的网络模块在启动过程中主要完成两块工作:

  1. 解析配置文件和命令行参数,完成初始化工作;
  2. 根据配置信息,创建要监听的socket,并注册回调;

下面依次进行论述。

启动阶段

redis-server的网络模块在启动过程中主要完成两块工作:

l 解析配置文件和命令行参数,完成初始化工作;

l 根据配置信息,创建要监听的socket,并注册回调;

下面依次进行论述。

a) 解析配置及初始化

如代码所示

  1. 接口loadServerConfig,接收命令行参数,其中filename指定了配置的文件名;而options则指定了其他配置参数;最终都被存放到config数组中,传入到接口loadServerConfigFromString进行解析
  2. 接口loadServerConfigFromString,对字符数组进行按照\t\r\n进行分割;并且对于空串”\0”和”\#”不进行处理
  3. 所有的配置,都被解析,存放在类型为redisServer的全局变量server中;具体可参照源码,不再赘述

b) 创建监听socket并注册事件回调

所有配置信息都被读入到server结构体之后,接口initServer开始创建监听socket并注册回调,代码如下所示:

主要做了以下工作:

  1. l结构体aeEventLoop事件收集器
  2. 接口aeCreateEventLoop通过接口aeApiCreate创建一个epoll实例
  3. 接口listenToPort绑定所有IP上对应的端口,
  4. 通过接口aeCreateFileEvent注册监听的socket句柄,及对应的回调函数acceptTcpHandler

客户端连接建立阶段

连接建立请求检测轮询接口
连接建立请求接口

主要流程包括:

  1. 客户端请求建立连接触发监听接口读事件,从而触发回调acceptTcpHandler
  2. acceptTcpHandler调用接口anetTcpAccept来接收连接,分配对应socket
  3. 连接建立之后,通过acceptCommonHandler,创建描述客户端的类型为client结构体&注册事件监听和回调,并通过全局变量server的client链表管理所有的客户端
  4. 此外接口acceptCommonHandler还进行最大连接数检查(客户端连接数是否大于server.maxclients)和保护模式下检查(保护模式下未配置密码只允许本地访问),检查通过则连接正式建立

交互流程

redis客户端和服务器建立连接之后,即可以通过客户端向redis-server发送命令;执行流程如下所述:

客户端输入指令的主调接口
指令解析接口

主流程如下:

  1. 主循环通过接口aeProcessEvents收集已经有客户端数据上来的socket
  2. 对于有数据的socket,触发回调readQueryFromClient,读入客户端请求
  3. 针对非管道指令,通过调用链processInputBuffer->processMultibulkBuffer对请求的参数进行解析(同时校验请求的合法性,参数合法性、参数个数合法性、长度合法性等),解析的结果存放在client->argv和client->argc中
  4. 解析出客户端请求的各个字段之后,通过processCommand这个接口找到对应的命令结构体,执行其对应的回调

以上为redis网络交互模块,监听接口注册、连接建立、注册回调以及命令解析与交互的主要流程源码走读;因笔者能力有限,若有疏误欢迎留言指正;

参考资料

1. https://redis.io/

2. https://www.xilidou.com/2018/03/22/redis-event/

3. https://www.runoob.com/redis/redis-pipelining.html

4. https://cloud.tencent.com/developer/article/1005481

5. http://blog.chinaunix.net/uid-28541347-id-4238524.html

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • redis代码走读与编程实践——网络交互篇(下)

    在文章《redis代码走读与编程实践——网络交互篇(上)》中,对redis连接请求与建立流程进行源码剖析和走读;本文主要尝试编写一个简单的redis客户端和re...

    王鹏程1990
  • Redis源码走读及编程实践——数据安全篇(一)

    redis作为内存数据库,为了防止因为程序bug或者机器故障导致的数据丢失,redis采取了多维度的措施来保障redis写入数据的安全。从单机层面:采取备份磁盘...

    王鹏程1990
  • Redis源码走读及编程实践——数据安全篇(二)

    《Redis源码走读及编程实践——数据安全篇(一)》介绍了RDB的落地原理并走读了redis的RDB落地流程,本文继续介绍redis的另外一种数据落地机制AOF...

    王鹏程1990
  • 有了它,Redis不再是你技术面试中的阻碍

    Redis在互联网技术存储方面使用非常广泛,几乎所有的后端技术面试官都要在Redis的使用和原理方面对求职小伙伴们进行各种刁难,特别是那些优秀的、竞争激烈的大型...

    博文视点Broadview
  • BATJTMD,大厂招聘,都招什么样Java程序员?

    最近总看到类似这样的问题,也有一些工作3年左右的小伙伴问小傅哥,该怎么进大厂。其实你说 Java 学多少可以找到工作,主要看你想在哪个城市找、找什么样的公司、找...

    小傅哥
  • 进BAT这些互联网大厂,面试之前刷几百道面试题真的有用吗?

    面试之前先刷几篇面经,或者做几道热门面试题,想必是大家很熟悉的一种复习方式了,就像我们当年经常做五年高考三年模拟一样。但是可不要把面试题和面经当成你的主要复习...

    美的让人心动
  • 校招进大厂,分享 Tom哥的读书单

    大家好,我是Tom哥。校招进阿里,研究生,P7技术专家,出过专利,竞赛拿过奖,CSDN博客专家,负责过电商交易、社区生鲜、营销、金融等业务,多年团队管理经验,爱...

    微观技术
  • 必看!java后端,亮剑诛仙(最全知识点)

    你可能有所感悟。零散的资料读了很多,但是很难有提升。到处是干货,但是并没什么用,简单来说就是缺乏系统化。另外,噪音太多,雷同的框架一大把,我不至于全都要去学了...

    xjjdog
  • 基于实践:一套百万消息量小规模IM系统技术要点总结

    本文由公众号“后台技术汇”分享,原题“基于实践,设计一个百万级别的高可用 & 高可靠的 IM 消息系统”,原文链接在文末。由于原文存在较多错误和不准确内容,有大...

    JackJiang
  • 【Rust日报】 2019-05-14:Rust中哪些特性是零开销抽象的

    Snips(一家做音频识别的创业公司) 出品。在神经网络领域,现在基本已经被 TensorFlow 和 PyTorch 给占了。但是对于移动设备或IoT这些性能...

    MikeLoveRust
  • 《后端成长路线》系列 导航篇

    1、在CSDN这么久了,也是有感情的。很感谢这么多粉丝们关注了我,我想,是要回报一下大家的。所以我的博客也是比较用心的,大家可以看出来吧,几乎每周我都会 “排水...

    看、未来
  • 从Java小白到收获BAT等offer,分享我这两年的经验和感悟

    常想,人生最有趣莫过于前路未知。于是我常常羡慕那些个“金梁古温”笔下随遇而安、随性而为、随缘而爱的浪子们。比如陆小凤,比如叶开。

    猿天地
  • 【真荐书】双11书单,我们一起共读 36 + 1 本书

    《Redis开发与运维》全面讲解 Redis 基本功能及其应用,并结合线上开发与运维监控中的实际使用案例,深入分析并总结了实际开发运维中遇到的“陷阱”,以及背后...

    kirito-moe
  • 从Java小白到收获BAT等offer,分享我这两年的经验和感悟

    我写过很多篇秋招总结,这篇文章应该是最后一篇总结,当然也是最完整,最详细的一篇总结。秋招是我人生中一段宝贵的经历,不仅是我研究生生涯交出的一份答卷,也是未来职业...

    程序员黄小斜
  • 2021 最新的Java 后端学习路线!凎!

    断断续续写了大半个月,终于把 2021 最新版的 Java 后端学习路线给整完了!

    Guide哥
  • Redis 深度历险:核心原理与应用实践

    Redis 是互联网技术架构在存储系统中使用最为广泛的中间件,它也是中高级后端工程师技术面试中面试官最喜欢问的工程技能之一,特别是那些优秀的、竞争激烈的大型互联...

    Bug开发工程师
  • 长连接网关技术专题(六):石墨文档单机50万WebSocket长连接架构实践

    本文由石墨文档技术杜旻翔分享,原题“石墨文档 Websocket 百万长连接技术实践”,有修订。

    JackJiang
  • 学习 Java,有什么书籍推荐?学习的方法和过程是怎样的?

    为什么要学 Linux 呢?因为在实际的开发工作中,项目基本上都要部署到 Linux 环境下。Windows 作为服务器的很少,除了慢没别的原因。

    AI码师
  • 程序员技术练级攻略

    月光博客6月12日发表了《写给新手程序员的一封信》,翻译自《An open letter to those who want to start programm...

    小小科

扫码关注云+社区

领取腾讯云代金券