当前位置: 首页 > news >正文

Redis_12_持久化(1)

认识持久化

在MySQL的事务中,有4个比较核心的特性~

1、原子性

2、一致性

3、持久性 =》 (和我们下文要讲的持久化是一回事)

4、隔离性

我们知道把数据存储在硬盘上是持久的;而把数据存储在内存上是不持久的,重启进程/重启主机之后,数据是否存在是不确定的!!

而Redis是一个内存数据库,它是把数据存储在内存中的。而内存中的数据是不持久的,要想能够持久,就需要让redis把数据存储到硬盘上~

Redis相比于MySQL这样的关系型数据库,最明显的特点/优势 =》 效率高/快~~为了保证速度快,数据肯定还是得在内存中,但是为了持久,数据还得想办法存储在硬盘上……

那到底是存在硬盘还是存在内存中呢?

redis表示我全都要,把存在内存中的数据,在硬盘中也存一份,这样的两份数据,理论上是完全相同的,实际上可能存在一个小概率的差异,取决于咱们具体怎么进行持久化~

当插入一个新的数据的时候,就需要把这个数据,同时写入到内存和硬盘~说是两边都写,但是实际上具体怎么写硬盘还有不同的策略,主要是为了保证整体的效率足够高。当查询某个数据的时候,还是直接从内存中读取,硬盘的数据只是在redis重启的时候,用来恢复内存中的数据的~~

代价就是消耗了更多的空间,同一份数据,存储了两遍。但是,毕竟硬盘是比较便宜,这样的开销并不会带来太多的成本。

Redis实现持久化的策略

Redis实现持久化主要有两种策略:

1、RDB:定期备份,就像每个月我把资料整体得备份到这个备份盘中。

2、AOF :实时存储,只要我下载了一个资料,立即把这个资料往备份盘中进行拷贝。  

RDB

RDB详解

刚才我们讲了,RDB是一种定期备份的方式,那么它到底是怎么做的呢?

RDB会定期地把我们Redis内存中的所有数据,生成一个“快照”,都给写入硬盘中。相当于Redis给内存中当前存储的这些数据,赶紧拍个照片,生成一个文件存储在硬盘中。后续Redis一旦重启了,(内存数据就没了),就可以根据刚才的“快照”,就能把内存中的数据给恢复回来~

实现“定期”,又有两种方式:

1、手动触发

程序员通过redis客户端,执行特定命令,来触发快照生成。

save:执行save的时候,redis就会全力以赴地进行“快照生成”,此时就会阻塞redis地其他客户端地命令~如果当前的数据量比较大,就会导致keys * 的后果,因此,一般不建议使用save。

bgsave:这个命令能够在不会影响Redis服务器处理其他客户端的请求和命令的情况下去生成快照。

那这里Redis是怎么做到的呢?是不是在背后搞了个多线程啥的?

并不是,此处Redis是使用多进程的方式来完成并发编程,完成bgsave的。

工作流程:

1、执行bgsave命令,Redis父进程判断当前进程是否存在其他正在执行的子进程,如RDB/AOF子进程,如果存在bgsave命令直接返回。

2、父进程执行fork创建子进程,fork过程中父进程会阻塞,通过info stats命令查看latest_fork_usec选项,可以获取最近一次fork操作的耗时,单位为微秒。

3、父进程fork完成后,bgsave命令返回“Background saving started”信息并不再阻塞父进程以继续响应其他命令

4、子进程创建RDB文件,根据父进程内存生成快照文件,完成后对原有文件进行原子替换,执行lastsave命令可以获取最后一次生成RDB的时间,对应info统计的rdb_last_save_time选项。

5、进程发送信号给父进程表示完成,父进程更新统计信息。

Redis这里采用“写时复制”的机制生成RDB,避免阻塞主进程,流程如下:

1、主线程受到RDB触发信号(如定时任务、手动执行save)

2、主线程调用fork创建一个子进程(此处的子进程与父进程共享内存页,不占用额外内存,除非父进程进行修改)

3、子进程负责遍历内存数据,生成RDB文件并写入磁盘。

4、主线程继续处理客户端请求:若期间有数据修改,Redis会为修改的内存页创建“副本”,子进程仅操作原内存页(保证RDB快照是“fork时刻”的全量数据)

5、子进程完成RDB写入后,通知主线程并退出,旧RDB文件被新文件替代

2、自动触发

在Redis配置文件中,设置一下,让Redis每隔多长事件/每产生多少次修改就触发。


