Redis服务器负责与多个客户端建立网络通信,处理客户端发送的命令请求,在数据库中保存客户端执行命令所产生的数据,并通过资源管理来维持服务器自身的运转。

命令请求过程(以set命令为例)

1、客户端向服务器发送命令请求 SET KEY VALUE。

Redis服务器的命令请求来自于Redis客户端,当用户从客户端键入一个命令请求时,客户端会将这个命令命令请求请求转换成协议格式,然后通过连接到服务器的套接字,将协议格式的命令请求发送给服务器。

2、服务器接收并处理客户端发送来的命令请求 SET KEY VALUE,在数据库中进行设置操作,并产生命令回复OK。

读取套接字中的协议格式命令请求,并将其保存在客户端状态的输入缓冲区中。

对输入缓冲区中的命令请求进行解析,提取出命令请求中包含的命令参数,以及命令参数的格式,分别将参数和参数个数保存到客户端状态的argv和argc属性中

调用命令执行器,执行客户端指定的命令。

命令执行器:

1、查找命令。2、执行预备操作。(检查命令、命令参数、客户端身份验证、检查服务器内存占用情况、事务、服务器状态、是否监听等)3、调用命令实现函数,产生命令回复函数,保存在客户端状态的输出缓存区4、执行后续工作:(慢查询检查记录日志;根据命令耗时更新redisCommand结构的milliseconds属性、calls计数器加1;如果开启了AOF,如果是写命令则写入到AOF缓冲区;如果有其他从服务器正在复制当前的服务器,那么服务器会将刚刚执行的命令传播给所有从服务器。)

3、服务器将命令回复OK发送为客户端。

当客户端套接字变为可写状态时,服务器会执行命令回复处理器,将保存在客户端缓冲区的命令回复发送给客户端。

4、客户端接收服务器返回的命令回复OK,并将这个回复打印给用户观看。客户端收到协议格式的命令回复后,将其转换为人类可读的格式,并打印。

 

serverCron函数

 

Redis服务器中的serverCron函数每100毫秒执行一次,这个函数负责管理服务器的资源,并保持服务器自身的良好运转。

1、更新服务器缓存时间,为减少系统调用获取当前时间的次数,服务器状态中的unixtime和mstime属性被用作当前时间的缓存:

struct redisServer{
//保存了秒级精度的当前unix时间戳
time_t unixtime;
//保存了毫秒级精度的系统当前unix时间戳
long long mstime;
//默认每10秒更新一次事件缓存,用于计算键的空转时间。
unsigned lruclock:
}

服务器只会在打印日志、更新服务器LRU始终、决定是否执行持久化任务、计算服务器上线时间这类对事件精度不高的功能上用;对于为键设置过期事件、添加慢日志这种需要高精度事件的功能来说,服务器还是会再次执行系统调用,从而获得更准确的系统当前事件。

每个Redis对象都有一个lru属性,这个lru属性保存了对象最后一次被命令访问的时间:

typedef struct redisObject{
unsigned lru:'
} robj;

serverCron函数中的trackOperationsPerSecond函数会以每100毫秒一次的频率执行,这个函数的功能以抽样计算的方式,估算并记录服务器在最近一秒钟处理的命令请求数量,这个值通过INFO status命令的instantaneous_ops_per_sec域查看。

2、更新服务器内存峰值记录:服务器状态中的stat_peak_memory属性记录服务器的内存峰值大小:

struct redisServer{
//已使用内存峰值
size_t stat_peak_memory;
}

3、处理sigterm信号

static void sigtermHandler(int sig){
//打印日志
redisLogFromHandler(REDIS_WARNING,"received sigterm,scheduling shutdown...");
//打开关闭标识
server.shutdown_asap=;
}
struct redisServer{
//serverCron函数运行时,程序灰度服务器状态的shutdown_asap属性进行检查,并根据属性值决定是否关闭服务器。
//关闭服务器的标识
//值为1时,关闭服务器
//值为0时,不做动作
int shutdown_asap;
}

4、管理客户端资源

serverCron函数每次执行都会调用clientCron函数,clientsCron函数会对一定数量的客户端进行检查:如果客户端与服务器之间的连接已经超时,那么程序释放这个客户端;如果客户端在上一次执行命令请求后,输入缓冲区的大小超过了一定的长度,那么程序会释放客户端当前的输入缓冲区,重新创建一个迷人大小的输入缓冲区,防止客户端的输入缓冲区耗费过多的资源。

