Redis的持久化存储

2021年11月23日 阅读数:3
这篇文章主要向大家介绍Redis的持久化存储,主要内容包括基础应用、实用技巧、原理机制等方面,希望对大家有所帮助。

Redis的持久化

Redis 是一种内存型数据库,一旦服务器进程退出,数据库的数据就会丢失,为了解决这个问题, Redis 提供了两种持久化的方案,将内存中的数据保存到磁盘中,避免数据的丢失。python

RDB

RDB持久化既能够手动执行,有能够根据服务器配置预约项执行,该功能能够将某个时间点上的数据库信息保存到一个RDB文件中。mysql

RDB持久化功能所生成的RDB文件是一个通过压缩的二进制文件,经过该文件能够还原数据库中的数据。redis

由于RDB文件是保存在硬盘里面,全部即便Redis服务器进程退出,甚至运行Redis服务器的计算机停机,只要RDB文件仍然存在,Redis服务器就可使用它来还原数据库中的数据。sql

RDB文件的建立和载入

RDB文件的建立能够经过SAVE和BGSAVE命令来建立,其中SAVE命令会阻塞Redis服务的进程,直到RDB文件建立完毕为止,在阻塞期间服务器不能处理任何命令请求。shell

BGSAVE命令是经过派出一个子进程在后台负责建立RDB文件,服务器进程仍然能够继续处理请求,数据库

RDB文件的载入工做在Redis启动的时候,只要Redis服务器在启动的时候检测到RDB的存在,就会自动载入RDB文件恢复内存数据。缓存

若是服务器开启了AOF持久化功能,那么服务器会优先使用AOF文件来还原数据库的信息,只要AOF持久化功能处于关闭状态的时候,服务器才会使用RDB文件来恢复数据库状态,默认使用的是RDB持久化。安全

SAVE命令建立RDB文件

当SAVE命令执行的时候,Redis服务器会被阻塞,因此当SAVE命令在执行的时候,客户端发送的全部命令请求都会被拒绝。服务器

只有当SAVE命令执行完毕的时候,服务器才会接受和处理客户端发来的请求。app

BGSAVE命令建立RDB

因为BGSAVE命令建立RDB文件是由子进程执行的,因此在子进程建立RDB文件的过程当中,Redis仍然能够继续处理客户端的请求命令,可是若是在BGSAVE命令执行期间,是不会接受SAVE、BGSAVE命令的执行的。

自动间隔性保存

在咱们实际应用中不可能时常经过SAVE和BGSAVE命令来将数据保存到RDB文件的,Redis为咱们提供了便利,能够经过配置文件来让服务器执行BGSAVE命令。默认提供的配置信息以下:

daemonize yes # 守护进程执行,后台运行
bind 127.0.0.1 #redis绑定地址
port 6379 # 端口
requirepass 123 # 密码
logfile /data/6379/redis.log # 日志文件
dir /data/6379/ # 定义持久化文件存储位置
dbfilename dbmp.rdb # rdb持久化文件

save 300 10 # 若是300秒内有大于等于10次修改则进行一次持久化保存
save 900 1  # 服务器在900秒以内,对数据库进行了只是1次修改
save 300 10  # 服务器在300秒以内,对数据库进行了只是10次修改
save 60 10000  # 服务器在60秒以内,对数据库进行了只是10000次修改

注:若是写入持久化配置文件,那么咱们启动时就不能直接使用redis-server。咱们须要从写入配置的文件启动redis。redis-server /opt/xxx/xxx.conf

RDB:基于快照的持久化,速度更快,通常用做备份,主从复制也是依赖于rdb持久化功能

AOF

Redis提供的RDB持久化是将数据以二进制存储到后缀为rdb的文件中,AOF持久化则是经过将全部的对数据库写入操做的命令存储到aof文件中实现持久化。

实现原理

AOF持久化功能的实现能够分为命令追加/文件写入/文件同步三个步骤。

