诠释serverCron函数在服务器的相关功能

追求适度,才能走向成功;人在顶峰,迈步就是下坡;身在低谷,抬足既是登高;弦,绷得太紧会断;人,思虑过度会疯;水至清无鱼,人至真无友,山至高无树;适度,不是中庸,而是一种明智的生活态度。

导读:本篇文章讲解 诠释serverCron函数在服务器的相关功能,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

目录

1.引言

2.serverCron的功能

2.1更新服务器时间缓存

2.2更新LRU时钟

2.3更新服务器每秒钟执行命令次数

2.4更新服务器内存峰值记录

         2.5处理sigterm

2.6管理客户端资源和数据库资源

2.7对持久化的影响

         2.8 增加cronloops的值


1.引言

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

2.serverCron的功能

2.1更新服务器时间缓存

Redis
服务器中有不少功能需要获取系统的当前时间,而每次获取系统的当前时间都需要执行一次系统调用,为了减少系统调用的执行次 数,服务器状态中的unixtime
属性和mstime属性被用作当前时间的缓存
truct redisServer {
// ...
//
保存了秒级精度的系统当前UNIX
时间戳
time_t unixtime;
//
保存了毫秒级精度的系统当前UNIX
时间戳
long long mstime;
// ...
};
因为
serverCron
函数默认会以每
100
毫秒一次的频率更新
unixtime
属 性和mstime
属性,所以这两个属性记录的时间的精确度并不高:
·
服务器只会在打印日志、更新服务器的
LRU
时钟、决定是否执行持久化任务、计算服务器上线时间(uptime)这类对时间精确度要求不高的功能上。
·
对于为键设置过期时间、添加慢查询日志这种需要高精确度时间 的功能来说,服务器还是会再次执行系统调用,从而获得最准确的系统当前时间

2.2更新LRU时钟

服务器状态中的
lruclock
属性保存了服务器的
LRU
时钟,这个属性 和上面介绍的unixtime
属性、
mstime
属性一样,都是服务器时间缓存的 一种
struct redisServer {
// ...
//
默认每10
秒更新一次的时钟缓存,
//
用于计算键的空转(idle
)时长。
unsigned lruclock:22;
// ...
};
每个
Redis
对象都会有一个
lru
属性,这个
lru属性保存了对象最后一 次被命令访问的时间
typedef struct redisObject {
// ...
unsigned lru:22;
// ...
} robj;
当服务器要计算一个数据库键的空转时间(也即是数据库键对应的 值对象的空转时间),程序会用服务器的lruclock
属性记录的时间减去 对象的lru
属性记录的时间,得出的计算结果就是这个对象的空转时间
redis> SET msg "hello world"
OK
#
等待一小段时间
redis> OBJECT IDLETIME msg
(integer)20
#
等待一阵子
redis> OBJECT IDLETIME msg
(integer)180
#
访问msg
键的值
redis> GET msg
"hello world"
#
键处于活跃状态,空转时长为0
redis> OBJECT IDLETIME msg
(integer)0
lruclock
时钟的当前值可以通过
INFO server
命令的
lru_clock
域查看
redis> INFO server
# Server
...
lru_clock:55923

2.3更新服务器每秒钟执行命令次数

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

redis> INFO stats
# Stats
...
instantaneous_ops_per_sec:6

解析上面的命令结果显示,在最近的一秒钟内,服务器处理了大概六个命令

2.4更新服务器内存峰值记录

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

每次serverCron函数执行时,程序都会查看服务器当前使用的内存 数量,并与stat_peak_memory保存的数值进行比较,如果当前使用的内 存数量比stat_peak_memory属性记录的值要大,那么程序就将当前使用 的内存数量记录到stat_peak_memory属性里面

INFO memory命令的used_memory_peak和 used_memory_peak_human两个域分别以两种格式记录了服务器的内存 峰值

