目录
一、简介
什么是持久化?
利用永久性存储介质将数据进行保存,在特定的时间将保存的数据进行恢复的工作机制称为持久化。说白了Redis是基于内存的,快是快,但一关机数据就没了,这样肯定不行啊,所以就要把数据都存在磁盘上,这个操作就叫持久化。
为什么要持久化?
防止数据的意外丢失,确保数据安全性。哪有服务器一宕机数据就没的,这谁还用Redis?
两种实现方式
RDB:是redis的默认持久化机制。RDB相当于照快照,是对 Redis中的数据执行周期性的持久化操作。
AOF:以独立日志的方式记录每次写命令,重启时再重新执行AOF文件中命令达到恢复数据的目的。与RDB相比可以简单描述为改记录数据为记录数据产生的过程。
二、RDB详解
2.1、介绍
RDB:是redis的默认持久化机制。RDB相当于照快照,保存的是一种状态。几十G数据 —>几kb快照。
快照是默认的持久化方式,这种方式就是将内存中数据以快照的方式写入到二进制文件中,默认的文件名为dump.rdb。
2.2、save指令前后对比
save命令就可以触发RDB持久化机制,我们发现,只要我们手动的去save,dump.rdb文件里的二进制数据就会发生改变。
save前:
save后:
2.3、save指令相关配置
一些设置
● dbfilename dump.rdb
说明:设置本地数据库文件名,默认值为dump.rdb
经验:通常设置为dump-端口号.rdb
● dir
说明:设置存储.rdb文件的路径
经验:通常设置成存储空间较大的目录中,目录名称data
● rdbcompression yes
说明:设置存储至本地数据库时是否压缩数据,默认为yes,采用LZF压缩
经验:通常默认为开启状态,如果设置为no,可以节省CPU运行时间,但会使存储的文件变大(巨大)
● rdbchecksum yes
说明:设置是否进行RDB文件格式校验,该校验过程在写文件和读文件过程均进行
经验:通常默认为开启状态,如果设置为no,可以节约读写性过程约10%时间消耗,但是存储一定的数据损坏风险
RDB快照条件
1、服务器正常关闭时 ./bin/redis-cli shutdown
2、key满足一定条件,会进行快照
在redis.conf文件中
save 900 1 //每900秒(15分钟)至少1个key发生变化,产生快照
save 300 10 //每300秒(5分钟)至少10个key发生变化,产生快照
save 60 10000 //每60秒(1分钟)至少10000个key发生变化,产生快照
2.4、RDB第一种方式:手动save
我们如果想产生快照,可以手动的去save,就类似于我们用eclipse开发程序的时候,总是习惯的去ctrl+s进行保存。我们发现,每次手动的save,dump.rdb文件就会变化。但这种方式有个弊端,就是执行save命令时会阻塞redis。后面的命令执行不了,万一数据很多,save时间过长,那就很难受了。所以线上环境不建议使用手动save。
2.5、RDB第二种方式:后台执行(bgsave)
用法就是直接输入bgsave命令
发送bgsave指令到redis中,这时redis直接返回给操作者一个Background saving started的信息,在返回信息的时候,抽空调用了linux的fork函数生成一个子进程去创建RDB文件,生成完返回给redis消息。
2.6、RDB第三种方式:自动执行
问题:反复执行保存指令(save或bgsave),忘记了怎么办?不知道数据产生了多少变化,何时保存?
解决方式:自动执行。
例如:配置文件中
save 900 1 //每900秒(15分钟)至少1个key发生变化,产生快照
save 300 10 //每300秒(5分钟)至少10个key发生变化,产生快照
save 60 10000 //每60秒(1分钟)至少10000个key发生变化,产生快照
注意:这种方式启动后执行的是bgsave的操作。
特别注意:如果我们设置每30秒有两个变化就bgsave,配置如:save 30 2
两个相同的set命令也会触发bgsave,也就是说redis是不会给你进行数据比对的,比如我原本有个key叫name,值为gala,那么我们连着两条set name gala,还是会触发bgsave,可以说,只要是写命令都会触发,不用看值是否变化了。
2.7、RDB的优缺点
RDB优点
● RDB是一个紧凑压缩的二进制文件,存储效率较高。
● RDB内部存储的是redis在某个时间点的数据快照,非常适合用于数据备份,全量复制等场景。
● RDB恢复数据的速度要比AOF快很多。
● 应用:服务器中每X小时执行bgsave备份,并将RDB文件拷贝到远程机器中,用于灾难恢复。
RDB缺点
● RDB方式无论是执行指令还是利用配置,无法做到实时持久化,具有较大的可能性丢失数据。
● bgsave指令每次运行要执行fork操作创建子进程,要牺牲掉一些性能。
● Redis的众多版本中未进行RDB文件格式的版本统一,有可能出现各版本服务之间数据格式无法兼容现象。
三、AOF详解
3.1、介绍
AOF(append only file)持久化:以独立日志的方式记录每次写命令,重启时再重新执行AOF文件中命令达到恢复数据的目的。与RDB相比可以简单描述为改记录数据为记录数据产生的过程。
AOF的主要作用是解决了数据持久化的实时性,目前已经是Redis持久化的主流方式。
3.2、AOF写数据的三种策略
我们先看看AOF将数据写入磁盘的过程。
每有一次写命令就将数据放入缓存区,那么问题来了,AOF存多少数据才同步到AOF文件中呢。
3.3、AOF重写(手动重写)
随着命令不断写入AOF,文件会越来越大,为了解决这个问题,Redis引入了AOF重写机制压缩文件体积。AOF文件重写是将Redis进程内的数据转化为写命令同步到新AOF文件的过程。简单说就是将对同一个数据的若干个条命令执行结果转化成最终结果数据对应的指令进行记录。
AOF重写作用:
降低磁盘占用量,提高磁盘利用率。
提高持久化效率,降低持久化写时间,提高IO性能。
降低数据恢复用时,提高数据恢复效率。
AOF重写规则:
1、进程内已超时的数据不再写入文件
2、忽略无效指令,重写时使用进程内数据直接生成,这样新的AOF文件只保留最终数据的写入命令
如del key1、 hdel key2、srem key3、set key4 111、set key4 222等。
3、对同一数据的多条写命令合并为一条命令,如lpush list1 a、lpush list1 b、 lpush list1 c 可以转化为:lpush list1 a b c。
为防止数据量过大造成客户端缓冲区溢出,对list、set、hash、zset等类型,每条指令最多写入64个元素。
3.4、AOF重写(自动重写)
条件1:当前AOF缓冲区里的数据大小 > 我们设置的auto-aof-rewrite-min-size。
条件2:(当前AOF缓冲区里的数据大小 - 我们设置的基础尺寸) / 我们设置的基础尺寸 >= 我们设置的百分比。