5、管理数据库资源 :删除过期键,如有需要,对字典进行收缩操作。

6、执行被延迟的BGREWRITEAOF

如果BGSAVE执行期间,客户端发来BGREWRITEAOF命令,则需要延迟到BGSAVE命令执行完成后。

7、检查持久化操作运行状态

服务器状态使用rdb_child_pid\aof_child_pid属性记录执行BGSAVe命令和BGREWRITEAOF命令的子进程ID,用于检查命令是否正在执行

struct redisServer{
//记录执行BGSAVE命令的紫禁城,如果没有执行则为-1
pid_t rdb_child_pid;
//记录执行BGREWRITEAOF命令的子进程ID,没执行则为-1
pid_t aof_child_pid;
}

8、将AOF缓冲区中的内容写入AOF文件

9、关闭异步客户端(检查输出缓冲区大小)

10、增加cronloops计数器的值(没执行serverCron函数N次就执行一次指定的代码)

初始化服务器

 

1、初始化服务器状态结构,创建一个struct redisServer类型的实例变量server作为服务器的状态。

initServerConfig函数完成的主要工作:

设置服务器运行ID

设置服务器的默认运行频率

设置服务器的默认配置文件路径

设置服务器的运行架构

设置服务器的默认端口号

设置服务器默认RDB持久化条件和APF持久化条件

初始化服务器LRU时钟

创建命令表

2、载入配置项修改默认的配置。

3、初始化服务器数据结构

在执行initServerConfig函数初始化server状态时,程序只创建命令表一个数据结构,服务器在次数初始化其他数据结构:

server.clients链表,记录所有与服务器相连接的客户端状态

erver.db数组,包含服务器的所有数据库。

保存频道订阅信息的server.pubsub_channels字典以及保存模式订阅信息的server_publsub_patterns链表。

执行Lua脚本的Lua环境 server.lua;

用于保存慢查询日志的server.slwlog链表

除了初始化数据结构之外,initServer还进行了一些非常重要的设置操作:

为服务器设置进程信号处理器。

创建共享对象。

打开服务器的监听端,并未监听套接字关联连接应答事件处理时,等待服务器正式运行时接收客户端连接。

为serverCron函数创建时间事件,等待服务器正式运行时,执行serverCron函数。

如果AOF持久化功能打开,那么打开现有的AOF文件,如果文件不存在则创建新的AOF文件

初始化服务器的后台I/O模块,为将来的I/O操作做准备。

执行完以上内容那么你就看到了熟悉的画面:

4、还原数据库装填

在完成对服务器状态server变量的初始化后,服务器需要载入RDB文件或者AOF文件,并根据文件记录的内容还原数据库状态

5、执行事件循环

到此服务器的初始化工作圆满完成,服务器现在开始可以接收客户端的连接请求,并处理客户端发来的命令请求。


写到这里,非常有冲动写一下.net 程序初始化以及运行过程服务端做了那些事情,着手准备!


每天学一点,总会有收获。

说明:尊重作者知识产权,文中内容参考《Redis设计与实现》,仅在此做学习与大家分享。

