一:持久化简介
redis是一种内存数据库,数据保存在内存中,但也可以将数据保存到文件中称之持久化,持久化的目的是为了防止数据意外丢失,便于恢复。持久化方式有两种:RDB(Redis DataBase)和AOF(Append Only File),RDB是默认方式。
二:RDB
RDB方式是将内存中的数据以快照的方式写入二进制文件中(dump.rdb),当重启服务时直接从二进制文件中来重新加载数据。RDB持久化可以通过配置save来实现,也可以在直接执行save命令来保存当前快照数据。
# 900秒内如果超过1个key被修改则发起快照保存
save 900 1
# 300秒内如果超过10个key被修改则发起快照保存
save 300 10
# 60秒内若果1万个key被修改则发起快照保存
save 60 10000
# 数据库文件名,一般采用命名为 dump-端口号.rdb
dbfilename dump-6379.rdb
# 持久化文件所保存的目录,默认 ./
dir /usr/local/redis/data/
# 日志文件名, 默认是"", 需要指定具体位置才能查看日志
logfile "/usr/local/redis/log/redis.log"
# 是否压缩数据库文件
rdbcompression yes
# 设置是否进行RDB文件格式校验,该校验过程在写文件和读文件均进行
rdbchecksum yes
shutdown命令用来关闭redis服务,当重新启动服务时通过日志可以看到redis重新将dump-6379.rdb文件中数据加载到内存中了。
手动执行save命令来保存当前快照数据。save命令执行会阻塞当前redis服务器,知道当前RDB过程完成为止,有可能会造成长时间阻塞,线上环境不建议使用。
手动执行bgsave命令来保存当前快照数据, 手动后台保存操作,但不是立即执行。bgsave是针对save阻塞问题的优化,redis是通过调用fork函数生成一个子进程来完成快照数据的备份,建议都使用bgsave,废弃掉save命令。bgsave有一个配置stop-writes-on-bgsave-error表示当后台保存出错时是否停止操作,一般默认为yes。
RDB三种方式对比与优缺点分析:
- save: 手动前台执行,会阻塞redis服务器。
- bgsave:手动后台启动新的子进程执行,不会阻塞redis服务器。
- 自动配置:自动执行bgsave命令。
以下三种情况也会启动rdb:
- 主从复制中全量复制
- 重启服务器 debug reload
- 关闭服务器并保存数据 shutdown save
RDB优点:
RDB是一个紧凑压缩的二进制文件,存储效率较高。
RDB内部存储的是redis在某个时间点的数据快照,非常适合用于数据备份,全量复制等场景。
RDB恢复数据的速度比AOF快很多。
应用:服务器中没隔多少小时执行bgsave备份,并将RDB文件拷贝到远程及其中,用于灾难恢复。
RDB缺点:
RDB方式无论是执行命令还是通过配置都无法做到实时持久化,有较大的可能性会丢失数据。每次RDB快照之间是有时间间隔的,如果在一次RDB快照时发生宕机,那上一次快照之后的key数据就会丢失了。
bgsave指令每次运行都要执行fork操作创建子进程,会牺牲一些性能。
Redis众多版本中未进行RDB文件格式版本统一,有可能出现各版本服务之间数据格式无法兼容。
基于快照思想,每次读写都是全部数据,当数据量大时效率就比较低。
三:AOF
AOF方式是将每个命令以Redis协议格式追加在appendonly.aof文件中,AOF持久化并不会立即将命令写入到磁盘文件中而是将命令写入到硬盘缓存中,在指定策略下会将硬盘缓存中写入到硬盘文件中。我们也可以手动修改appendonly.aof文件中的内容。所以在一定条件下AOF方式还是会发生数据丢失的,只不过这种方式可以大大减少数据丢失。AOF的作用主要是解决了数据持久化实时性,目前已经是redis持久化的主流方式。
AOF持久化策略:
- always:每次执行命令都会写入到aof文件中,数据零误差,性能较低。
- everysec:默认配置,每秒持久化一次,性能较高,服务宕机最多丢1秒内的数据。
- no:不主动进行同步操作,由系统控制默认30秒同步一次。
redis持久化默认使用的RDB方式,所以这里的appendonly值为no,只需要将该值设置为yes即表示使用AOF方式进行持久化,开启后需要重启服务redis-server /usr/local/etc/redis.conf,在目录下就会多一个appendonly.aof文件。
# 启用AOF方式
appendonly yes
# 持久化策略,每秒持久化一次
appendfsync everysec
# The name of the append only file (default: "appendonly.aof")
appendfilename "appendonly.aof"
# 持久化文件所保存的目录
dir /usr/local/redis/data/
我们停止redis服务,编辑appendonly.aof文件,去掉最后一行flushdb命令,然后再重新启动服务,可以看到数据被加载进来了。
AOF重写概念:
AOF会记录每条执行命令,如果对某个key操作多次就会记录多次,其实这没必须,只需要记录最新的那个命令所执行的结果即可。
随着命令不断写入AOF,文件会越来越大,为了解决这个问题,Redis引入了AOF重写机制来压缩文件体积。AOF文件重写是将Redis进程内的数据转化为命令同步到新AOF文件的过程,简单的说就是将对同一个数据的若干个命令执行结果转化为最终结果数据对应的指令进行记录,比如执行3次自增操作可以直接改写成set num 3的命令。
AOF重写作用
- 降低磁盘占用量,提高磁盘利用率。
- 提高持久化效率,降低持久化写时间,提高IO性能。
- 降低数据恢复用时,提高数据恢复效率。
AOF重写规则:
- 进程内已经超时的数据不再写入文件
- 忽略无效指令,重写是使用进程内数据直接生成,这样新的AOF文件只保留最终数据的写入命令。如删除操作
- 对同一个数据的多条写命令合并为一条命令,如 lpush list a、 lpush list b、 lpush list c 合并为 lpush list a b c,为防止数据量过大造成客户端缓冲区溢出,对list、set、hash、zset等类型,每条指令最多写入64个元素。
incr num
incr num
incr num
# set num 3
AOF重写方式
-
手动重写:执行 bgrewriteaof命令
- 自动重写:
触发规则满足一个就会重写。info命令会列出当前redis运行的属性值,通过info Persitence可以查看持久化的属性值,其中aof_current_size 和 aof_base_size和自动重写有关系。
# 百分比,表示当aof文件的大小增加一倍时,触发一次aof重写
auto-aof-rewrite-percentage 100
# 自动重写最小内容,表示当aof文件的大小超过64m时触发aof重写
auto-aof-rewrite-min-size 64mb