Redis学习笔记(十一) 服务器

Redis学习笔记(十一) 服务器Redis服务器负责与多个客户端建立网络通信,处理客户端发送的命令请求,在数据库中保存客户端执行命令所产生的数据,并通过资源管理来维持服务器自身的运转。 命令请求过程(以set命令为例) 1、客户端向

Redis学习笔记(十一) 服务器

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

 

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

 

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

 

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

Redis学习笔记(十一) 服务器

 

 

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

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

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

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

命令执行器:

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

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

 

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

 

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

 

 Redis学习笔记(十一) 服务器

 

 

serverCron函数

 

 

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

 

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

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

代码100分

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

 

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

代码100分typedef struct redisObject{
    unsigned lru:22"
} robj;

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

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

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

3、处理sigterm信号

代码100分static void sigtermHandler(int sig){
    //打印日志
    redisLogFromHandler(REDIS_WARNING,"received sigterm,scheduling shutdown...");
    //打开关闭标识
    server.shutdown_asap=1;
}

struct redisServer{
    //serverCron函数运行时,程序灰度服务器状态的shutdown_asap属性进行检查,并根据属性值决定是否关闭服务器。
    //关闭服务器的标识
    //值为1时,关闭服务器
    //值为0时,不做动作
    int shutdown_asap;
}

4、管理客户端资源

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

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

6、执行被延迟的BGREWRITEAOF

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

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

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

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

Redis学习笔记(十一) 服务器

 

 

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操作做准备。

 

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

Redis学习笔记(十一) 服务器

 

 

4、还原数据库装填

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

5、执行事件循环

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

 


 

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


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

 

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

 

Redis学习笔记(十一) 服务器

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
转载请注明出处: https://daima100.com/8352.html

(0)
上一篇 2023-03-01
下一篇 2023-03-01

相关推荐

  • 使用Python构建企业级Web应用程序的最佳模块

    使用Python构建企业级Web应用程序的最佳模块Python是一种功能强大的编程语言,它在Web开发领域的广泛应用使其成为最受欢迎的语言之一。 企业级应用程序需要可靠的模块来确保高效,可靠性和安全性。 这篇文章将介绍Python中最好的企业级Web应用程序模块。

    2023-12-22
    66
  • Python中的实例变量和类变量

    Python中的实例变量和类变量在Python中,变量可以分为两种主要类型:实例变量和类变量。本文将详细介绍这两种变量类型以及它们的区别、优缺点和使用场景。

    2024-02-12
    44
  • windows下安装mysql5.7「终于解决」

    windows下安装mysql5.7「终于解决」1.首先官网下载ZIP安装包(即以解压,配置的方式安装) 2.解压完成之后在目录下创建my.ini文件 内容如下: [mysql]# 设置mysql客户端默认字符集default-character-

    2023-05-09
    116
  • 数据库-数据库系统原理[通俗易懂]

    数据库-数据库系统原理[通俗易懂]数据库-数据库系统原理 落花人独立,微雨燕双飞。 简介:数据库-数据库系统原理。 一、事务 概念 事务指的是满足 ACID 特性的一组操作,可以通过 Commit 提交一个事务,也可以使用 Rollb

    2023-04-19
    112
  • 用Python打印99乘法表

    用Python打印99乘法表乘法口诀表是小学数学教育中最基础的知识之一,也是计算机编程基础教育中重要的一环。Python作为一门强大而易学的编程语言,可以通过多种方法打印乘法表。本文将介绍Python打印乘法表的多种方法,并给出详细的代码示例。

    2024-04-21
    13
  • SQL 子查询简介[亲测有效]

    SQL 子查询简介[亲测有效]学习重点 一言以蔽之,子查询就是一次性视图(SELECT 语句)。与视图不同,子查询在 SELECT 语句执行完毕之后就会消失。 由于子查询需要命名,因此需要根据处理内容来指定恰当的名称。 标量子查询

    2023-04-29
    115
  • Python安装后CMD无法运行的解决方法

    Python安装后CMD无法运行的解决方法Python是一种高级编程语言,被广泛用于各种web应用程序和数据科学领域。但是,有时在安装Python后,无法在命令提示符(CMD)中运行python命令。本文将介绍如何解决这个问题。

    2024-04-22
    14
  • 如何安装Jupyter

    如何安装JupyterJupyter Notebook是一个非常强大的工具,可以让用户编写和分享文档,代码以及其他数据。它是一个基于Web的应用程序,支持多种编程语言,如Python,R和Julia等。使用Jupyter Notebook可以有效地组织和演示工作流程,还支持实时共享文档,便于远程团队合作。

    2024-05-11
    9

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注