Redis-持久化

众所周知,Redis常常用来作为缓存、内存数据库、消息队列......这都由于Redis是将数据存储在内存上的,因此访问速度就会比MySQL这样的数据库快。

但数据储存在内存上就会有一个非常致命的缺点:掉电就没了。

试想一下,当我们将很多数据储存在Redis中,还没来得及使用,突然停电了,再打开主机启动服务之后,啥都没了,这得多难受。为了应对这种情况,Redis在背后就搞了一系列的机制来进行数据持久化,保证Redis服务器的高可用~

简介

Redis实现持久化的时候主要是按照两个策略来做的:RDB,AOF

RDB:Redis DataBase -> 定期备份

AOF:Append Only File -> 实时备份

当我们插入一个数据的时候,首先会在内存中存储一份,然后再在硬盘上存一份,虽然一份数据存了两份,但提高了可用性。当我们查询数据的时候,会先从内存中去查,当服务器进行重启的时候,则会从硬盘上将原有的数据读取到内存中~

RDB

RDB指的是对Redis内存中的数据定期的写入硬盘,进行备份保存,生成一个快照文件。具体触发保存的方式有两种:手动触发、自动触发.

手动触发

1)手动触发,程序员通过执行命令才触发保存

save:执行save的时候,redis服务器会全力去执行备份操作,当数据量多的时候,执行时间就会延长,就会阻塞其他客户端的操作,导致出现bug(与keys * 操作一样,也是个比较危险的操作)

bgsave:与save相对,不会影响其他客户端的操作,通过”多进程“的方式来实现备份.

父进程通过fork指令(写时拷贝),创建了一个长得一模一样的子进程(内存地址、PCB都相同,为了减小开销),当父进程中有变量被修改,子进程才会去重新创建,防止冲突。

执行流程如下:

首先Redis服务器收到了bgsave命令,会先去判断当前是否存在正在执行备份操作(RDB/AOF)的子进程,如果存在,则返回。如果不存在则继续。

父进程调用fork,创建子进程(写时拷贝的方式,不会太影响效率),然后父进程就可以继续去接受客户端的其他命令了。子进程将内存中的数据写入到新生成的RDB文件中,然后再将旧的RDB文件进行替换。

自动触发

2)自动触发,可以在配置文件中进行设置,每隔多长时间/每产生多少次修改进行一次触发

redis配置文件在linux中存放的路径:/etc/redis

我们不用刻意去记这个路径,可以用过指令来查找:

-> whereis redis

配置文件中默认的进行自动触发的配置如下:

解释:

save <seconds> <changes> 表示 每多少秒 且 这一秒修改了几次,就进行一次持久化操作.

save 900 1 表示 每900秒(15min) 且 进行了一次修改key的操作进行一次保存.

RDB文件

RDB是一个保存了压缩形式二进制的文件。当Redis服务器进行重启的时候,就会去加载这个文件,由于是二进制文件,加载的速度相较于AOF文件是更快的。

RDB文件存储位置:/var/lib/redis

文件内容:

由于是压缩形式的二进制文件,我们很难观察出里面的内容。

如果我们对这个文件进行修改呢?

1.如果是在已有的数据中进行修改,会在redis重启的时候,启动失败,提示文件错误

2.如果是在这个文件的末尾进行添加,此时redis可以启动。

综上,把错误的RDB文件去交给Redis,得到的结果是不可预期的。我们可以使用Redis提供的工具来检查一下这个二进制文件:

redis-check-rdb xxxx.rdb

如果rbd文件错误,就会显示如下信息:


RDB文件的优缺点:

1.RDB是一个压缩的二进制文件,数据加载的速度远快于AOF文件加载速度。

2.RDB文件做的是一个定期备份的事情,里面的数据表示的是某一时间点中Redis的数据,适合用于全量备份。

3.RDB的初心本就是定期备份,并且需要创建进程进行备份,无法做到实时性,可能存在数据丢失。

4.RDB是二进制文件,可能在某些Redis版本中RDB的文件格式会出现不一致,兼容性不能保证。

AOF

AOF是以独立日志的方式记录每次写命令,主要用于解决Redis数据持久化的实时性。

AOF默认是关闭状态,需要通过修改配置文件来开启。

cd /etc/redis

vim redis.conf

将no改为yes,就可以开启了。修改完了之后,要想生效,需要重启服务器。

service-redis-server restart

AOF的文件也是跟RDB在同一个地方的,即/var/lib/redis。

AOF是一个文本文件,会将每次操作进行记录。


AOF执行流程