命令追加

当AOF持久化功能处于开启状态的时候,服务器在执行完一个写命令后,会以协议格式将被执行的写命令追加到服务器状态的aof_buf缓冲区中。

文件写入与同步

当命令追加到aof_buf缓冲区后,服务器就会调用flushAppendOnlyFile函数,根据配置的策略决定是否将缓冲区中的内容写入和保存到AOF文件中。具体策略以下:

daemonize yes # 守护进程执行,后台运行
bind 127.0.0.1 #redis绑定地址
port 6379 # 端口
requirepass 123 # 密码
logfile /data/6379/redis.log # 日志文件
dir /data/6379/ # 定义持久化文件存储位置
appendonly  yes

appendfsync  always   # 老是修改类的操做
		    everysec # 每秒作一次持久化
			no  # 依赖于系统自带的缓存大小机制
Always:每次写操做完成都同步一次aof_buf数据到AOF文件
everysec:由线程负责,每秒同步一次aof_buf数据到AOF文件
no:何时同步aof_buf数据到AOF文件由操做系统控制

AOF文件的载入与数据还原

AOF持久化一旦开启,那么RDB持久化就失效。因此Redis在重启的时候,若是发现AOF持久化开启,就会读取AOF文件恢复数据状态,而忽略RDB文件。一开始就说过了AOF持久化是经过将数据库的写命令保存起来实现的,因此Redis只须要将AOF文件中的命令执行一遍就能够恢复数据库数据状态。

AOF重写

既然知道AOF是将写命令存储到AOF文件中实现持久化,那么就应该会想到AOF文件体积愈来愈大,一旦达到某个量级,重启Redis的时间必将严重增长。

为了解决这个问题,Redis提供了AOF文件重写功能。经过该功能,能够建立一个新的AOF文件替换现有的AOF文件,两个AOF文件的数据库数据一致,可是新的AOF文件不会包含浪费空间的冗余命令。并且提交会比旧的AOF文件小的多。

AOF重写实现原理

AOF文件从新并不须要对现有的AOF文件进行任何读取,分析或者写入操做,而是经过读取当前数据库的数据来完成的。简单总结就是:读取当前数据库中键现有的值,而后用一条命令去记录键值对,代替以前记录这个键值对的多条命令。

AOF重写过程数据不一致

为何会出现重写后AOF数据不一致的问题呢?咱们能够这样思考:

1)Redis后台进程处理AOF重写。

2)对key1={"1", "2","3"}这个键值对完成了重写。

3)用户对key1这个键执行了删除3这个值。

4)重写完成。这样致使的缘由是在AOF重写过程当中,有用户对数据库从新执行了写操做,致使从新的AOF文件不一致。

针对这个问题,Redis服务器设置了一个AOF重写缓冲区,这个缓冲区在服务器建立子进程以后开始调用,当Redis服务器执行完一个写命令后,它会同时将这个命令发送给AOF缓冲区和AOF重写缓冲区。在AOF重写完成后,会执行AOF重写缓冲区的命令确保数据库数据的一致性。

AOF和RDB的区别

RDB

优势:基于快照的持久化,数据恢复速度更快,通常用做备份,主从复制也是依赖于rdb持久化功能。

缺点:若是服务器宕机,可能会形成一段时间内的数据丢失。

AOF

优势:以追加的方式记录redis操做日志的文件。能够最大程度的保证redis数据安全,相似于mysql的binlog。

缺点:AOF生成的日志文件太大,即便经过重写,文件体积仍然很大。数据恢复速度比RDB慢。

##rdb模式下的redis持久化,不重启切换为 aof模式

CONFIG set appendonly yes #开启AOF功能
CONFIG SET save "" #关闭RDB功能

注:执行完上述命令,还要更改配置文件为AOF模式,才是真的永久切换

参考:https://blog.csdn.net/sinat_32366329/article/details/81266568