Redis数据库持久化

2022-09-08 10:37:14

一、Redis概述

  • Redis是一种高级键值对的非关系型数据库,同时也是一个高速缓存数据库

  • Redis和memcache很相似,不同的是,Redis的数据可以持久化,而且支持的数据类型很丰富

  • Redis的数据类型有字符串、列表、集合、有序集合,支持在服务器端计算集合的并、交和补(差)集,还支持多种排序功能,所以Redis也可以被看作是一个数据结构服务器

二、Redis的持久化

  • Redis的所有数据都是保存在内存中,如果没有配置持久化,Redis重启后数据就会丢失,所以需要开启Redis的持久化功能,将内存中的数据保存在硬盘上,在Redis重启之后,可以从硬盘中恢复数据到内存中,而这个过程是分为两种模式的:

半持久化模式:不定期的通过异步同步的方式把内存中的数据保存到硬盘上,也叫RDB模式

全持久化模式:把内存中每一次数据的变化都写入到一个append only file(AOF文件)里面,也叫AOF模式

(1)持久化过程

  1. 客户端向数据库服务器发送写操作,写的数据保存在客户端的内存中
  2. 数据库服务器接收到客户端写请求的操作,写操作的数据保存在服务器的内存中
  3. 服务器调用write这个系统进程,将内存中的数据往硬盘上写,数据会先到系统内存的缓冲区中
  4. 系统将缓冲区中的数据转移到磁盘控制器上,数据会到磁盘缓存中
  5. 磁盘控制器将数据写到磁盘的物理介质中,这个时候数据才是真正的保存到了磁盘中

上面的五个步骤是理想的数据保存流程,但是在大多数情况下,实际的服务器会有各种各样的故障,下面是出现故障后持久化成功的的两种情况

  1. Redis数据库发生故障,只需要完成上面的前三个步骤,那么就可以完成持久化,剩下的操作是由系统完成的
  1. 如果系统发生故障,就必须上面的五个步骤全部完成,数据才可以完成持久化

这两中情况只是说了保存过程中可能发生的故障,但是其实保存的数据也有可能发生损坏,需要一定的恢复机制

Redis有两种策略机制来实现持久化的五个步骤,分别是RDB和AOF,通过配置redis.conf主配置文件来配置两种持久化方式,两种持久化方式同时开启时,AOF的优先级高一点

(2)RDB机制

  • RDB的数据保存机制其实就是把数据以快照的形式保存在磁盘上,这个快照和虚拟机的快照的含义是相似的,需要注意的是每次生成的RDB文件会把旧的RDB文件顶掉,也就说只有一份RDB文件

  • RDB持久化是指在指定时间间隔内将内存中的数据集快照写入磁盘,也是Redis默认的持久化方式,这种方式就是将内存中的数据以快照的方式写入到二进制文件中,默认的文件名称为dump,rdb

  • 既然RDB的保存机制是指定时间间隔内把数据生成快照来保存,那么肯定会有一个触发机制,对于RDB来说,Redis提供了三种机制,分别是:save、bgsave、自动化

-save触发方式

当有一个客户端向Redis发送命令后,该命令会阻塞Redis服务器,在执行Save机制(保存数据到RDB文件)的过程中,Redis是不能执行其他命令的,直到保存完成后才可以

当Redis在保存RDB文件时,如果已经存在之前保存的RDB文件,那么Redis就会把新的文件顶替掉旧的文件,实际环境中,Redis接收到的客户端请求可能是几万甚至几十万,这种方式显然是不可取的

-bgsave触发方式

在这里插入图片描述

使用bgsave后,客户端发送的操作,Redis会在后台进行异步快照保存,而且Redis还可以继续接受其他客户端的操作

当客户端发送操作到Redis服务器时,在Redis执行操作后,会执行fork()操作创建子进程,RDB的持久化操作由子进程完成,在子进程完成操作后,会自动结束。这个过程中的阻塞只发生在子进程的阶段,基本上Redis内部所有的RDB操作都是采用bgsave完成的

-自动化

自动化也就是自动触发,是由Redis的主配置文件Redis.conf来完成的,可以配置如下选项:

  1. save:

这里是用来配置触发Redis的持久化条件的,也就是什么时候把内存中的数据保存到硬盘中,格式为save m n,当m秒之内发生了n个数据的变化,就把数据保存到硬盘中,并且采用机制是bgsave,如果不需要持久化可以把所有的save行注释掉来停用此功能

  1. stop-writes-on-bgsave-error:

此选项的默认配置为yes,意思是当启动了RDB并且在最后一次后台保存数据失败时,Redis是否停止接收数据,配置yes可以让管理人员意识到数据没有正确的持久化到硬盘上,否则配置no的话会使管理人员无法意识到事故发生。在停止接收数据后只需要重新启动Redis,就可以重新开始接收数据了

  1. rdbcompression

此选项的默认值为yes,意思是是否对存储到磁盘中的快照进行压缩存储

  1. rdbchecksum