Redis本身是一个单线程模型,如果对于每个命令都去访问一次IO设备,那么效率会大大下降。因此就在内存中搞了一个缓冲区,先将命令写入缓冲区,然后再将缓冲区的数据一下子写入到文件中。此处的rewrite操作是为了给文件“瘦身”(例如:一 增一删,相当于没有),当redis服务器重启的时候,就会去读AOF文件中的数据(当开启AOF的时候,Redis重启读数据就会以AOF为准).

AOF机制为了提高效率,会将数据先写到缓存中,如果此时断电了,缓冲区在内存中,未写入硬盘,此时也就没有了~ 虽然AOF是实时备份,但为了效率也不得不进行取舍。

不过Redis也在内部提供了一些数据同步策略。当然也在 /ect/redis/redis.conf 文件中

策略:

配置值 说明
no 不主动进行同步,让OS来控制,最快最不可靠
always 每次写入都进行同步,最慢最可靠
everysec 每秒进行一次同步,中庸之道~

AOF重写机制

通过观察上述AOF文件中的内容,我们会发现,里面记录了每次指令的操作,如:select、set、del.....

AOF是用来进行持久化数据,以便下次Redis服务器进行重启的时候恢复数据

当出现如下指令的时候:

set k1 100  #add
get k1      #select
del k1      #delete

虽然AOF文件中记录了上述指令,但记录了个寂寞~当下次重启的时候啥也不会恢复,并且记录了这么多指令,会大大提高文件的大小。因此就需要用来重写机制,来将一些操作进行合并,只需关注最终结果即可~~

出发重写机制也有两种方式:手动触发、自动触发


手动触发

通过调用bgrewriteaof指令,进行重写。

AOF重写流程:

1.首先父进程收到bgrewriteaof命令,调用fork,创建子进程。

2.子进程根据当前内存中的key,写入到新的AOF文件。

3.父进程继续接受客户端的指令,会将指令写入到缓冲区和重写指令缓冲区

4.当子进程数据已经写完的时候,告诉父进程,然后父进程会将重写指令缓冲区的数据写入到新的AOF文件,最后将新的AOF文件替换旧的AOF文件。

在RDB中,对于fork以后得数据,就不会去管理了,在AOF中会先写入到缓冲区中~

父进程继续将数据写入到旧的AOF文件是否有意义?最后会被新的AOF文件替换。

如果遇到掉电的情况,子进程由于没有保存,新的AOF文件数据全都丢了,如果父进程不去写旧的AOF文件的话,重启的时候恢复的数据会有问题,无法保证数据完整性~

自动触发

通过设置auto-aof-rewrite-percentage 和 auto-aof-rewrite-min-size 这两个属性来进行配置。

auto-aof-rewrite-percentage:表示当前AOF占用大小相较于上次重写是增加的比例。

auto-aof-rewrite-min-size:表示触发重写时AOF的最小文件大小。

混合持久化

AOF本来是按照文本的方式记录数据的,但后续服务器加载文本文件成本比较高,redis就引入了“混合持久化”。

先按照AOF的方式,记录每一个操作,然后在重写的时候,将内存中的key用rdb文件-压缩二进制的方式进行记录,然后保存在AOF文件中。

因此我们有时候也会在AOF见到类似RDB文件中的数据。

相关推荐

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-06-07 06:34:03       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-06-07 06:34:03       106 阅读
  3. 在Django里面运行非项目文件

    2024-06-07 06:34:03       87 阅读
  4. Python语言-面向对象

    2024-06-07 06:34:03       96 阅读

热门阅读

  1. Android中ANR的分析和解决

    2024-06-07 06:34:03       25 阅读
  2. 人机验证问题库

    2024-06-07 06:34:03       28 阅读
  3. Pytorch语义分割(2)--------模型搭建

    2024-06-07 06:34:03       33 阅读
  4. ChatGPT-3

    2024-06-07 06:34:03       33 阅读
  5. QT之全局忽略编译警告QMAKE_CXXFLAGS

    2024-06-07 06:34:03       31 阅读
  6. Ubuntu禁止内核自动更新

    2024-06-07 06:34:03       24 阅读
  7. nginx如何编译安装?

    2024-06-07 06:34:03       29 阅读
  8. 【Android】点击图片获取点击位置在图片中的位置

    2024-06-07 06:34:03       32 阅读
  9. electron录制工具-准备录制mask

    2024-06-07 06:34:03       28 阅读
  10. 一些关于科技的想法

    2024-06-07 06:34:03       33 阅读
  11. 使用docker直接运行不同版本nodejs命令

    2024-06-07 06:34:03       36 阅读