什么是Redis持久化?Redis有哪几种持久化方式?优缺点是什么?
什么是持久化?
持久化就是把内存的数据写到磁盘中去,防止服务宕机了内存数据丢失。
持久化有哪些方式?
Redis 提供了两种持久化方式:RDB(默认) 和AOF
- RDB:
rdb是Redis DataBase缩写,将进程数据写入文件;
功能核心函数rdbSave(生成RDB文件)和rdbLoad(从文件加载内存)两个函数
- AOF:
Aof是Append-only file缩写,将Redis执行的每次写命令记录到单独的日志文件中,
当Redis重启时再次执行AOF文件中的命令来恢复数据。
RDB持久化
RDB文件
RDB文件是经过压缩的二进制文件。
存储路径
RDB文件的存储路径既可以在启动前配置,也可以通过命令动态设定。
配置:dir配置指定目录,dbfilename指定文件名。默认是Redis根目录下的dump.rdb文件。
Reids:6379>config set dir /tmp
OK
Redis:6379>config set dbfilename mydump.rdb
OK
触发条件
RDB持久化的触发分为手动触发和自动触发两种。
- 手动触发(save命令和bgsave命令,两者都可以生成RDB文件)
-
- save命令会阻塞Redis服务器进程,直到RDB文件创建完毕为止,在Redis服务器阻塞期间,服务器不能处理任何命令请求
- bgsave(Background save)命令会创建一个子进程,由子进程来负责创建RDB文件,父进程(即Redis主进程)则继续处理请求。
bgsave命令执行过程中,只有fork子进程时会阻塞服务器,而对于save命令,整个过程都会阻塞服务器,因此save已基本被废弃,线上环境要杜绝save的使用;
- 自动触发
自动触发最常见的情况是在配置文件中通过save m n,指定当m秒内发生n次变化时,会触发bgsave。
redis根目录下的 redis.conf 文件
save 900 1 # 900秒内发生1次变化
save 300 10 # 300秒内发生10次变化
save 60 10000 # 60秒内发生一万次变化
压缩
Redis默认采用LZF算法对RDB文件进行压缩。虽然压缩耗时,但是可以大大减小RDB文件的体积,因此压缩默认开启;可以通过命令关闭:
Redis:6379>config set rdbcompression no
OK
优势
- 每隔一段时间备份,全量备份
- 灾备简单,可以远程传输
- 子进程备份的时候,主进程不会有任何io操作(不会有写入修改或删除),保证备份数据的的完整性
- 相对AOF来说,当有更大文件的时候可以快速重启恢复
劣势
- 发生故障是,有可能会丢失最后一次的备份数据
- 子进程所占用的内存比会和父进程一模一样,如会造成CPU负担
- 由于定时全量备份是重量级操作,所以对于实时备份,就无法处理了。
AOF持久化
配置:
与RDB相比,AOF的实时性更好,因此已成为主流的持久化方案。
AOF文件名 通过appendfilename配置设置,默认文件名是appendonly.aof。保存路径同 RDB持久化方式一致,通过dir配置指定
开启AOF
Redis服务器默认开启RDB,关闭AOF;要开启AOF,需要在配置文件中配置:
appendonly yes
由于需要记录Redis的每条写命令,因此AOF不需要刻意触发
执行流程:
AOF的执行流程包括:
- 命令追加(append):将Redis的写命令追加到缓冲区(aof_buf)
- 文件写入(write)和文件同步(sync):根据不同的同步策略将缓冲区中的内容同步到硬盘;
- 文件重写(rewrite):定期重写AOF文件,达到压缩的目的。
命令追加(append):
Redis先将写命令追加到缓冲区,而不是直接写入文件,主要是为了避免每次有写命令都直接写入硬盘,导致硬盘IO成为Redis负载的瓶颈。
文件写入(write)和文件同步(sync):
AOF缓存区的同步文件策略由参数appendfsync控制,各个值的含义如下:
- always:命令写入缓冲区后立即调用系统fsync操作同步到AOF文件。但会降低Redis的性能;
- no:命令写入缓冲区后调用系统write操作,不对AOF文件做fsync同步;同步由操作系统负责,通常同步周期为30秒。缓冲区中堆积的数据会很多,宕机的话这一段时间内的数据会消失,数据安全性无法保证。
- everysec:命令写入缓冲区后调用系统write操作,write完成后线程返回;fsync同步文件操作由专门的线程每秒调用一次。
everysec是前述两种策略的折中,是性能和数据安全性的平衡,因此是Redis的默认配置,也是最推荐的配置。
文件重写(rewrite):
文件重写是指定期重写AOF文件,减小AOF文件的体积。需要注意的是,AOF重写是把Redis进程内的数据转化为写命令,同步到新的AOF文件;不会对旧的AOF文件进行任何读取、写入操作!
文件重写之所以能够压缩AOF文件,原因在于:
1、过期的数据不再写入文件
2、压缩命令:如sadd myset v1, sadd myset v2, sadd myset v3
可以合并为sadd myset v1 v2 v3。
文件重写的触发
文件重写的触发,分为手动触发和自动触发:
- 手动触发
直接调用bgrewriteaof命令,该命令的执行与bgsave有些类似:都是fork子进程进行具体的工作。
Reids:6379>bgrewriteaof
Backgrounder append only file rewriting started
- 自动触发
redis.conf文件中配置重写的条件
auto-aof-rewrite-min-size 64MB // 当文件小于64M时不进行重写
auto-aof-rewrite-min-percenrage 100 // 当文件比上次重写后的文件大100%时进行重写
优势
- AOF更加耐用,可以以秒级别为单位备份,如果发生问题,也只会丢失最后一秒的数据,大大增加了可靠性和数据完整性。所以AOF可以每秒备份一次,使用fsync操作。
- 以log日志形式追加,如果磁盘满了,会执行 redis-check-aof 工具
- 当数据太大的时候,redis可以在后台自动重写aof。当redis继续把日志追加到老的文件中去时,重写也是非常安全的,不会影响客户端的读写操作。
- AOF 日志包含的所有写操作,会更加便于redis的解析恢复。
劣势
- 相同的数据,同一份数据,AOF比RDB大
- 针对不同的同步机制,AOF会比RDB慢,因为AOF每秒都会备份做写操作,这样相对与RDB来说就略低。 每秒备份fsync没毛病,但是如果客户端的每次写入就做一次备份fsync的话,那么redis的性能就会下降。
- AOF发生过bug,就是数据恢复的时候数据不完整,这样显得AOF会比较脆弱,容易出现bug,因为AOF没有RDB那么简单,但是为了防止bug的产生,AOF就不会根据旧的指令去重构,而是根据当时缓存中存在的数据指令去做重构,这样就更加健壮和可靠了。
总结:
- Redis 默认开启RDB持久化方式,在指定的时间间隔内,执行指定次数的写操作,则将内存中的数据写入到磁盘中。
- RDB 持久化适合大规模的数据恢复但它的数据一致性和完整性较差。
- Redis 需要手动开启AOF持久化方式,默认是每秒将写操作日志追加到AOF文件中。
- AOF 的数据完整性比RDB高,但记录内容多了,会影响数据恢复的效率。
- Redis 针对 AOF文件大的问题,提供重写的瘦身机制。
- 若只打算用Redis 做缓存,可以关闭持久化。
- 若打算使用Redis 的持久化。建议RDB和AOF都开启。使用RDB和AOF结合一起做持久化,RDB做冷备,可以在不同时期对不同版本做恢复,AOF做热备,保证数据仅仅只有1秒的损失。当AOF破损不可用了,那么再用RDB恢复,这样就做到了两者的相互结合,也就是说Redis恢复会先加载AOF,如果AOF有问题会再加载RDB,这样就达到冷热备份的目的了。