此选项的默认值为yes,意思是在存储快照后,是否让redis使用crc64算法来进行数据校验,开启后会增加大约百分之十的性能消耗,如果需要redis达到最大性能,可以关闭此选项

  1. dbfilename

配置快照的文件名,默认是dump.rdb

  1. dir

设置快照保存的路径,这个路径必须是目录,而不是文件名,默认是保存到当前目录./

对比save和bgsave:

命令savebgsave
同步方式(IO类型)同步异步
是否阻塞阻塞阻塞(发生在子进程)
优点不会消耗额外内存不阻塞客户端,可以继续接收命令
缺点阻塞客户端命令需要子进程,消耗内存

-RDB的优势和劣势

  • 优势:
  1. RDB文件紧凑,并且是全量备份,非常适合用于备份和灾难恢复
  2. 在使用bgsave机制生成RDB文件的时候,redis主进程会新建一个子进程来处理所有的数据保存工作,主进程不需要进行任何的磁盘IO操作,并且可以继续接收其他客户端的操作
  3. RDB在恢复大数据集时的速度要比AOF快的
  • 劣势:
  1. 生成的RDB快照是一次全量备份,存储的是内存数据的二进制序列化形式,在存储上十分紧凑。
  2. 在进行快照持久化时,会开启一个子进程专门进行快照持久化,在这个期间主进程修改数据在子进程中是不会反应出来的,也就是说在数据持久化期间的数据不会被保存,可能会丢失数据。并且当数据集较大的时候,可以会导致整个服务器停止服务几百微秒甚至一秒

(3)AOF机制

  • 全量备份总是耗时的,而AOF提供了一种更为高效的方式,工作机制非常简单,redis会把收到的每一个写命令都通过write函数追加到指定的文件中,这个和mysql的二进制日志很是相似

  • AOF持久化方式:

在这里插入图片描述

每当Redis收到一条写命令时,Redis就会记录到AOF文件中

-文件重写

AOF的持久化方式也带来了一个问题,持久化的AOF文件会越来越大,为了压缩AOF持久化文件,Redis提供了bgrewriteaof命令,将当前内存中的数据以命令的方式保存到临时文件中时,同时会创建一个新的子进程来将文件重写到一个新的AOF文件中,这个方式有点类似于快照

在这里插入图片描述

-AOF的三种触发机制

  1. 每次修改都同步(always):同步持久化,每次数据发生变化时会被立刻记录到磁盘上,性能较差但是数据完整性好

  2. 每秒同步(everysec):异步同步,每秒都会记录,但是如果在一秒内Redis服务器宕机,那么就会丢失一秒的数据

  3. 从不同步(no):从不同步,这里指的是由系统决定什么时候同步

比对三种机制:

命令alwayseverysecno
优点不丢失数据每秒一次同步不用进行管理
缺点性能较差最多会丢失一秒的数据不可控制

-AOF的优点和缺点

  • 优点:
  1. AOF可以更好的保护数据不丢失,一般AOF会每隔一秒,然后通过一个后台线程执行一次同步操作,所以说最多丢失一秒的数据
  2. AOF日志文件没有任何磁盘寻址的开销(日志文件位置是自己指定的),写入性能非常高,文件不容易损坏
  3. AOF日志文件出现后台重写操作时,是不会影响客户端的读写的
  4. AOF日志文件是记录命令的,这个特性十分适合做灾难恢复性的误删除和紧急恢复,例如:某人不小心使用了flushall命令清空了所有数据,这个时候只要重写操作没有发生,就可以立即拷贝AOF文件,删除最后一条的flushall命令然后再把AOF文件放回去,就可以通过恢复机制,恢复数据库
  • 缺点:
  1. 对于同一份数据来说,AOF的文件通常要比RDB的快照文件更大
  2. AOF开启后,支持的写的QPS(每秒查询率)会比RDB写的QPS低,因为AOF一般都会配置成每秒同步一次文件,当然,每秒一次的同步,性能消耗也不会很高

(4)选择RDB还是AOF

  1. 愿意牺牲一些性能的,可以选择AOF
  2. 换取更高的缓存一致性,保证数据库最高可能的完整性,选择AOF
  3. 愿意写操作频繁的时候,不启用备份来换取更高的性能,在手动运行save的时候再做备份,选择RDB

通常来说两者一起使用效果是最好的,但是同时开启两种方式的话,只有AOF会生效,Redis默认使用RDB,AOF配合RDB时,两者开启可以手动运行save

三、RDB持久化配置

准备Reids:

