Redis持久化

92 阅读7分钟

什么是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 
优势
  1. 每隔一段时间备份,全量备份
  2. 灾备简单,可以远程传输
  3. 子进程备份的时候,主进程不会有任何io操作(不会有写入修改或删除),保证备份数据的的完整性
  4. 相对AOF来说,当有更大文件的时候可以快速重启恢复
劣势
  1. 发生故障是,有可能会丢失最后一次的备份数据
  2. 子进程所占用的内存比会和父进程一模一样,如会造成CPU负担
  3. 由于定时全量备份是重量级操作,所以对于实时备份,就无法处理了。

AOF持久化

配置:

与RDB相比,AOF的实时性更好,因此已成为主流的持久化方案。

AOF文件名 通过appendfilename配置设置,默认文件名是appendonly.aof。保存路径同 RDB持久化方式一致,通过dir配置指定

开启AOF

Redis服务器默认开启RDB,关闭AOF;要开启AOF,需要在配置文件中配置:

appendonly yes

由于需要记录Redis的每条写命令,因此AOF不需要刻意触发

执行流程:

AOF的执行流程包括:

  1. 命令追加(append):将Redis的写命令追加到缓冲区(aof_buf)
  2. 文件写入(write)和文件同步(sync):根据不同的同步策略将缓冲区中的内容同步到硬盘;
  3. 文件重写(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%时进行重写 
优势
  1. AOF更加耐用,可以以秒级别为单位备份,如果发生问题,也只会丢失最后一秒的数据,大大增加了可靠性和数据完整性。所以AOF可以每秒备份一次,使用fsync操作。
  2. 以log日志形式追加,如果磁盘满了,会执行 redis-check-aof 工具
  3. 当数据太大的时候,redis可以在后台自动重写aof。当redis继续把日志追加到老的文件中去时,重写也是非常安全的,不会影响客户端的读写操作。
  4. AOF 日志包含的所有写操作,会更加便于redis的解析恢复。
劣势
  1. 相同的数据,同一份数据,AOF比RDB大
  2. 针对不同的同步机制,AOF会比RDB慢,因为AOF每秒都会备份做写操作,这样相对与RDB来说就略低。 每秒备份fsync没毛病,但是如果客户端的每次写入就做一次备份fsync的话,那么redis的性能就会下降。
  3. AOF发生过bug,就是数据恢复的时候数据不完整,这样显得AOF会比较脆弱,容易出现bug,因为AOF没有RDB那么简单,但是为了防止bug的产生,AOF就不会根据旧的指令去重构,而是根据当时缓存中存在的数据指令去做重构,这样就更加健壮和可靠了。

总结:

  1. Redis 默认开启RDB持久化方式,在指定的时间间隔内,执行指定次数的写操作,则将内存中的数据写入到磁盘中。
  2. RDB 持久化适合大规模的数据恢复但它的数据一致性和完整性较差。
  3. Redis 需要手动开启AOF持久化方式,默认是每秒将写操作日志追加到AOF文件中。
  4. AOF 的数据完整性比RDB高,但记录内容多了,会影响数据恢复的效率。
  5. Redis 针对 AOF文件大的问题,提供重写的瘦身机制。
  6. 若只打算用Redis 做缓存,可以关闭持久化。
  7. 若打算使用Redis 的持久化。建议RDB和AOF都开启。使用RDB和AOF结合一起做持久化,RDB做冷备,可以在不同时期对不同版本做恢复,AOF做热备,保证数据仅仅只有1秒的损失。当AOF破损不可用了,那么再用RDB恢复,这样就做到了两者的相互结合,也就是说Redis恢复会先加载AOF,如果AOF有问题会再加载RDB,这样就达到冷热备份的目的了。