Redis(十三,java面试简历项目

2021/12/29 19:10:17

本文主要是介绍Redis(十三,java面试简历项目,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

Redis提供了RDB持久化功能,这个功能可以将Redis在内存中的数据库状态保存到磁盘里面去,避免数据意外丢失。

RDB持久化既可以手动执行,也可以根据服务器配置选项定期执行,该功能可以将某个时间点上的数据库状态保存到一个RDB文件中

RDB持久化功能所生成的RDB文件是一个经过压缩的二进制文件,通过该文件可以还原生成RDB文件时的数据库状态

RDB文件是保存在硬盘里面的,所以即使Redis服务器进程退出,甚至运行Redis服务器的计算机停机,但只要RDB文件仍然存在,Redis服务器就可以用他来还原数据库状态。

RDB文件的创建与载入


创建(SAVE与BGSAVE)

有两个Redis命令可以用于生成RDB文件,一个是SAVE,另一个是BGSAVE。

SAVE命令会阻塞Redis服务器的进程,知道RDB文件创建完毕,在服务器进程阻塞期间,服务器不能处理任何命令请求的

//执行save命令,RDB进行持久化生成RDB文件

save

和SAVE命令直接阻塞服务器进程的做法不同,BGSAVE命令会派生出一个子进程,然后由子进程负责创建RDB文件,服务器进程继续处理命令请求。

这里涉及到两个问题?为什么是进程,而不是开线程(消耗更少资源,一个进程包含多个线程)

这是因为Redis是单线程的,不可能开多一个线程

Redis为什么是单线程?

Redis是一个内存型数据库,数据都是从内存上读取的,所以CPU并不是他的上限瓶颈,因为CPU读内存是很快的,足够应付大流量,Redis的上限瓶颈是内存的大小,所以只需要一个单线程就足够了,不需要开多个线程去访问内存加快速度

所以BGSAVE是派生出一个子进程去执行创建RDB文件。

在这里插入图片描述

创建RDB文件的实际工作是由rdb.c/rdbSave函数完成,SAVE命令和BGSAVE命令会以不同的方式去调用这个函数。下面用伪代码去表示两者不同

def SAVE():

//创建RDB文件

rdbSave()

End SAVE;

def BGSAVE():

//创建子进程

pid = fork()

if pid == 0:

//成功创建到子进程

//让子进程去创建RDB文件

rdbSave()

//完成之后向父进程发送信号

signal_parent()

elif pid > 0:

//子进程数量太多,轮询等待子进程创建成功

//父进程继续处理命令请求,并通过轮询等待子进程的信号

handle_requeset_and_wait_signal()

else:

//子进程为负数

//处理出错情况

handle_fork_error()

End BGSAVE;

载入RDB文件

RDB文件的载入工作是在服务器启动时自动执行的,所以Redis并没有专门用于载入RDB文件的命令,只要Redis服务器在启动时,只要检测到RDB文件存在,就会自动载入RDB文件

另外值得一提的是,因为AOF文件的更新频率通常比RDB文件的更新频率高,所以:

  • 如果服务器开启了AOF持久化功能,那么服务器会优先用AOF文件来还原数据库的状态

  • 只有在AOF持久化功能处于关闭状态时,服务器才会使用RDB文件来还原数据库状态

在这里插入图片描述

SAVE命令执行时的服务器状态

当SAVE命令在执行时,Redis服务器会被阻塞,当SAVE命令正在进行时,客户端发送的所有命令请求都会被阻塞,直到SAVE命令执行完成,重新开始接收命令请求之后,客户端发送的命令才会被处理

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两个命令的实际工作都是由子进程执行的,

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

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

这两个命令在操作方面并没有什么冲突的地方,但是不能同时执行他们只是一个性能方面的考虑,并发出两个子进程,并且这两个子进程都同时执行大量的磁盘写入操作,这会很消耗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;

};



这篇关于Redis(十三,java面试简历项目的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程