《Redis设计与实现》读书笔记(二十) ——Redis命令在redis服务器执行过程

《Redis设计与实现》读书笔记(二十) ——Redis命令在redis服务器执行过程

(原创内容,转载请注明来源,谢谢)

序:redis服务器是redis一切的基础,服务器执行命令过程,是redis服务器的根本;服务器定时函数、服务器初始化,是服务器对客户端提供高效、稳定服务的根本。这三篇文章都是讲述redis服务器相关的原理。

一、概述

redis服务器负责和多个客户端建立连接,处理客户端发送的命令,在数据库中保存命令生成的数据,并且通过资源管理来实现自身的运转。

二、redis命令在服务器中的执行过程

redis服务器从接收到命令,到返回给客户端,中间会执行很多操作,下面以set命令作为例子。

当执行set keyvalue,共要执行4步操作:

1)客户端发送命令setkey value。

2)服务器接收并处理客户端发送的命令,在数据库进行相应的写操作,并产生回复OK。

3)服务器将OK发送给客户端。

4)客户端接收到OK,并在屏幕显示。

1、发送命令

发送命令是由客户端来进行的,当用户在客户端输入redis命令,redis客户端会将其转换成对应的协议格式的命令,再通过连接到服务器的套接字,将其发给服务器。

协议包括命令单词数量、每个单词的长度与具体内容等。

2、读取命令

1)当服务器与客户端的套接字可读时,服务器会先将命令保存到客户端状态的输入缓冲区中,即客户端状态结构的querybuf属性。

2)再解析命令,生成命令的参数和命令参数的个数(包含命令本身),保存到客户端状态结构的argc和argv。

3)再通过分析argv[0],即命令本身,从服务器存储的命令字典里,找到命令对应的执行方式redisCommand的结构,将指针保存在客户端状态结构的cmd属性。

redisCommand属性包含名称、实现函数、参数个数、属性类型(读还是写、是否允许载入数据时候使用、是否允许lua脚本使用、是否是发布订阅相关命令、是否占用大量内存等)、属性类型的二进制标识(便于对属性类型进行二进制与、或、非运算)、该命令被调用的总次数、执行这个命令耗费的时长

sflag标识:

redis查找到命令对应的命令表后,就会用属性cmd指向执行该命令的结构,如下:

其中,redis不区分命令的大小写。

3、发送命令

1)发送之前

分析完毕后,redis服务器会对命令之前,进行执行预备操作,注意查看是否具备操作条件,检查的内容众多,如下:

1. 检查cmd指针,如果其指向null,表示用户输入的命令有误,则不往后执行,直接对用户报错。

2. 检查参数的个数,即上图的arity属性,确认参数个数满足规定要求,如get命令参数个数只能两个,set命令参数个数要求三个或以上。

3. 查看是否通过身份验证,没有通过身份验证的只能执行auth命令,不能执行其他命令。不是一开始就查看验证,也是因为即使没有验证,也是可以执行auth命令的。

4. 如果限制了内存,还要查看内存是否足够,如果不足会进行回收内存。

5. 如果服务器上一次bgsave命令出错,且配置中开启stop-write-on-bgsave-error,并且此次命令是写命令,则服务器拒绝执行。

6. 如果服务器正在用subscribe或者psubscribe订阅频道,则只能执行subscribe、psubscribe、unsubscribe、punsubscribe命令,其他命令都会被拒绝。

7. 如果服务器的数据正在载入,则只执行部分命令,如info、shutdown、publish等,这些命令都带有1标识。

8 如果服务器正在执行lua脚本而阻塞,则服务器只接受客户端发来的shutdown nosave命令和script kill命令,其他命令都会拒绝。

9. 如果服务器正在执行事务,则服务器只接受客户端发来的exec、discard、multi、watch命令,其他命令都会被放入队列中。

10. 如果服务器开启监视器功能,则会将命令发送给监视器。

2)发送命令

在完成上述10个步骤后,redis调用命令执行器,开始执行命令。

执行命令前,客户端状态结构如下:

执行命令后,状态如下:

3)执行命令后的后续工作

执行完命令后,并不是直接将结果发送给客户端,redis还会先进行部分后续工作,如下:

1. 如果服务器开启慢查询,则会查看刚才的记录是否是慢查询,如果是则写入慢查询日志。

2. 根据命令执行的时间,更新redisCommand结构的耗时属性millisecond,并且将calls计数器加一,表示调用次数多一次。

3. 如果开启AOF持久化,则如果是写命令,会将命令写入缓冲区。

4. 如果该服务器是主服务器,并且有其他服务器正在复制此服务器数据,则会将刚刚的这条写命令一并发送过去。

4、命令回复客户端

完成上述内容后,redis会将结果放入写缓冲区,并关联套接字的写回复处理器,当套接字是可写的状态时,服务器将命令写入套接字。

客户端接收到命令后,会进行一次转化,将结果转换成人性化的结果。

流程如下:

——written by linhxx 2017.09.09

原文发布于微信公众号 - 决胜机器学习(phpthinker)

原文发表时间:2017-09-09

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Linyb极客之路

linux常用基本命令之文件搜索命令

命令:find 语法:find [搜索范围路径] -name 【文件名称】(根据文件名查找) find [搜索范围路径] -size [...

3856
来自专栏Python小屋

Python+django网页设计入门(9):自定义反爬虫功能

2)获取客户端IP地址并限制其访问时间间隔,如果来自爬虫程序,则多次访问之间的间隔会很短,判断这种情况并给出相应的响应。

1304
来自专栏我的博客

zendframework中render,forward,redirect区别

1.render $this->render(‘my’);//注意没有.phtml 这样会在当前控制器下的my.phtml(也就是views/scripts...

3535
来自专栏性能与架构

Redis3 添加新节点到集群

向集群中添加新节点,有两种情况: (1)添加一个新节点,做为master,需要移动一部分slot到此节点 (2)添加一个新节点,做为slave,设置为集群中某个...

3487
来自专栏Java成神之路

Struts框架搭建时所遇到的问题

        解决方案:将以下7个jar拷贝到项目工程中_(workspace_项目名_webRoot_WEB-INF_lib下),其他用到的包再慢慢添加: ...

755
来自专栏流柯技术学院

修改windows系统文件权限

修改windows系统文件总是提示没有权限,虽然已是administrator也不管用。

1051
来自专栏后台及大数据开发

Linux巩固记录(6) Hbase环境准备-zookeeper安装

Hbase是运行在hadoop之上,所以请参考第3篇文章搭建好一个master,两个slave的hadoop环境,我采用的版本为hadoop2.7.4

934
来自专栏林德熙的博客

C#枚举中使用Flags特性 合并多个值判断是否存在某个值去掉一个值取反一个值

如果对一个值可以包含多个,那么可以使用枚举,加上Flags 本文告诉大家如何写一个 Flags。

2042
来自专栏www.96php.cn

【fastadmin安全篇】设置全局 HtmlPurifier 安全过滤

首先下载HtmlPurifier 链接:https://github.com/ezyang/htmlpurifier

2103
来自专栏IT笔记

hibernate3事务不起作用

如果没有如果,也许永远都发现不了这个问题,除非数据出现问题没有回滚。 由于一同事测试事务问题,发现数据不对,事务没有回滚。项目采用shiro+struts2+s...

3548

扫码关注云+社区