内容简介:本文主要回答如下问题:RDB持久化是将进程数据写入文件,而AOF持久化(即Append Only File持久化),则是将Redis执行的每次
本文主要回答如下问题:
-
Redis如何做持久化的?
Redis的持久化支持2种方式:rdb 和aof 两种方式。这个和 mysql 的binlog支持几种格式有点类似。比如mysql binlog支持(row(数据快照,二进制格式),statement(文本,存修改操作的 sql 语句),mix)等等多种格式。rbd类似于mysql的row,aof类似于mysql的statement。 复制代码
目录
- RDB 持久化
- AOF 持久化
- 两种持久化方式比较
RDB 持久化
RDB持久化是将当前进程中的数据生成快照保存到硬盘(因此也称作快照持久化),保存的文件后缀是rdb;当 Redis 重新启动时,可以读取快照文件恢复数据。 复制代码
-
触发条件
RDB持久化的触发分为手动触发和自动触发两种。 复制代码
-
1)手动触发 通过手动执行save命令和bgsave命令都可以生成RDB文件。
save命令会阻塞Redis服务器进程,直到RDB文件创建完毕为止,在Redis服务器阻塞期间,服务器不能处理任何命令请求。而bgsave命令会创建一个子进程,由子进程来负责创建RDB文件,父进程(即Redis主进程)则继续处理请求。bgsave命令执行过程中,只有fork子进程时会阻塞服务器,而对于save命令,整个过程都会阻塞服务器,因此save已基本被废弃,线上环境要杜绝save的使用,后文中也将只介绍bgsave命令。此外,在自动触发RDB持久化时,Redis也会选择bgsave而不是save来进行持久化。 复制代码
备注: fork 子进程时会阻塞,而fork的过程与redis进程占用的内存大小有关,占用内存过大时,fork阻塞时间会变长。
-
2)自动触发
自动触发是通过redis的配置文件中save m n 进行条件配置的,指的是在m秒内发生n次修改时,会触发进行bgsave。 复制代码
其中save 900 1的含义是:当时间到900秒时,如果Redis数据发生了至少1次变化,则执行bgsave;save 300 10和save 60 10000同理。当三个save条件满足任意一个时,都会引起bgsave的调用。 复制代码
提示: 因为自动触发需要满足一定的配置条件后才能触发,因而在redis出现故障时,可能部分数据还没有被持久化到rdb文件中,因而会出现数据丢失
。
- 触发bgsave的其他方式
-
在主从复制场景下,如果从节点执行全量复制操作,则主节点会执行bgsave命令,并将生成的rdb文件发送给从节点;
-
执行shutdown命令时,自动执行rdb持久化。
-
RDB文件
RDB文件是经过压缩的二进制文件。Redis默认采用LZF算法对RDB文件进行压缩。虽然压缩耗时,但是可以大大减小RDB文件的体积,因此压缩默认开启 复制代码
RDB常用配置总结
save m n:bgsave自动触发的条件;如果没有save m n配置,相当于自动的RDB持久化关闭,不过此时仍可以通过其他方式触发。 stop-writes-on-bgsave-error yes:当bgsave出现错误时,Redis是否停止执行写命令;设置为yes,则当硬盘出现问题时,可以及时发现,避免数据的大量丢失;设置为no,则Redis无视bgsave的错误继续执行写命令,当对Redis服务器的系统(尤其是硬盘)使用了监控时,该选项考虑设置为no。 rdbcompression yes:是否开启RDB文件压缩。 rdbchecksum yes:是否开启RDB文件的校验,在写入文件和读取文件时都起作用;关闭checksum在写入文件和启动文件时大约能带来10%的性能提升,但是数据损坏时无法发现。 dbfilename dump.rdb:RDB文件名。 dir ./:RDB文件和AOF文件所在目录。 复制代码
AOF持久化
RDB持久化是将进程数据写入文件,而AOF持久化(即Append Only File持久化),则是将Redis执行的每次 写命令
记录到单独的日志文件中,当Redis重启时再次执行AOF文件中的命令来恢复数据。相比RDB,AOF的优先级要高。
-
开启AOF
Redis服务器默认开启RDB,关闭AOF;要开启AOF,需要在配置文件中配置:
appendonly yes 复制代码
AOF 命令执行过程:
-
命令写入(append)
Redis先将写命令追加到缓冲区,而不是直接写入文件,主要是为了避免每次有写命令都直接写入硬盘,导致硬盘IO成为Redis负载的瓶颈。 复制代码
-
文件写入(write)和文件同步(sync)
Redis提供了多种AOF缓存区的同步文件策略,策略涉及到操作系统的write函数和fsync函数,说明如下: 为了提高文件写入效率,在现代操作系统中,当用户调用write函数将数据写入文件时,操作系统通常会将数据暂存到一个内存缓冲区里,当缓冲区被填满或超过了指定时限后,才真正将缓冲区的数据写入到硬盘里。这样的操作虽然提高了效率,但也带来了安全问题:如果计算机停机,内存缓冲区中的数据会丢失;因此系统同时提供了fsync、fdatasync等同步函数,可以强制操作系统立刻将缓冲区中的数据写入到硬盘里,从而确保数据的安全性。 复制代码
AOF缓存区的同步文件策略由参数appendfsync控制,各个值的含义如下:
always:命令写入aof_buf后立即调用系统fsync操作同步到AOF文件,fsync完成后线程返回。这种情况下,每次有写命令都要同步到AOF文件,硬盘IO成为性能瓶颈,Redis只能支持大约几百TPS写入,严重降低了Redis的性能;即便是使用固态硬盘(SSD),每秒大约也只能处理几万个命令,而且会大大降低SSD的寿命。 no:命令写入aof_buf后调用系统write操作,不对AOF文件做fsync同步;同步由操作系统负责,通常同步周期为30秒。这种情况下,文件同步的时间不可控,且缓冲区中堆积的数据会很多,数据安全性无法保证。 everysec:命令写入aof_buf后调用系统write操作,write完成后线程返回;fsync同步文件操作由专门的线程每秒调用一次。everysec是前述两种策略的折中,是性能和数据安全性的平衡,因此是Redis的默认配置,也是我们推荐的配置。 复制代码
-
文件重写(rewrite)
随着时间流逝,Redis服务器执行的写命令越来越多,AOF文件也会越来越大;过大的AOF文件不仅会影响服务器的正常运行,也会导致数据恢复需要的时间过长。 复制代码
文件重写的触发,分为手动触发和自动触发:
手动触发:
直接调用bgrewriteaof命令,该命令的执行与bgsave有些类似:都是fork子进程进行具体的工作,且都只有在fork时阻塞。 复制代码
自动触发:
根据auto-aof-rewrite-min-size和auto-aof-rewrite-percentage参数,以及aof_current_size和aof_base_size状态确定触发时机。 auto-aof-rewrite-min-size:执行AOF重写时,文件的最小体积,默认值为64MB。 auto-aof-rewrite-percentage:执行AOF重写时,当前AOF大小(即aof_current_size)和上一次重写时AOF大小(aof_base_size)的比值。 只有当auto-aof-rewrite-min-size和auto-aof-rewrite-percentage两个参数同时满足时,才会自动触发AOF重写,即bgrewriteaof操作。 复制代码
-
AOF 常用配置项:
appendonly no:是否开启AOF appendfilename "appendonly.aof":AOF文件名 dir ./:RDB文件和AOF文件所在目录 appendfsync everysec:fsync持久化策略 no-appendfsync-on-rewrite no:AOF重写期间是否禁止fsync;如果开启该选项,可以减轻文件重写时CPU和硬盘的负载(尤其是硬盘),但是可能会丢失AOF重写期间的数据;需要在负载和安全性之间进行平衡 auto-aof-rewrite-percentage 100:文件重写触发条件之一 auto-aof-rewrite-min-size 64mb:文件重写触发提交之一 aof-load-truncated yes:如果AOF文件结尾损坏,Redis启动时是否仍载入AOF文件 复制代码
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。