[root@Centos7 ~]# vim /usr/local/redis/redis.conf
。。。。。。217218 save9001#开启RDB后,在900秒内发生1个数据的变化就触发生成快照219 save30010220 save6010000221 
。。。。。。234# permissions, and so forth.235 stop-writes-on-bgsave-erroryes#当RDM快照失败后,不影响用户得写操作236 
。。。。。。240# the dataset will likely be bigger if you have compressible values or keys.241 rdbcompressionyes#是否将RDB快照文件压缩,关闭后会增加性能242 
。。。。。。250 rdbchecksum no#关闭RDB快照的检查校验,会增加性能251252# The filename where to dump the DB253 dbfilename dump.rdb#快照的名称254 
。。。。。。262# Note that you must specify a directory here, not a file name.263dir /usr/local/redis/rdb#快照的存放路径264 
。。。。。。#保存退出[root@Centos7 ~]# mkdir /usr/local/redis/rdb[root@Centos7 ~]# /etc/init.d/redis start   #开启redis
/var/run/redis_6379.pid exists, process is already running or crashed
Redis is running...[root@Centos7 ~]# redis -h 192.168.100.202 -p 6379  #进入redis写数据192.168.100.202:6379> auth123123
OK192.168.100.202:6379>set aaa bbb
OK192.168.100.202:6379>set bbb ccc
OK192.168.100.202:6379> keys *1)"aaa"2)"bbb"192.168.100.202:6379>exit[root@Centos7 ~]# /etc/init.d/redis restart   #重启redis
Stopping...
Warning: Using a password with'-a' or'-u' option on thecommand line interface may not be safe.
Redis stopped
Starting Redis server...1073:C 05 Jun202121:54:27.156# oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo1073:C 05 Jun202121:54:27.156# Redis version=5.0.4, bits=64, commit=00000000, modified=0, pid=1073, just started1073:C 05 Jun202121:54:27.156# Configuration loaded
Redis is running...[root@Centos7 ~]# redis -h 192.168.100.202 -p 6379  #再次进入查看数据还在不在192.168.100.202:6379> auth123123
OK192.168.100.202:6379> keys *1)"aaa"2)"bbb"#发现数据存在,redis的数据是存放到内存的,不配置持久化的话,重启redis数据就会丢失,但是开启了RDB持久化机制,并且配置文件中配置了每600秒发生一次数据的变化就拍摄快照,刚才写了两个数据,写完之后Redis其实已经拍摄完快照并且保存在指定路径下,所以在重启Redis后数据还是存在的192.168.100.202:6379>exit[root@Centos7 ~]# ll /usr/local/redis/rdb/
总用量4
-rw-r--r--1 root root1156521:54 dump.rdb

四、AOF持久化配置

[root@Centos7 ~]# vim /usr/local/redis/redis.conf
。。。。。。217218#save 900 1     #把save向全部注释表示关闭RDB持久化方式219#save 300 10220#save 60 10000221 
。。。。。。262# Note that you must specify a directory here, not a file name.263dir /usr/local/redis/rdb#这个同时也是AOF文件的存放路径264 
。。。。。。698699 appendonlyyes#开启AOF持久化方式700701# The name of the append only file (default: "appendonly.aof")702703 appendfilename"appendonly.aof"#设置持久化的文件704 
。。。。。。728# appendfsync always729 appendfsync everysec#设置AOF持久化的方式,默认就是everysec每秒一次730# appendfsync no731 
。。。。。。750751 no-appendfsync-on-rewrite no#如果设置为yes,则redis执行的命令会存放到缓冲区,等待系统自动同步到硬盘,no就可以752 
。。。。。。769770 auto-aof-rewrite-percentage100#若当前写入的AOF文件达到了上次重写文件的大小的100%的话,就触发重写771 auto-aof-rewrite-min-size 64mb#设置AOF持久化重写文件大小的最小值,当达到64MB并且符合100%时,就触发重写操作772 
。。。。。。#保存退出[root@Centos7 ~]# /etc/init.d/redis restart
Stopping...
Warning: Using a password with'-a' or'-u' option on thecommand line interface may not be safe.
Redis stopped
Starting Redis server...1122:C 05 Jun202122:08:19.456# oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo1122:C 05 Jun202122:08:19.456# Redis version=5.0.4, bits=64, commit=00000000, modified=0, pid=1122, just started1122:C 05 Jun202122:08:19.456# Configuration loaded
Redis is running...[root@Centos7 ~]# redis -h 192.168.100.202 -p 6379192.168.100.202:6379> auth123123
OK192.168.100.202:6379> keys *(empty list orset)192.168.100.202:6379>set aaa bbb
OK192.168.100.202:6379> keys *1)"aaa"192.168.100.202:6379>set bbb ccc
OK192.168.100.202:6379> keys *1)"bbb"2)"aaa"192.168.100.202:6379>exit[root@Centos7 ~]# cat /usr/local/redis/rdb/appendonly.aof   #可以看到AOF文件中全部都是执行过的命令
*2$6
SELECT$10
*3$3set$3
aaa$3
bbb
*3$3set$3
bbb$3
ccc
  • 作者:礁之
  • 原文链接:https://renzeyuan.blog.csdn.net/article/details/125537146
    更新时间:2022-09-08 10:37:14