redis 系列20 服务器上
一.客户端与服务端交互
本篇简单介绍下服务器,服务器运行涉及的内部原理知识很多,主要了解Redis服务器内部要做哪些事情,需要开发人员去干预的比较少。Redis服务器负责与多个客户端建立网络连接,处理客户端发送的命令请求,在数据库中保存客户端执行命令所产生的数据,并通过资源管理来维持服务器自身的运转。本节先说客户端与服务器交互原理:服务器与客户端进行了什么交互,服务器中的各个不同组件又是如何协作的。在详细了解客户端与服务器在执行命令请求时所做的各种工作之前,先慨括看下命令请求的执行步骤过程:
(1) 客户端向服务器发送命令请求,比如set key value 。
(2) 服务器接收并处理客户端发来的命令请求,在数据库中进行设置操作,并产生命令回复OK。
(3) 服务器将命令回复OK发送给客户端。
(4) 客户端接收服务器返回的命令回复OK,并打印给用户看。
1.1 客户端发送命令请求
Redis服务器的命令请求来自Redis客户端,当用户在客户端中输入一个命令请求时,客户端会将这个命令请求转换成协议格式,然后通过连接到服务器的套接字,将协议格式的命令请求发送给服务器。

1.2 服务端读取命令
当客户端与服务器之间的连接套接字因为客户端的写入而变得可读时,服务器将调用命令请求处理器来执行以下操作:
(1) 读取套接字中协议格式的命令请求,并将其保存到客户端状态的输入缓冲区里面。
(2) 对输入缓冲区中的命令请求进行分析,提取出命令请求中包含的命令参数,以及命令参数的个数。分别保存到服务端记录客户端状态的argv和argc属性中。
(3) 调用命令执行器,执行客户端指定的命令。
1.3 命令执行器
(1) 查找命令实现
命令执行器要做的第一件事就是根据客户端状态的argv[0]参数,在命令表(command table)中查找参数所指定的命令,并将找到的命令保存到客户端状态的cmd属性里面。命令表是一个字典,字典的键是一个个命令的名字,比如常见的如: get , set ,del等命令,字典的值则是一个个redisCommand结构,每个结构记录了一个命令的实现信息。redisCommand结构的主要属性就不在此了解。
(2) 执行预备操作
服务器已经将执行命令所需的命令实现函数(客户端状态的cmd属性),参数(客户端状态的argv属性),参数个数(客户端状态的argc属性)都收集全了,但在真正执行命令之前,程序还要进行一些预备操作,确保命令可以正确,顺利地被执行。简单说包括:1.检查cmd属性中命令是否正确。2.参数以及参数个数是否正确。3.是否通过身份验证。4.如果打开了maxmemory功能,那么在执行命令之前,先检查服务器内存占用情况,需要时进行内存回收,以接下来的命令可以顺利执行。5.如果服务器正在进行数据载入,那么客户端发送的命令会被服务器拒绝。6.如果客户端当前正使用subscribe命令订阅频道,或者用psubscribe命令订阅模式,那么其它命令都会被服务器拒绝,8.如果客户端正在执行事务,那么服务器只会执行客户端发来的exec,discard,multi,watch命令,其它命令都会被放进事务队列中。9如果服务器开启了监视器功能,那么服务器会将要执行的命令和参数信息发送给监视器。10.如果服务器因为执行Lua脚本而超时并进入阻塞状态,那么其他命令会被服务器拒绝。注意:如果服务器是在复制或者集群模式下,预备操作会更多。完成了以上预备操作之后,服务器才会执行命令。
(3) 执行命令实现函数操作
服务器已经将要执行命令的实现保存到了客户端状态的cmd属性里,并将命令的参数和参数个数分别保存到了客户端状态的argv属性和argv属性中,当服务器决要执行命令时,内部只要执行以下语句就可以了:
//clinet是指向客户端状态的指针
client->cmd->proc(client);
当执行命令操作后,会产生相应的命令回复,比如ok, 这些回复会被保存在客户端状态的输出缓冲区里面(redisClient结构的buf属性和reply属性),之后还会为客户端的套接字关联命令回复处理器,这个处理器命令回复返回给客户端。
(4)执行后续工作
当执行命令实现函数之后,服务器还需要执行后续工作:1.如果服务器开启了慢查询日志功能,那么慢查询日志模块会添加一条新的慢查询日志。2.根据执行命令所耗时的时长,更新被执行命令的redisCommand结构的millisecondes属性,并将命令的redisCommand结构的calls计数器值增一。3.如果开启了AOF功能,刚执行的命令请求写入到AOF缓冲区中。4.如果有从服务器正在复制,那么该命令会传播给所有从服务器。
当以上操作都执行完了后,服务器就可以继续从文件事件处理器中取出并处理下一个命令请求了。
二. serverCron函数
在上节中介绍了客户端与服务端交互过程,这节了解serverCron函数执行操作,并说明这些操作对于服务器维持正常运行有何帮助。 redis服务器中的serverCron函数默认每隔100毫秒执行一次,负责管理服务器的资源,并保存执行器自身的良好运转。
2.1 更新服务器时间缓存
redis服务器中有不少功能需要获取系统当前时间,每次获取系统的当前时间都需要执行一次系统调用,为了减少系统调用的执行次数,服务器状态redisServer结构的unixtime属性和mstime属性被用作当前时间的缓存。默认每隔100毫秒一次频率更新unixtime属性和mstime属性,所以这两个属性记录的时间的精确度并不高。一般用在服务器打印日志、更新服务器的LRU时钟、决定是否执行持久化任务、计算服务器上线的时间(uptime)等这类对时间精度度要求不高的功能上。对于要求精确度高的时间,会再次执行系统调用获取,一般用在为键设置过期时间、添加慢日志等功能上。
2.2 更新LRU时钟
LRU全称是Least Recently Used,即近期最少使用算法。用于内存数据清除方面,在第15篇中有介绍。服务器状态redisServer结构的lruclock属性保存了服务器的LRU时钟。默认每隔10秒更新一次时钟缓存。通过该算法计算一个数据库键的空转时间。
127.0.0.1:> set msg "hello"
OK
127.0.0.1:> object idletime msg
(integer)
127.0.0.1:> object idletime msg
(integer)
在Redis4.0版本中,感觉这个空转时钟很精确,不像默认10秒一次更新lurclock属性的值。
redis 系列20 服务器上的更多相关文章
- redis 系列20 服务器下
二. serverCron函数 2.3 更新服务器每秒执行命令次数 serverCron函数中的trackOperationsPerSecond函数会以每100毫秒一次的频率执行,这个函数以抽样计算的 ...
- redis 系列 在 vs上 set,get 键值
1.启动两个 cmd,一个用于打开服务,一个用于运行客户端. 详细步骤可见上一篇文章 2.下载nuget的 ServiceStack.Redis; ,并在using中引用 ,详细步骤可见上一篇文章 ...
- 【目录】redis 系列篇
随笔分类 - redis 系列篇 redis 系列27 Cluster高可用 (2) 摘要: 一. ASK错误 集群上篇最后讲到,对于重新分片由redis-trib负责执行,关于该工具以后再介绍.在进 ...
- Shell脚本实现超简洁的在Linux服务器上安装nginx、resin、java、tomcat、redis等程序
说明: 用平常的方式在Linux服务器上安装程序,需要下载安装包.进入安装包位置.给安装包文件赋予可执行权限.执行安装.设置环境变量--等等一系列复杂的操作.并且如果有关联也需要一个一个的挨着安装.耗 ...
- 在多台服务器上简单实现Redis的数据主从复制(3)(转载)
转载地址:http://www.cnblogs.com/liping13599168/archive/2011/04/14/2016226.html Redis的主从复制功能非常强大,一个master ...
- 在多台服务器上简单实现Redis的数据主从复制
Redis的主从复制功能非常强大,一个master可以拥有多个slave,而一个slave又可以拥有多个slave,如此下去,形成了强大的多级服务器集群架构.下面我演示下怎样在多台服务器上 ...
- 在服务器上,配置redis可以外网访问
首先linux开放默认端口6379打开redis配置文件redis-conf注释掉 bind 127.0.0.1(默认只有本地主要才能访问)这个注释掉现在处于受保护的状态,外网连不上,因为没有密码 在 ...
- redis在linux云服务器上完整的搭建步骤
Redis的安装 搭建环境: 华为云linux服务器 Linux系统CneterOS-7.3 SSH客户端 Xshell6 安装c语言编译环境软件如下: 安装报错 然后找到了解决方法: 安装kerne ...
- Linux 服务器上Redis安装和配置
1.下载安装redis 在Linux服务器上,命令行执行以下命令(cd ./usr local/src 一般源码放在这里(推荐源码安装)) wget http://download.redis.io/ ...
随机推荐
- DW1000 用户手册中文版 附录3:双向测距(Two-Way Ranging)
由于已经在wode中排版无法直接复制到博客中,故本节博客发布使用了图片. 论坛可下载PDF http://bphero.com.cn/forum.php?mod=viewthread&tid ...
- window 安装redis、memcache的php扩展和 reidis 、memcache 及 reids管理软件
redis 1.安装redis的php扩展 http://windows.php.net/downloads/pecl/releases/redis/ http://windows.php.net/d ...
- TypeScript 函数-函数类型
//指定参数类型 function add(x:number,y:number){ console.log("x:"+x); // reutrn(x+y); } //指定函数类型 ...
- 181102 Windows下安装kivy(用python写APP)
了解到Instgram,知乎等APP是用python写的.我也决定学习用python写APP.这里我们需要安装kivy. 环境:win7,python3.6 安装方式:DOS命令窗口 注意事项:目前不 ...
- django+javascrpt+python实现私有云盘代码
丁丁:由于篇幅有限,这里暂时只展示python后端代码,前端js代码后面上传,有需要的也可以留言私信我. 1.view.py 使用用户.部门.公司等相关账号的创建,已经个人,部门账号的冻结,删除,相关 ...
- C# static 变量 和方法
静态成员属于类所有,无认创建多少实例对象,静态成员在内存中只有一份:实例成员属于类的实例所有,每创建一个实例对象,实例成员都会在内存中分配一块内存区域. 就像图书馆的书,书的数量就是图书馆这个对象的静 ...
- Servlet 监听器Listner
定义: 专门用于对其他对象身上发生的事件或状态改变进行监听和相应处理的对象,当被监视的对象发生情况时,立即采取相应的行动. Servlet 规范为每种事件监听器都定义了相应的接口,它用于监听 ...
- swust oj 1051
输出利用先序遍历创建的二叉树中的指定结点的孩子结点 1000(ms) 10000(kb) 2432 / 5430 利用先序递归遍历算法创建二叉树并输出该二叉树中指定结点的儿子结点.约定二叉树结点数据为 ...
- Trie树(字典树)的介绍及Java实现
简介 Trie树,又称为前缀树或字典树,是一种有序树,用于保存关联数组,其中的键通常是字符串.与二叉查找树不同,键不是直接保存在节点中,而是由节点在树中的位置决定.一个节点的所有子孙都有相同的前缀,也 ...
- 数组Array和列表集合ArrayList、LinkedList和Vector的区别
一.ArrayList和Vector的区别 ArrayList与Vector主要从以下方面来说. 1.同步性: Vector是线程安全的,也就是说是同步的,而ArrayList是线程序不安全的,不是同 ...