栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Redis(十三),java高级特性面试

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Redis(十三),java高级特性面试

BGSAVE命令执行的服务器状态

BGSAVE命令是由子进程去执行的,所以在子进程创建RDB文件的过程,并不会阻塞Redis,Redis服务器仍然会继续处理客户端的命令请求,但是,在BGSAVE命令执行期间,服务器处理SAVE、BGSAVE、BGREWRITEAOF三个命令会和平时不一样。

首先,Redis在BGSAVE命令期间,客户端发送的SAVE命令会被服务器拒绝,服务器会禁止SAVE命令和BGSAVE命令同时执行,这种操作是为了避免父进程和子进程同时执行,即会同时调用两个rdbSave,防止产生竞争条件。

其次,在BGSAVE期间也是不可以执行客户端发送的BGSAVE,因为也是会产生竞争条件。

最后的就是BGREWRITEAOF和BGSAVE两个命令是不可以同时执行的,情况分以下两种

  • 如果BGSAVE命令正在执行,那么客户端发送的BGREWRITEAOF命令会被延迟到BGSAVE命令执行完毕之后执行

  • 如果BGREWRITEAOF命令正在执行,那么客户端发送的BUSAVE命令会被服务器拒绝

虽然BGREWRITEAOF和BGSAVE两个命令的实际工作都是由子进程执行的,这两个命令在操作方面并没有什么冲突的地方,但是不能同时执行他们只是一个性能方面的考虑,并发出两个子进程,并且这两个子进程都同时执行大量的磁盘写入操作,这会很消耗CPU资源,不是一个好主意(至于为什么更倾向于执行BGREWRITEAOF,可能Redis设计者觉得AOF的优先级比较高吧)。

RDB文件载入时的服务器状态

服务器在载入RDB文件期间,会一直处于阻塞状态,直到载入工作完成为止。

自动间隔性保存


SAVE命令与BGSAVE命令主要的区别其实就是SAVE命令是服务器进程去执行工作的,会阻塞服务器进程影响服务,而BGSAVE是服务器进程开启了另一个进程去执行的,不会影响服务器进程。

Redis允许用户通过设置服务器配置的SAVE选项,让服务器每隔一段时间自动执行一次BGSAVE命令,而且SAVE选项可以有多个保存条件(触发执行BGSAVE命令条件),只要其中一个条件被满足,服务器就会执行BGSAVE命令

redis默认的配置如下

那么只要满足以下三个条件之一,BGSAVE命令就会被执行

  • SAVE 900 1:服务器在900秒之内(15分钟),只要服务器进行了至少一次修改(新增修改和删除键)

  • SAVE 300 10:服务器在300秒之内(5分钟),只要服务器进行了至少十次修改(新增修改和删除键)

  • SAVE 60 10000:服务器在60秒之内(1分钟),只要服务器进行了至少一万次修改(新增修改和删除键)

每次触发都会重写RDB文件(原来的数据清空,完整将数据重新放入)

也就是60秒检查一次,300秒检查一次,900秒检查一次,符合条件就会重写RDB文件,重写了之后重新计算时间

设置保存条件

Redis服务器启动后,用户可以通过指定配置文件或者传入启动参数的方式去设置save选项

接着,服务器会根据save选项所设置的保存条件,设置服务器状态redisServer对象(前面提过其存储服务器状态,里面有数据库数组)里面的saveparams属性

struct redisServer{

//。。。

。。。

//记录了保存条件的数组

struct saveparam *saveparams;

};

saveparams参数是一个saveparam数组,一个saveparam保存了一个save选项设置的保存条件

struct saveparam{

//秒数

time_t seconds;

//修改数

int changes;

};

比如save 900 1,那么saveparam结构里面的属性就是seconds = 900,changes = 1。

像Redis的默认配置的话,saveparams结构就如下所示

dirty计数器和lastsave属性

除了saveparams数组外,redisServer里面还维持着一个dirty计数器以及一个lastsave属性

  • dirty,翻译过来就是脏嘛,脏其实就代表内存中的数据与磁盘中的数据不一致,dirty属性其实记录的是距离最近一次执行成功的BGSAVE和SAVE命令之后,服务器对数据库状态(所有的数据库)进行了多少次修改操作(新增、删除和修改键值对)

  • lastsave,翻译过来就是最新的一次保存,lastsave属性是一个UNIX时间戳,记录的是服务器上一次成功执行SAVE或者BGSAVE命令的时间戳

struct redisServer{

//…

//保存选项的数组

struct saveparam *saveprams;

//dirty计数器

long long dirty;

//lastsave属性

time_t lastsave;

//…

};

当服务器(所有数据库)执行了一个数据库修改命令后,dirty属性就会进行更新,命令修改了多少次数据库,dirty计数器的值就增加多少

举个栗子

//dirty属性加1

set msg hello

//dirty属性加3,新增了3个

sadd msg 1 2 3

当执行完了SAVE或者BGSAVE命令之后,dirty属性就会归0,lastsave属性就会记录此时完成命令的时间戳

检查条件是否满足

Redis服务器拥有一个周期性的函数serverCron,默认的是每隔100毫秒就会执行一次,这个函数用于对正在运行的服务器进行维护,它的其中一项工作就是检查save选项所设置的保存条件是否满足,如果满足的话,就执行BGSAVE命令

def serverCron();

//前面的执行操作

//遍历所有save选项去判断是否满足

for saveparams in server.saveparams;

//先计算

《一线大厂Java面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义》

【docs.qq.com/doc/DSmxTbFJ1cmN1R2dB】 完整内容开源分享

上次执行SAVE或者BGSAVE命令的时间间隔

//使用当前时间减去上一次在执行SAVE或者BGSAVE的时间(注意使用的是时间戳)

//这里是要将这个时间放在循环里面的,因为下一次save选项可能会基于此次执行SAVE或者BGSAVE

save_interval = unixtime_now() - server.lastsave;

//接下来就是一系列的判断

//判断时间和更改操作的数量是否达到save命令的选项

if(save_interval > saveparam.seconds and server.dirty >= saveparam.changes)

//执行BGSAVE

BGSAVE();

//更新最新一次BGSAVE或SAVE执行的时间,即lastsave属性

//更新dirty属性,为0

end if

//…

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/682835.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号