持久化数据就是将内存中的数据写入到硬盘中。 进行持久化主要是为了防止机器、设备故障而将数据备份以便数据恢复。 Redis有两种持久化方式: (1)AOF:只追加文件 (2)RDB: 快照
AOF
开启AOF:
在Redis中AOF默认是不开启的,如果要开启AOF,需要修改redis.conf配置文件中的一些参数
appendonly yes
appendfilename "appendonly.aof"
使用AOF的好处和风险:
注意:AOF只会记录写操作命令,不会记录读操作命令。 Redis是先执行写操作命令,然后再将该命令记录到AOF日志中。 好处: 1.避免额外的检查开销 先执行写操作再将操作记录到AOF中就不用在记录到AOF之前检查这个命令的语法是否正确,因为只有语法正确写操作才会执行。 2.不会阻塞当前写操作命令 风险: 1.执行写操作和记录日志是两个过程,如果写操作执行完,服务器就宕机了,这时数据还没记录到日志上,这个数据就会有丢失的风险。 2.记录日志不会阻塞当前写操作命令的执行,但有可能会阻塞下一条写操作命令的执行。
AOF日志写回硬盘策略:
写回策略使用时机:  1.Always:每次写操作执行完后,就同步将AOF日志数据写回硬盘。 2.Everysec:每秒,每次写操作命令执行完后,先将命令写入page cache中,然后每隔一秒再将page cache中的内容写回硬盘。 3.No:不由Redis控制写回硬盘的实际,交给操作系统控制
AOF重写机制:
当AOF日志文件写入内容越来越多,超过AOF文件大小所设定的阈值后,redis就会启用AOF重写机制。
重写机制就是读取当前数据库中所有的键值对,然后将每个键值对用一条命令记录到新的AOF文件中,全部记录完后,用新的AOF文件替换旧的AOF文件。
注意:写入AOF日志是在主进程中完成的;重写AOF文件是在后台子进程中完成的。
使用AOF日志的方式恢复数据是比较慢的,因为Redis执行命令由单线程复制,AOF日志恢复数据的方式是顺序执行日志里的每一条命令,如果AOF日志比较大,这个恢复过程就会比较慢。
子进程在执行AOF重写时的操作: 1.执行客户端的命令 2.将执行后的写命令追加到 AOF缓冲区 3.将执行后的写操作命令追加到 AOF重写缓冲区 子进程完成AOF重写工作后: 1.向主进程发送一个信号 2.主进程调用一个信号处理函数 3.信号处理函数的工作: (1)将AOF重写缓冲区中的内容追加到新的AOF文件中,保证新旧AOF文件的数据库状态一致 (2)新的AOF文件覆盖旧的AOF文件
RDB
RDB快照就是记录某一瞬间的内存数据。
生成RDB文件的方式
1.执行save命令:会在主线程中生成RDB文件,所以会阻塞主线程。 2.执行bgsave命令:会创建一个子进程来生成RDB文件,不会阻塞主线程。
RDB的加载是在服务器启动时自动执行的。 Redis的快照是全量快照,记录的是所有数据。
如果主线程正在对数据进行修改,子进程同时在生成RDB文件,会有影响吗? 创建bgsave子进程后,子进程会共享父进程的所有内存数据。 如果主线程进行的是读操作,那么主线程(父进程)和子进程之间互不影响。 如果主线程进行的是写操作,它会发生写时复制(在执行写操作时,这块数据的物理内存会被复制一份,然后在这个副本上进行修改,修改完,再用这个副本替换原来的数据),这时子进程生成RDB文件使用的是原本的内存数据。
不适合频繁生成RDB文件,频繁写入磁盘和创建子进程会带来额外的性能开销。
AOF和RDB混合使用
在redis4.0之后,开始使用混合持久化,就是混合使用AOF日志和内存快照。
开启混合持久化功能,需要修改配置文件redis.conf中
aof-use-rdb-preamble yes
混合持久化工作在AOF日志重写过程中。 在AOF重写日志时,fork出来的子进程会先将与内存共享的数据以RDB的方式写入到AOF文件中,然后主线程处理的操作命令记录在重写缓冲区中,重写缓存区里的命令以AOF方式写入到AOF文件中。最后再用新的AOF文件覆盖旧的AOF文件。 也就是说,在使用混合持久化时,AOF文件前半部分是RDB的全量数据,后半部分是在重写日志过程中主线程执行的操作(AOF格式)。 混合持久化好处: 1.前半部跟是RDB,加载时速度会很快 2.加载完前半部分,再加载后面的AOF内容,可以减少数据的丢失
|