Redis学习笔记(十一) 服务器的更多相关文章

  1. redis 学习笔记(6)-cluster集群搭建

    上次写redis的学习笔记还是2014年,一转眼已经快2年过去了,在段时间里,redis最大的变化之一就是cluster功能的正式发布,以前要搞redis集群,得借助一致性hash来自己搞shardi ...

  2. Redis学习笔记~目录

    回到占占推荐博客索引 百度百科 redis是一个key-value存储系统.和Memcached类似,它支持存储的value类型相对更多,包括string(字符串).list(链表).set(集合). ...

  3. Redis学习笔记4-Redis配置详解

    在Redis中直接启动redis-server服务时, 采用的是默认的配置文件.采用redis-server   xxx.conf 这样的方式可以按照指定的配置文件来运行Redis服务.按照本Redi ...

  4. Redis学习笔记一:数据结构与对象

    1. String(SDS) Redis使用自定义的一种字符串结构SDS来作为字符串的表示. 127.0.0.1:6379> set name liushijie OK 在如上操作中,name( ...

  5. Redis学习笔记之ABC

    Redis学习笔记之ABC Redis命令速查 官方帮助文档 中文版本1 中文版本2(反应速度比较慢) 基本操作 字符串操作 set key value get key 哈希 HMSET user:1 ...

  6. (转)redis 学习笔记(1)-编译、启动、停止

    redis 学习笔记(1)-编译.启动.停止   一.下载.编译 redis是以源码方式发行的,先下载源码,然后在linux下编译 1.1 http://www.redis.io/download 先 ...

  7. Redis学习笔记(二)Redis支持的5种数据类型的总结之String和Hash

    引言 在Redis学习笔记(一)中我们已经会安装并且简单使用Redis了,接下来我们一起来学习下Redis支持的5大数据类型. 简介 Redis是REmote DIctionary Server(远程 ...

  8. Redis学习笔记(3)——Redis的命令大全

    Redis是一种nosql数据库,常被称作数据结构服务器,因为值(value)可以是 字符串(String), 哈希(Map), 列表(list), 集合(sets) 和 有序集合(sorted se ...

  9. Redis学习笔记(1)——Redis简介

    一.Redis是什么? Remote Dictionary Server(Redis) 是一个开源的使用ANSI C语言编写.遵守BSD协议.支持网络.可基于内存亦可持久化的日志型.Key-Value ...

  10. redis 学习笔记-cluster集群搭建

    一.下载最新版redis 编译 目前最新版是3.0.7,下载地址:http://www.redis.io/download 编译很简单,一个make命令即可,不清楚的同学,可参考我之前的笔记: red ...

随机推荐

  1. C#多线程(13):任务基础①

    目录 多线程编程 多线程编程模式 探究优点 任务操作 两者创建任务的方式 Task.Run() 创建任务 取消任务和控制任务的创建 任务返回结果以及异步获取返回结果 捕获任务异常 全局捕获任务异常 多 ...

  2. Kubernetes笔记(一):十分钟部署一套K8s环境

    Kubernetes是Goole开源的一个容器编排引擎,它支持自动化部署.大规模可伸缩.应用容器化管理 -- 百度百科. 接触K8s也有半年多了,也基于阿里云平台搭建了包含多级服务.目前运行较为稳定的 ...

  3. WebApi参数检查验证FluentValidation的使用方法

    右键打开NuGet程序包管理,进入浏览,搜索 FluentValidation,点击下载 在Model文件夹添加一个Person类进行校验 校验前,using需要引入相应的命名空间方可使用,Abstr ...

  4. PHP生成桌面快捷方式,保存一个网页至桌面上成为快捷方式

    header("Content-Type: application/octet-stream; charset=utf8"); header("Content-Dispo ...

  5. /sbin/mount.vboxsf: mounting failed with the error: Protocol error

    公司换了新电脑,需要把之前的虚拟机的配置全部备份下来,在移动的过程中挂载共享文件夹时候出现了 /sbin/mount.vboxsf: mounting failed with the error: P ...

  6. [Qt] QProcess::startDetached() 避免弹窗,或者窗口一闪而过

    主动宣告setProcessState(QProcess::NotRunning)   或者在堆上new一个QProcess.     出处:  https://stackoverflow.com/q ...

  7. Spring Boot Starters介绍

    文章目录 Web Start Test Starter Data JPA Starter Mail Starter 结论 对于任何一个复杂项目来说,依赖关系都是一个非常需要注意和消息的方面,虽然重要, ...

  8. Hyperledger Fabric基础知识

    文章目录 什么是Hyperledger Fabric? Hyperledger架构是怎么工作的? Hyperledger交易如何执行 总结 Hyperledger Fabric基础知识 本文我们会介绍 ...

  9. 1月份中国综合PMI指数为53.2% 企业生产经营活动总体增速加快

    中新社北京1月31日电 (记者 王恩博)中国国家统计局31日发布数据显示,2019年1月份,中国综合PMI产出指数为53.2%,比上月上升0.6个百分点,表明中国企业生产经营活动总体增速加快. 其中, ...

  10. ES6的let和const命令(一)

    2019独角兽企业重金招聘Python工程师标准>>> ES6新增了let命令,用来声明变量.它的用法类似于var,但是所声明的变 量,只在let命令所在的代码块内有效. let   ...