Redis是一个内存数据库,数据保存在内存中,其最明显的有点就是读写速度非常快,但其致命缺点就是一旦redis服务宕机,则先前存储在内存中的数据也会全部丢失。所以redis为了避免这一缺点,提供了数据持久化的机制,主要有RDB和AOF两种方式。
1、RDB方式
RDB是一种快照存储持久化方式,在指定的时间间隔内将内存中的全部数据写入临时的快照文件中,完成数据写入后会用临时的快照文件替换掉先前保存的快照文件,最后删除掉先前的快照文件。也是redis默认的持久化方式,默认保存的文件名为dump.rdb
。在Redis服务器启动时,会重新加载dump.rdb文件的数据到内存当中恢复数据。
1.1、开启RDB持久化方式
- 手动触发:通过向Redis服务器发送save或bgsave命令让服务器生成rdb文件;
(1)save
:是一个同步操作,当客户端向服务器发送save命令请求进行持久化时,服务器会阻塞save命令之后的其他客户端的请求,直到数据同步完成。如果同步的数据量很大,持久化的时间太长,会导致redis长时间不可用,所以尽量避免使用save命令进行持久化。
(2)bgsave
:是一个异步操作,当客户端发服务发出bgsave命令时,redis服务器主进程会forks一个子进程来处理数据同步操作,在将数据保存到rdb文件之后,子进程会自动退出。阻塞只发生在fork阶段,一般时间很短。基本上 redis 内部所有的RDB操作都是采用 bgsave 命令。 - 自动触发:通过服务器配置文件指定触发RDB条件;
(1)服务器配置自动触发:在redis.conf配置文件中,指定触发RDB持久化的条件,例如:“save m n”,表示m秒内数据集存在n次修改时,自动触发RDB持久化操作。默认配置为: save 900 1 :表示900秒钟内至少1个键被更改则进行快照。通过服务器配置文件触发RDB的方式,与bgsave命令类似,达到触发条件时,会forks一个子进程进行数据同步,不过最好不要通过这方式来触发RDB持久化,因为设置触发的时间太短,则容易频繁写入rdb文件,影响服务器性能,时间设置太长则容易造成数据丢失。
1.2、RDB持久化过程
(1)生成临时的dump.rdb文件,并将当前时刻内存中的结果集写入dump.rdb文件中。
(2)完成数据写入,用临时文代替代正式rdb文件。
(3)删除原来的rdb文件。
(4)Redis服务重启时,将rdb文件中的数据复制到内存中。
1.3、RDB持久化优缺点
- 优点:
(1)体积更小:相对于AOF方式,.rdb
文件是紧凑型的二进制文件,相同的数据量.rdb
文件更小,更适合于数据备份。
(2)恢复更快:在恢复大量数据的情况下,.rdb
文件恢复速度更快。
(3)简单易用:RDB持久化是Redis提供的默认持久化方式,使用起来比较简单。 - 缺点:
(1)数据完整性较差:RDB持久化主要是在指定时间间隔后或者达到指定触发条件后才会触发将内存中的全量数据持久化的操作,如果在触发时间间隔之间redis服务宕机了,则在这间隔时间内的数据时无法写入到快照文件中,也就意味着这段时间内写入到内存中的数据将会丢失。
(2)数据一致较差:如果Redis在执行RDB持久化时发生了故障,可能会导致数据不一致。
2、AOF方式
与RDB存储某个时刻的快照不同,AOF是以日志的形式来记录每个写命令,并将这些写命令通过write函数追加到appendonly.aof
的文件末尾,在Redis服务器重启时,会加载并运行appendonly.aof
文件,将文件中的所有写命令重新执行一遍,以达到恢复数据的目的。
2.1、开启AOF持久化方式
redis默认不开启AOF持久化方式,可以在redis.conf配置文件中开启并进行更加详细的配置。
# 开启aof机制
appendonly yes
# aof文件名
appendfilename "appendonly.aof"
# 写入策略,有always、everysec、no三种策略
# always:客户端的每一个写操作都保存到aof文件当,这种策略很安全,但是每个写请求都有IO操作,所以也很慢。
# everysec:默认写入策略,每秒写入一次aof文件,因此,最多可能会丢失1s的数据。
# no:Redis服务器不负责写入aof,而是交由操作系统来处理什么时候写入aof文件。更快,但也是最不安全的选择。
appendfsync always
# 默认不重写aof文件
no-appendfsync-on-rewrite no
# 保存目录
dir ~/redis/
2.2、AOF持久化过程
(1)客户端的请求写命令会被append追加到AOF缓冲区内。
(2)再根据AOF持久化策略[always,everysec,no]将缓冲区内的命令通过fsync命令同步到磁盘的AOF文件中;
(3)当AOF文件大小超过重写策略或手动重写时,会对AOF文件rewrite重写,压缩AOF文件容量;
(4)Redis服务重启时,会重新加载AOF文件中所有的写操作达到数据恢复的目的;
2.3、write命令和fsync命令的区别
(1)write命令将客户端的操作命令写入OS缓冲区;
(2)fsync命令具有强制将OS缓冲区数据写入到aof文件;
2.4、AOF重写机制
AOF持久化是通过将每一个写操作都追加到aof文件末尾,所以AOF文件的大小随着时间的流逝一定会越来越大。当aof文件太大,加载aof文件恢复数据时,就会非常慢,为了解决这个问题,Redis支持aof文件重写,通过重写aof,可以生成一个恢复当前数据的最少命令集,从而到达压缩aof文件,减少磁盘占用量,同时也加快了数据恢复的速度。两种重写方式:
(1)通过在redis.conf配置文件中的选项no-appendfsync-on-rewrite可以设置是否开启重写,默认值为no。
# 默认不重写aof文件
no-appendfsync-on-rewrite no
(2)客户端向服务器发送bgrewriteaof命令,fork一个子进程进行AOF重写。
# 让服务器异步重写追加aof文件命令
> bgrewriteaof
2.5、AOF优缺点
- 优点:
(1)数据安全性更高:通过设置fsync策略,一般默认是everysec,也可以设置每次写入追加,所以即使服务死掉了,咱们也最多丢失一秒数据。
(2)数据一致性较强:AOF持久化可以保证Redis在执行持久化操作时,所有的写操作都会被写入到持久化文件中,因此可以保证数据的一致性。 - 缺点:
(1)文件体积更大:通过append方式将客户端的每个写命令都追加在.aof文件后,而.rdb文件存放的是最终的结果,往往多个写命令执行结果最终只有一个,所以导致.aof文件的体积会远大于.rdb文件。
(2)数据恢复时间更久:由于.aof文件是将所有写命令重新执行一遍,而.rdb文件只是将最终存储的结果集复制到内存中,这也导致.aof文件的恢复时间要很长。
(3)性能相对较差:AOF的写入策略决定了与redis服务间的交互频率更多,从而增加了redis服务器的性能损耗。