redis生成的rdb文件,是存放在redis的工作目录中的。也是在redis配置文件中进行设置的。

进入/etc/redis目录下,我们可以看到redis.conf(注意:这里如果是使用Xshell连接服务器,需要使用sudo -i切换为root身份连接服务器,才能进入当前目录!!!),这个是redis的配置文件!!!

我们使用vim命令进入查看:

这里的dir/var/lib/redis就是redis的工作目录。

进入当前的工作目录,可以看到当前目录下有一个dump.rgb文件,这个就是rgb机制生成的镜像文件,redis服务器默认是开启了rgb的。这是一个二进制的文件,把内存中的数据,以压缩(需要消耗一定的cpu资源,但是能够节省存储空间)的形式,保存到这个二进制文件中~~

我们vim进入这个rgb文件看看,注意:这里只能是看看,一旦把这个文件数据格式改坏了就麻烦了~~后续redis重启,就会尝试加载这个rgb文件(这个rgb文件,虽然咱们不主动去动它,但是也可能出现一些意外问题,一旦通过一些操作(比如一些网络传输)引起这个文件被破坏,此时redis服务器就无法启动),如果发现格式错误,就可能会加载数据失败~~

当执行rdb镜像操作的时候,此时就会把要生成的快照数据先保存到一个临时文件中,当这个快照生成完毕之后,再删除之前的rdb文件,把新生成的临时的rdb文件名字改成刚才的dump.rdb,也就是说,自始自终,rdb文件是只有一个的。

我们使用Xshell再开一个连接操纵Redis:

再进入rdb文件中看看当前的key和value是否被存储在rdb文件中:

可以看到当前数据并没有被存储进来,这是因为rdb文件中的数据,不是你这百年插入了数据就会立即更新的!

刚才我们也讲了rdb的触发时机可以分为手动(save,bgsave)和自动(配置文件中,进入设置)。

进入redis.conf中,可以看到当前字段:

我们刚才插入的几个键值对,没有手动触发rdb存储,也达不到自动触发的条件。

虽然此处的这些数值,都可以自由修改配置~~但是,此处修改上述数据的时候,要有一个基本原则:生成一次rgb快照,这个成本是比较高的成本,不能让这个操作执行的太频繁!!

正因为rdb生成的不能太频繁,这就导致,快照里的数据,和当前实时的数据情况可能存在偏差~~

从最后一行的配置中,我们得到:两次生成rdb之间的间隔,最少得是60s。这就可能会导致出现下图中的情况。

解决这个问题的办法:AOF(实时备份)。、

 RDB效果演示

1、手动执行save&bgsave触发生成快照

此时我们再查看rdb文件:

由于咱们这里的数据比较少,执行bgsave瞬间就完成了,立即查看应该是有结果的,如果以后咱们接触到的数据多了,执行bgsave就可能需要消耗一定的时间,立即查看不一定就是生成完毕了。

我们再重启下redis服务器:

进入redis中查看key还是否存在:

通过上述操作,就可以看到,redis再重新启动的时候加载了rdb文件的内容,恢复了内存中之前的状态了。

2、插入新的key,不手动执行bgsave重新启动redis服务器

咦?这里我们刚才没有执行bgsave!!但是key4仍然再重启之后存在!!

这是因为,redis生成快照操作,不仅仅是手动执行命令才触发,也可以自动触发!!

1、通过刚才配置文件中的save执行M时间内,修改N次……

2、通过shutdown命令(redis中的一个命令)关闭redis,也会触发。(service redis-server restart)(正常关闭)。

3、redis进行主从复制的时候,主节点也会自动生成rgb快照,然后把rdb快照文件内容传输给从节点。

下面我们来看一种没法自动触发的情况:

先在redis中设置key:

使用kill-9强制杀掉redis进程:

这里注意:如果使用的是centos系统,这里杀掉redis进程之后就不会显示了,而不是像此处一样显示另一个端口号!!!

查看key5是否存在:

3、bgsave操作流程是创建子进程,子进程完成持久化操作。持久化会把数据写入到新的文件中,然后使用新的文件替换旧的文件。

这里第一步的速度太快了(数据少),难以观察到子进程。而新的文件替换旧的文件,是很容易观察到的(克隆)。

可以使用linux的stat命令,查看文件的inode编号来观察是否是一个文件~~

在Linux文件系统中,文件系统的典型组织方式(ext4)主要是把整个文件系统分成了三个大部分~~

