上篇文章: redis知识盘点【贰】_五种类型
因为redis是内存数据库,其所有数据都是保存在内存中,那么当服务器进程挂掉,数据将丢失。为了解决这个问题,redis支持了将数据持久化到本地硬盘中,具体实现有RDB和AOF两种方案。
RDB(redis database)
是把当前进程数据生成内存快照保存到硬盘的过程,分手动触发和自动触发两种情况。RDB持久化生成的RDB文件是一个经过压缩的二进制文件,通过它可以还原生成RDB文件时的数据库状态。
手动触发:
save:阻塞当前redis服务器,直到RDB过程完成为止,对于内存比较大的实例会造成长时间阻塞,线上环境一定不要使用。基本已废弃。
bgsave:redis进程执行fork操作传经子进程,父进程继续处理命令请求,RDB持久化过程由子进程来完成,完成后自动结束。阻塞发生在fork阶段,时间很短。
自动触发4种情况:
1.执行save m n :当m秒内数据集存在n次修改时,自动触发bgsave;
2.如果从节点执行全量复制操作,主节点自动执行bgsave生成RDB文件并发送给从节点;
3.执行debug reload命令重新加载redis时,会触发save操作;
4.默认情况下执行shutdown时,如果没有开启AOF持久化功能则自动执行bgsave。
需要注意的是,在bgsave执行期间,客户端发送的save和bgsave命令都会被服务器拒绝,目的是为了避免父进程和子进程同时执行rdbSave调用而产生竞争条件。此外,bgsave和bgrewriteaof(此命令后面介绍)也不能同时执行:如果bgsave正在执行,那么bgrewriteaof会等待其执行完毕后再执行;如果bgrewriteaof在执行,那么bgsave命令会被拒绝。
redis没有专门用于载入RDB文件的命令,只要redis在启动时检测到RDB文件存在,就会自动进行载入,在载入期间redis会一直处于阻塞状态,直到载入完成为止。
RDB默认是开启的,在.conf配置文件中还有如下相关参数:
#根据给定的时间间隔和写入次数将数据保存到磁盘
# 900秒(15分钟)之后,且至少1次变更
save 900 1
# 300秒(5分钟)之后,且至少10次变更
save 300 10
# 60秒之后,且至少10000次变更
save 60 10000
# 当导出到 .rdb 数据库时是否用LZF压缩字符串对象,默认都设为 yes
rdbcompression yes
# 是否校验rdb文件,版本5的RDB有一个CRC64算法的校验和放在了文件的最后。这将使文件格式更加可靠。
rdbchecksum yes
# 持久化数据库的文件名
dbfilename dump.rdb
# 工作目录
# 例如上面的 dbfilename 只指定了文件名,但是它会写入到这个目录下。这个配置项一定是个目录,而不能是文件名
dir ./
RDB的优点:
RDB是一个紧凑压缩的二进制文件,代表Redis在某个时间点上的数据快照。非常适用于备份,全量复制等场景。比如每6小时执行bgsave备份,并把RDB文件拷贝到远程机器或者文件系统中(如hdfs), 用于灾难恢复。
Redis加载RDB恢复数据远远快于AOF的方式。
RDB的缺点:
RDB方式数据没办法做到实时持久化/秒级持久化。因为bgsave每次运行都要执行fork操作创建子进程,属于重量级操作,频繁执行成本过高。
RDB文件使用特定二进制格式保存,Redis版本演进过程中有多个格式的RDB版本,存在老版本Redis服务无法兼容新版RDB格式的问题。
针对RDB不适合实时持久化的问题,Redis提供了AOF持久化方式来解决。
AOF(append only file)
以独立日志的方式记录每次写命令,重启时再重新执行AOF文件中的命令达到恢复数据的目的。AOF的主要作用是解决了数据持久化的实时性, 目前已经是Redis持久化的主流方式。理解掌握好AOF持久化机制对我们兼顾数据安全性和性能非常有帮助。AOF也支持手动触发和自动触发。
手动触发:
bgrewriteaof
自动触发:
在Redis配置文件redis.conf中,用户设置了auto-aof-rewrite-percentage(当前aof文件空间和上一次重写后aof文件空间的比值)和auto-aof-rewrite-min-size(aof重写时文件最小体积,默认64MB)参数,并且当前AOF文件大小server.aof_current_size大于auto-aof-rewrite-min-size(server.aof_rewrite_min_size),同时AOF文件大小的增长率大于auto-aof-rewrite-percentage(server.aof_rewrite_perc)时,会自动触发AOF rewrite。
AOF的主要流程分为命令追加、文件写入和文件同步三个步骤。
首先redis所有的写入命令都追加到aof_buf缓冲区的末尾;然后缓冲区根据对应的策略向硬盘做写入和文件同步的工作,策略包括:
always(命令写入aof_buf后调用系统fsync同步到aof文件,fsync完成后线程返回);【不建议】
everysec(命令写入aof_buf后调用系统write操作,write完成后线程返回。fsync同步文件操作一秒一次);
no(命令写入aof_buf后调用系统write操作,不对文件进行sync同步。同步由操作系统完成,一般不超过30s)。
关于系统提供的write和fsync两个同步函数的特点:
write:会触发延迟写机制。如果同步前系统宕机,缓冲区数据将丢失;
fsync:针对单个文件做强制硬盘同步,fsync将阻塞直到硬盘完成后返回,保证数据持久化。
随着aof文件越来越大,需要定期对aof文件重写,达到压缩的目的,文件重写的优点有:
1.只保留最终数据的写入命令;
2.多个同样命令合并为1个;
AOF默认是关闭的,如需开启需要在.conf配置文件中进行修改,但注意,如果开启后那么系统将自动关闭RDB持久化。相关参数如下:
appendonly yes:设置开启,默认不开启
appendfilename fileName:执行文件名,默认appendonly.aof
appendfsync always/everysec/no:同步策略,默认everysec
no-appendfsync-on-rewrite yes/no:是否在日志重写时不进行命令追加操作,默认no
auto-aof-rewrite-percentage 100:当前aof文件空间和上一次重写后aof文件空间的比值,默认100
auto-aof-rewrite-min-size 64mb:aof重写时文件最小体积,默认64M
下一篇讲一讲redis的sentinel(哨兵)功能。