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

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

导语

在文章《redis代码走读与编程实践——网络交互篇(上)》中,对redis连接请求与建立流程进行源码剖析和走读;本文主要尝试编写一个简单的redis客户端和redis-server进行连接和交互,借此加深对上文源码走读的理解。为便于理解和组织文章,实验分为三个部分:

连接建立实验。

命令交互实验。

模拟redis机制实现的简单server的demo。

简单的连接实验

本实验通过简单的单线程的同步交互方式,与redis-server建立连接;过程不涉及redis的命令交互,同时验证redis的最大连接和保护模式配置。

所谓最大连接配置,是指redis支持配置最大连接数,当连接数达到最大连接数时,不再接收新的连接请求;对应配置文件的maxclients配置项。

所谓保护模式配置,是一种保护机制,当保护模式开启时,若是redis-server没有配置密码,则只接收本机IP地址的连接请求,即127.0.0.1的源IP连接请求。

实验源码如下:

最大链接配置如下:

配置最大连接数为1当同时打开两个客户端,后入的客户端运行之后报错:

对应源码:

保护模式配置如下:

对于开启保护模式,不配置密码的场景下;使用客户端直接链接上去,服务端返回错误信息为为:

验证之前的说明,开启保护模式下,若不配置密码,为了避免redis-server暴露在外网环境下,只允许本机连接;对应源码:

简单的命令交互实验

前文在走读redis源码,我们可以分析出客户端请求redis的源码格式,以set指令为例,我们输入set aaa bbb的时候,实际客户端发给服务器的命令内容为:*3\r\n$3\r\nset\r\n$3\r\naaa\r\n$4\r\nbbb\r\n;其中:

  1. *,是普通指令标识
  2. 3,是参数个数
  3. \r\n是分隔符
  4. $3是字符串长度

源码如下所示:

运行结果:

可见数据是成功写入到redis服务器端了

前文说到,redis协议规定,bulk之间使用\r\n进行分割,但是在代码中没有作相应的校验,只是单取\r进行分割,为了验证这个问题,我们将代码中的\n替换为\t如下图所示:

重新编译,运行,结果如下:

是成功的,说明是可以正常写入的。

需要说明的是,这个客户端只针对set命令做了简单的实现,没有实现解码的部分;所以是一个演示功能代码。

基于epoll的server demo

学习源码,不仅是去看开源项目底层的具体实现;更重要是是学习开源项目优秀的设计思想,为后续的项目开发助力;redis网络交互模块是基于epoll机制实现的连接管理,在本节我们模仿redis-server的连接管理机制,实现一个简易的多链接服务器。

首先简单介绍一下epoll:

众所周知,epoll相对于select,能处理更多的连接并且提供更高的性能;具体是通过以下几点做到的:

  1. epoll需要关注的fds,是通过mmap存放在内核态与用户态都可见的位置,避免了epoll-wait时用户态和内核态之间的内存拷贝;
  2. epoll底层使用红黑树管理fds列表,相比于顺序查询提供了更高的增删查改的性能;
  3. epoll-wait返回的是已经就绪的fds列表,主调接口不必遍历所有的fd收集事件;
  4. epoll-wait在收集已经就绪的fd列表的时候,也不是遍历监控的fd,而是让已经就绪的fd自己插入到就绪列表,减少了无意义的遍历行为;

介绍完epoll的原理,server-demo源码如下:

主要包括以下几点:

  1. aeEventElem:用于描述所有被监控的fd,包括关注的事件(mask)、对应的回调(rfunc/wfunc)、以及连接对应的session数据(privdata)
  2. aeEventPool:用于管理所有的需要监控的FD(eventList),fd的值作为eventlist的下标
  3. 接口:aeAddFileEvent用于注册fd事件被触发时的的回调
  4. 因此,主流程里面,首先创建epoll实例,然后创建监听socket,将监听socket事件被触发的回调aeAcceptSocket通过adAddFileEvent注册到aeEventPool中&通过epoll_ctl注册到epoll实例中;然后轮询调用epoll_wait,若有事件发生,被触发的事件存放在events数组中,我们通过event的fd找到对应回调;若是监听接口,则分配连接,并注册连接回调;若是其他接口,则直接读取数据即可

参考资料

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

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

    redis是一种内存数据存储系统,可被用作数据库、缓存、消息队列等;以高性能、高并发能力著称;本文分为上下两篇,其中上篇主要着眼于最简单的单机数据库&非...

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

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

    王鹏程1990
  • XenMobile 9.0 完全部署指南之安装第一台 DeviceManager--04

      经过前期的证书与数据库准备,接下来我们可以开始XenMobile的正式安装了,XenMobile2个组件,我们首先介绍DeviceManager的安装,该组...

    SuperDream
  • 内网渗透靶机-VulnStack 1

    靶机是红日团队开源的一个靶机,靠着这个环境学习到了很多啊哈哈哈!现在自己也是会搭建一些环境了!也是靠着这个靶机从0开始学内网,了解内网渗透,虽然很菜很菜很菜!靶...

    黑白天安全
  • ubuntu配置ZeroTier

    1)官网: https://www.zerotier.com/ 2)注册账号 免费的账户允许接入100台设备,然后就是一些相关信息的登记,不用

    治电小白菜
  • 第五:人脸识别算法课程系列文章-Facenet算法

    大家好,欢迎大家来到本节课。本次课给大家分享人脸识别的算法。从这里开始,我们就先看一下人脸识别算法所面临的挑战吧。

    算法发
  • Kettle7.1创建资源库,资源库颜色灰色,没有Connect按钮解决办法

    cn華少
  • 感恩,关注优图实验室的你

    优图实验室
  • HBase监控

    HBase自带的Web UI上Region单位的 Read Request Count/Write Request Count,不过这只是个累计值。

    sparkle123

扫码关注云+社区

领取腾讯云代金券