1、超级块(放的是一些管理信息)

2、inode区(存放inode节点。每个文件都会分配一个inode数据结构,包含了文件的各种元数据)

3、block区,存放文件的数据结构

使用bgsave命令,完成持久化操作:

再次使用stat命令:

此处文件内容和大小虽然是一样的,但是因为执行了bgsave,文件已经不是同一个文件了(inode编号,就相当于文件的身份标识)。

这里注意,如果直接使用save命令,此时是不会触发子进程&文件替换的,如果save就直接在当前进程中,往刚才的同一文件中写入数据了~~

4、通过配置自动生成rdb快照

这里我们修改为当更新两条数据之后就会自动生成rdb快照:

这里注意:配置文件修改之后,一定要重新启动服务器,才能生效!!

这里执行flushall也会清空rdb文件:

rdb文件:

此时我们插入两条数据,等待1分钟后,再重新查看rdb文件:

此处,可以使用该选项,关闭自动生成快照

5、如果把rdb文件,故意改坏了,会咋样?

手动地把rdb文件内容改坏。

然后通过kill进程的(如果通过service redis-server restart的方式重新启动,redis会重新生成快照)方式重新启动redis服务器:

此时,重新进入redis,发现redis没有受到啥影响,还是能够正常启动,还是正常获取到key~~这里redis会咋样,取决于rdb文件坏了的地方在哪~~刚才改坏的地方正好是文件末尾,对前面的文件没啥影响。如果是中间位置坏了可就不一定了

改完之后可以可以看到redis服务器挂了!!!

如何处理呢?

当redis服务器挂了的时候,可以看看redis日志,了解一下发生了啥~~

这个是日志文件本体,后面几个是压缩包!!!

拖到最后可以看到日志显示:rdb恢复数据过程中出现问题了!!

redis也为我们提供了rdb文件的检查工具,可以先通过检查工具,检查一下rdb文件格式是否符合要求:

这里的检查工具和redis服务器在5.0版本是同一个可执行程序。可以在运行时加入不同的选项,从而使用其中不同的功能~~

运行的时候,加入rdb文件作为命令行参数,此时就是以检查工具的方式来运行,不会真的启动redis服务器:

那我们的redis服务器还是起不起来怎么办?

在我们当前的情况下,直接把刚才改废了的redis文件删除即可……而到了公司的话,数据重要的情况下,我们可以看看有没有备份的文件,给他重新写回去就行了。但是,大家还是不要去动这里的rdb文件!!!!

http://www.dtcms.com/a/613951.html

相关文章:

  • stm32f4点灯
  • 自己做网站详细步骤电脑如何安装免费wordpress
  • 前端微前端样式隔离,CSS-in-JS方案
  • 【go.sixue.work】2.3 面向对象:结构体里的 Tag 用法
  • Halcon ROI 与图像仿射变换笔记
  • 软件设计师(软考中级)公式速记笔记
  • 电商网站开发过程手机推广app
  • 18.HTTP协议(三)
  • 产科信息管理系统,智慧产科源码,支持与医院HIS、EMR系统及国家级妇幼平台的数据对接
  • 在VPython中使用向量计算3D物体移动
  • R语言在线编译器 | 提供方便快捷的数据分析工具
  • YOLOv8多场景人物识别定位与改进ASF-DySample算法详解
  • 网网站基础建设优化知识成都感染人数最新消息
  • 电商网站建设实训要求威海好的网站建设公司哪家好
  • Ionic 安装指南
  • kubernetes 导入镜像tar包
  • 南通网站开发上海网站搭建
  • oracle 物化视图设置自动更新日志
  • Java测试题
  • YOLO v11的学习记录(五) 使用自定义数据从头训练一个实例分割的模型
  • 大模型Agent工作流设计模式深度解析:从ReAct到ReWOO的实践演进
  • redis的配置windows
  • 漯河英文网站建设秦皇岛陵县网站建设
  • HTML5+CSS3+JS小实例:螺旋鼠标轨迹
  • 长沙市云网站建设大型电商网站开发方案
  • 从一到无穷大 #57:Snowflake的剪枝方案
  • 网页网站的区别是什么最适合seo的wordpress主题
  • 深入理解 OverlayFS:用分层的方式重新组织 Linux 文件系统
  • 定制型网站制作公司织梦图片自适应网站源码
  • 解决mac端pycharm执行allure命令报错:returned non-zero exit status 127