redis支持两种持久化方式,一种是RDB方式,另一种是AOF方式。
RDB持久化:
RDB持久化指的是把数据生成快照保存到硬盘的过程,会生成一个rdb文件,可以在配置文件中配置文件生成目录及文件名,默认目录是根目录,默认文件名是dump.rdb。
RDB可以手动触发,也可以自动触发。手动触发对应save命令和bgsave命令。save命令会阻塞服务器,直到RDB完成为止,不建议在生产环境使用。bgsave是save命令的升级版,redis进程会执行fork操作创建子进程,子进程负责RDB持久化,redis阻塞只发生在创建子进程阶段。
redis在以下2种情况下会自动触发RDB持久化:
1、根据配置规则自动进行RDB持久化
使用save相关配置,如"save m n"表示m秒之内数据存在n次修改时,自动触发bgsave。
2、执行一些特殊命令:
执行flushall、reload、shutdown命令时,会触发RDB操作。执行shutdown命令只有在没有开启AOF时才会触发RDB。
RDB没办法做到实时持久化或者说是秒级持久化,因为bgsave每次运行都要执行fork操作创建子进程,属于重量级操作,频繁执行成本过高。秒级持久化可由AOF来实现。
AOF持久化:
AOF是append only file,与RDB保存数据快照不同,AOF保存的是写命令,即把每一条写命令保存到硬盘上的一个文件上(读命令不会保存),文件名和文件路径也可以在配置文件中配置,默认目录是根目录,默认文件名是appendonly.aof。
redis默认关闭AOF,需要我们修改配置文件来开启AOF:appendonly yes,这样在redis服务一启动的时候就会在指定目录里创建aof文件,如果有的话(人为复制进去),就会读取aof文件内容,加载数据到内存。
将写命令保存到aof文件中的频率是可以在配置文件中配置的,默认是appendfsync everysec即每秒保存一次,这也是最好的方式。配置文件中还有另外两种可以选,appendfsync always即是每执行一条写命令就保存到文件中,这种方式是最安全的,但是要知道执行一条命令的速度是毫秒级的,所以这种方式是也是最耗费性能的。还有一种appendfsync no,最不常用,意思是由操作系统来决定,这简直是扯淡,不确定性太大。
aof文件还可以重写,为什么重写?比如说执行了100条写命令,但这些写命令都是对同一个键操作的,那么第100条命令的结果就会覆盖掉前99条命令的结果,这时候实际上只需要第100条命令就好了。aof文件重写可以自动重写,也可以调用命令手动重写。
自动重写条件可以在配置文件中配置,默认是
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb,即aof文件大小超过上次重写后的100%时会重写,但是文件大小要最少达到64M。
手动重写命令是bgrewriteaof,当执行了这个命令之后,aof文件就会立刻重写。
如果没有开启AOF,那么redis启动后redis会在dir目录中找rdb文件。如果有(在第一次启动时,人为添加一个rdb文件也可以),则读取rdb文件并加载数据到内存中,之后按照配置的规则来进行RDB持久化。如果没有(可能被人为删掉了),则在第一次RDB持久化的时候创建rdb文件,此后还是按照配置的规则来进行RDB持久化。
如果开启了AOF,那么redis就会在启动的时候读取aof文件的内容加载数据到内存中,即使aof文件内容为空,也不会去读取rdb文件。如果没有(可能redis上次运行的时候没有进行操作或者aof文件被人为的删掉了),则新建,之后按照配置的规则往文件里写数据。运行过程中,如果人为删掉aof文件,也不会再创建了,重启之后就会丢数据。