您现在的位置是:首页 >技术杂谈 >Redis(四)持久化策略网站首页技术杂谈
Redis(四)持久化策略
文章目录
持久化策略
1、为什么Redis需要持久化
Redis对数据的操作都是基于内存的,当遇到了进程退出、服务器宕机等意外情况,如果没有持久化机制,那么Redis中的数据将会丢失无法恢复。有了持久化机制,Redis在下次重启时可以利用之前持久化的文件进行数据恢复
2、Redis提供的两种持久化方式
从配置文件中我们可以看出有两类持久化文件:
RDB
持久化AOF
持久化
(1)RGB持久化详解
概述
RDB 即 快照
模式(将内存数据以二进制文件形式保存起来),它是 Redis 默认的数据持久化方式,它会将数据库的快照保存在 dump.rdb
这个二进制文件中。
RGB持久化的两种触发策略
- 手动触发
-
save
命令
save由主线程执行,会阻塞客户端命令;
-
-
bgsave
命令Redis会单独创建(fork)一个子进程来进行持久化(该子进程与父进程享有相同的地址空间),会先将数据写入一个临时RDB文件,待持久化过程都结束了,再用这个临时文件替换上次持久化好的文件。注意:此时的
主进程仍然可以对外提供服务
。
-
-
flushall
命令
-
- 关掉redis也会产生dump.rdb文件
-
自动触发
用户可以通过 save 选项设置多个保存条件, 但只要其中任意一个条件被满足,服务器就会执行 BGSAVE 命令。
手动触发实例测试:
通过CONFIG GET dir
命令查看当前的工作目录
无论是使用RDB还是AOF持久化方式,持久化文件都会保存在Redis服务器的工作目录中。
通过find
命令查看已经存在的dump.rdb文件
通过rm
命令删除此文件
此时运行save
命令,可以看到已经重新生成一个dump.rdb文件
bgsave
命令测试
flushall
命令测试
关掉redis服务测试是否产生文件
自动触发实例测试:
修改配置文件:
save 60 3 60秒3个改变进行持久化
注意:修改配置文件后一定要重启redis服务
查看rdb的状态信息info Persistence
rdb模式的优缺点
优点:
- RDB可以最大化Redis的性能,父进程再保存RDB文件时唯一要做的就是fork出一个子进程,然后这个子进程就会处理接下来的所以保存工作,父进程无需执行任何磁盘I/O操作
- 适合大规模的数据恢复
- rdb文件为二进制数据,占用的内存更小
缺点:
- 不能实时的保存数据,需要一定的时间间隔进行操作,如果redis意外宕机了,这个最后一次修改的数据就没有了。
- 当数据量非常大的时候,从父进程fork子进程进行保存至rdb文件时需要一点时间,
(2)AOF持久化详解
从 1.1 版本开始, Redis 增加了一种完全耐久的持久化方式: AOF 持久化。
默认是不开启AOF持久化方式,需修改配置文件 (永久)
appendonly no 默认是不开启,改为yes
appendfilename "appendonly.aof"
redis7后将会创建三个文件
# For example, if appendfilename is set to appendonly.aof, the following file
# names could be derived:
#-appendonly.aof.1.base。rdb作为基本文件。
#appendonly.aof.1.incr.aof。aof作为增量文件。
#-appendonly.aof。manifest作为清单文件。
appendfilename "appendonly.aof"
appenddirname "appendonlydir" //文件夹名
默认是不开启AOF持久化方式,通过命令暂时开启 (暂时)config set appendonly yes
redis6或者之前的版本,那么在目录下会直接在/usr/local/bin/ 目录下生成一个appendonly.aof文件
会在你的工作目录下创建一个appendonlydir目录,并创建以下三个文件:
appendonly.aof.1.incr.aof里保存的就是刚才的写入命令
该命令格式为Redis的序列化协议(RESP)。*3代表这个命令有三个参数,$3表示该参数长度为3
AOF持久化步骤:
AOF需要记录Redis的每个写命令,步骤为:命令追加(append)、文件写入(write)和文件同步(sync)
- 命令追加:开启AOF持久化功能后,服务器每执行一个写命令,都会把该命令以协议格式先追加到aof_buf缓存区的末尾,而不是直接写入文件,避免每次有命令都直接写入硬盘,减少硬盘IO次数
- 文件写入与文件同步:然后通过 write() 系统调用,将 aof_buf 缓冲区的数据写入到 AOF 文件,此时数据并没有写入到硬盘,而是拷贝到了内核缓冲区 page cache,等待内核将数据写入硬盘;
为了提高文件的写入效率,当用户调用write函数,将一些数据写入到文件的时候,操作系统通常会将写入数据暂时保存在一个内存缓冲区里面,等到缓冲区的空间被填满、或者超过了指定的时限之后,才真正地将缓冲区中的数据写入到磁盘里面。
这种做法虽然提高了效率,但也为写入数据带来了安全问题,因为如果计算机发生停机,那么保存在内存缓冲区里面的写入数据将会丢失。为此,系统提供了fsync和fdatasync两个同步函数,它们可以强制让操作系统立即将缓冲区中的数据写入到硬盘里面,从而确保写入数据的安全性。
Redis 提供了 3 种写回硬盘的策略:
appendfsync always 每执行一个命令就保存一次,安全性最高,最多只丢失一个命令的数据,但是性能也最低(频繁的磁盘IO)
appendfsync everysec 每一秒保存一次,推荐使用,在安全性与性能之间折中,最多丢失一秒的数据
appendfsync no 依赖操作系统来执行(一般大概30s一次的样子),安全性最低,性能最高,如果系统宕机,丢失操作系统最后一次AOF文件的数据
AOF的重写机制
AOF的工作原理是将写操作追加到文件中,文件的冗余内容会越来越多。所以Redis 新增了重写机制。当AOF文件的大小超过所设定的阈值时,Redis就会对AOF文件的内容压缩。
例如:
set k1 k1
set k1 k2
。。。将k1一共更改100次
如果没有重写机制,持久化文件就有100条写入的命令记录
而有重写机制,只保留最后一条,消除无效信息
- 重写会有大量的写入操作,所以服务器进程会fork一个子进程
- 子进程遍历 Redis 内存快照中数据写入临时 AOF 文件,同时会将新的写指令写入 aof_buf 和 aof_rewrite_buf 两个重写缓冲区,前者是为了写回旧的 AOF 文件,后者是为了后续刷新到临时 AOF 文件中,防止快照内存遍历时新的写入操作丢失
- 当子进程完成重写之后,会给父进程一个信号,然后父进程会把AOF重写缓冲区的内容写进新的AOF临时文件中,再对新的AOF文件改名完成替换,这样可以保证新的AOF文件与当前数据库数据的一致性
AOF的两种触发方式
-
手动触发
-
-
bgrewriteaof
命令
重新生成了这三个文件:
可以看到appendonly.aof.2.base.rdb文件有
-
-
自动触发
auto-aof-rewrite-percentage 100 AOF文件重写的大小比例,100代表100%表示当前AOF文件比上一次大一倍才会触发重写机制 auto-aof-rewrite-min-size 64mb允许AOF重写的最小文件容量 no-appendfsync-on-rewrite=no 如果 no-appendfsync-on-rewrite=yes ,不写入aof文件只写入缓存,用户请求不会阻塞,但是在这段时间如果宕机会丢失这段时间的缓存数据。(降低数据安全性,提高性能) 如果 no-appendfsync-on-rewrite=no, 还是会把数据往磁盘里刷,但是遇到重写操作,可能会发生阻塞。(数据安全,但是性能降低)
AOF的数据恢复
打开aof文件,对其进行修改
重启服务,发现连接失败
通过命令修复redis-check-aof --fix appendonly.aof.1.incr.aof
会删除错误的那段数据
查看AOF的状态信息info Persistence
AOF模式的优缺点
优点:
- 数据更完整,安全性更高,秒级数据丢失(取决fsync策略,如果是everysec,最多丢失1秒的数据)
- AOF文件是一个只进行追加的日志文件,且写入操作是以Redis协议的格式保存的,内容是可读的,适合误删紧急恢复’
缺点:
- 对于相同的数据集,AOF文件的体积要大于RDB文件,数据恢复也会比较慢
- 在Redis负载比较高的情况下,RDB比AOF的性能好。
AOF和RDB的选择场景
- 如果是数据比较重要,不想再从其他地方获取,且可以承受数分钟的数据丢失,比如缓存等,那么可以只使用RDB
- 有很多用户都只使用 AOF 持久化, 但并不推荐这种方式: 因为定时生成 RDB 快照(snapshot)非常便于进行数据库备份, 并且 RDB 恢复数据集的速度也要比 AOF 恢复的速度要快。
- 如果是用做内存数据库,要使用Redis的持久化,建议是RDB和AOF都开启,或者定期执行bgsave做快照备份,RDB方式更适合做数据的备份,AOF可以保证数据的不丢失
(3)混合持久化
Redis4.0开始支持RDB和AOF的混合持久化:
通过修改配置开启
aof-use-rdb-preamble yes
其中 yes 表示已经开启混合持久化,no 表示关闭,默认值为 yes。