关闭redis时,会将内存中的数据持久化到硬盘,同步数据;
启动redis时,会从硬盘加载数据到内存。
平时也要将内存的数据同步到硬盘,redis提供了2种持久化方案:RDB、AOF
RDB
RDB是redis默认使用的持久化方案,隔一段时间同步一次,使用快照保存内存中的数据。
打开redis.conf,搜索rdb即可找到RDB相关配置:
RDB默认设置了3种策略,分别对应redis服务器key的更改频率:
- 如果900s(即15min)内,对redis中键值对的修改个数达到1,就同步数据到硬盘。对应修改很少的情况。
- 如果300s(即5min)内,对redis中键值对的修改个数达到10,就同步数据到硬盘。对应修改小多的情况。
- 如果60s(即1min)内,对redis中键值对的修改个数达到10000,就同步数据到硬盘。对应修改很多的情况。
默认会压缩字符串,减小.rdb文件的体积,但会加大服务器开销。
默认的数据库文件名是dump.rdb
执行过程:
达到同步要求后,启动一个子线程,将内存中的数据写到一个临时的.rdb文件中,完成后用临时文件替换原来的.rdb文件。
AOF
把redis服务器执行的写指令记录到一个.aof文件中(相当于写指令的日志),启动redis服务器时,把.aof中的写指令重新执行一遍,还原数据。
在redis.conf中搜索append即可找到AOF的配置:
默认是没开启AOF的,如果要使用AOF,将no改为yes即可。
默认的写命令的日志文件名是appendonly.aof。
向.aof文件追加写指令(同步)有3种策略:
- always 每执行一条写指令,都会在.aof中追加,开销大、拉低服务器性能,但最安全,宕机就丢失1个写指令
- no:把写指令放到缓冲区里,由操作系统决定什么时候写到.aof中,资源开销最小,但不安全,宕机缓冲区里的写指令都会丢失
- everysec:每秒在.aof中追加一次,一次性写入这一秒内执行的所有写指令。上面2种的折中,宕机丢失1s内的写指令。
默认值everysec,不知道要使用哪种策略,使用默认的everysec即可。
AOF的执行过程:
每隔1s,启动一个后台线程,将这段时间内的写指令写到.aof文件中。
.aof文件中存储的是执行过的写指令,不是内存中的数据。
redis服务器启动时,把.aof中的写指令重新执行一遍,还原数据。
AOF重写:
.aof文件中的写指令越来越多,文件越来越大,还原数据越来越慢。AOF会自动重写.aof文件。
比如.aof文件中有2条写指令:
hmset user name "chy" password "abcd"
hset user password "ABCD"
重写合并为一条:
hmset user name "chy" password "ABCD"
password原来的值不用了,不必再去执行。这样就减小了文件体积,少执行一条写指令,还原|启动也要快一些。
AOF重写是是否不同步写指令到.aof中,默认值no,要同步。
如果设置为yes,不同步,会丢失AOF重写时执行的所有写指令。
AOF会记录上次重写后.aof的文件大小,如果redis服务器启动后还没有过AOF重写,则默认为redis服务器启动时.aof的文件尺寸。
默认设置了2种重写策略:
- 如果当前.aof的尺寸,比上一次重写后增加了百分之多少(默认是100,就翻了一倍),就自动执行AOF重写
- 如果当前.aof的尺寸,比上一次重写后增加了多少(默认是64mb),就自动执行AOF重写
如果增量的百分比设置为0,即禁用AOF的自动重写。
在redis.conf中搜索dir:
.rdb文件、.aof文件都是保存在此目录下的。
RDB、AOF的优缺点分析
可以把各个时间段的.rdb文件备份,这样就有了数据库各个时间段的数据备份,可以将数据还原到某个时间段,RDB方式十分适合做备份。
.aof中全是写指令,鬼知道是哪个时间段执行的,不好还原到某个时间段,不适合做备份。
但AOF有一个好处:如果不小心使用flushall命令清空了所有数据,只要还没有进行AOF重写,就可以在.aof删除flushall指令,重新启动redis即可恢复数据。
RDB每次都是备份内存中的所有数据,有点吃资源、时间开销大。
AOF每次只需要往.aof中写入写指令即可,资源消耗少,且以追加方式写入,没有文件寻址开销,时间开销小。
RDB每隔60|300|900秒才进行备份,如果期间机器出故障了,这几十、几百秒内的数据会全部丢失。
AOF一般是1秒写一次指令,出故障丢失的数据极少,毕竟只有1秒,数据的一致性、完整性更高。
每次启动redis服务器,AOF都要重新执行一遍写指令来还原数据,启动数据慢。
RDB直接将.rdb中的数据库数据读取到内存即可,启动速度快。
RDB和AOF如何选择
只使用RDB,可能会丢失很多数据
只使用AOF,不好做各个时间段的备份
一般是AOF、RDB结合使用,用AOF保证数据不丢失,用RDB做各个时间段的备份。
也可以手动同步数据:
dump key #同步某个key,返回该key序列化之后的值
save #同步内存中的所有数据
bgsave #同上,只不过是在后台进行同步,bg即backgroud