redis> INFO memory
# Memory
...
used_memory_peak:501824
used_memory_peak_human:490.06K

2.5处理sigterm

在启动服务器时,Redis会为服务器进程的SIGTERM信号关联处理 器sigtermHandler函数,这个信号处理器负责在服务器接到SIGTERM信 号时,打开服务器状态的shutdown_asap标识

// SIGTERM
信号的处理器
static void sigtermHandler(int sig) {
//
打印日志
redisLogFromHandler(REDIS_WARNING,"Received SIGTERM, scheduling shutdown...");
//
打开关闭标识
server.shutdown_asap = 1;
}

每次serverCron函数运行时,程序都会对服务器状态的 shutdown_asap属性进行检查,并根据属性的值决定是否关闭服务器

truct redisServer {
// ...
//
关闭服务器的标识:
//
值为1
时,关闭服务器,
//
值为0
时,不做动作。
int shutdown_asap;
// ...
};

2.6管理客户端资源和数据库资源

1.管理客户端

erverCron函数每次执行都会调用clientsCron函数,clientsCron函数 会对一定数量的客户端进行以下两个检查:

·如果客户端与服务器之间的连接已经超时(很长一段时间里客户 端和服务器都没有互动),那么程序释放这个客户端。

·如果客户端在上一次执行命令请求之后,输入缓冲区的大小超过 了一定的长度,那么程序会释放客户端当前的输入缓冲区,并重新创建 一个默认大小的输入缓冲区,从而防止客户端的输入缓冲区耗费了过多 的内存

2.管理数据库

serverCron函数每次执行都会调用databasesCron函数,这个函数会 对服务器中的一部分数据库进行检查,删除其中的过期键,并在有需要时,对字典进行收缩操作,

2.7对持久化的影响

1.执行被延后的BGrewriteaOF

在服务器执行BGSAVE命令的期间,如果客户端向服务器发来 BGREWRITEAOF命令,那么服务器会将BGREWRITEAOF命令的执行 时间延迟到BGSAVE命令执行完毕之后

服务器的aof_rewrite_scheduled标识记录了服务器是否延迟了 BGREWRITEAOF命令

struct redisServer {
// ...
//
如果值为1
,那么表示有 BGREWRITEAOF
命令被延迟了。
int aof_rewrite_scheduled;
// ...
}

2.检查持久化操作的影响

服务器状态使用rdb_child_pid属性和aof_child_pid属性记录执行 BGSAVE命令BGREWRITEAOF命令的子进程的ID 这两个属性也可 以用于检查BGSAVE命令或者BGREWRITEAOF命令是否正在执行

struct redisServer {
// ...
//
记录执行BGSAVE
命令的子进程的ID
:
//
如果服务器没有在执行BGSAVE
,
//
那么这个属性的值为-1
。
pid_t rdb_child_pid; /* PID of RDB saving child */
//
记录执行BGREWRITEAOF
命令的子进程的ID
:
//
如果服务器没有在执行BGREWRITEAOF
,
//
那么这个属性的值为-1
。
pid_t aof_child_pid; /* PID if rewriting process */
// ...
}

检查流程

诠释serverCron函数在服务器的相关功能

 3.将AOF缓冲区中的内容写入AOF文件

如果服务器开启了AOF持久化功能,并且AOF缓冲区里面还有待写 入的数据,那么serverCron函数会调用相应的程序,将AOF缓冲区中的 内容写入到AOF文件里面

2.8 增加cronloops的值

服务器状态的cronloops属性记录了serverCron函数执行的次数

struct redisServer {
// ...
// serverCron
函数的运行次数计数器
// serverCron
函数每执行一次,这个属性的值就增一。
int cronloops;
// ...
}

cronloops属性目前在服务器中的唯一作用,就是在复制模块中实 现“每执行serverCron函数N次就执行一次指定代码”的功能

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

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/129582.html

(0)
飞熊的头像飞熊bm

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!