Redis持久化概念
什么是持久化?
持久化用一句话来概括:将数据(如内存中的对象)存放到可永久保存的存储设备,如数据库、磁盘文件或XML中。
什么是Redis持久化?
众所周知,Redis和Memcache一样,为了保证效率,数据都是缓存在内存中的,这就导致一旦重启系统或系统故障后,缓存在内存中的Redis数据将无法找回,所以,为了Redis数据能够长期保存,Redis提供了持久化机制,将数据从内存写入磁盘文件。
Redis持久化流程
1、客户端向服务端发送写操作**【数据在客户端内存】**
2、服务端接收到写操作数据**【数据在服务端内存】**
3、服务端调用系统write将数据写入磁盘缓冲**【数据在系统内存缓冲区】**
4、操作系统将内存缓冲区数据转移至磁盘控制器**【数据在磁盘缓冲】**
5、磁盘控制器将数据写入磁盘的物理介质**【数据在磁盘中】**
而关于这个过程的实现,Redis提供了两种持久化的策略:RDB持久化和AOF持久化
RDB持久化
RDB:中文名为快照/内存快照,是一个非常紧凑的文件,它保存了某个时间点的数据集,非常适用于数据集的备份
RDB持久化:Redis的默认持久化方式,将某个时间点的所有数据都以快照文件的形式存放到硬盘上【全量备份】,默认文件名为dump.rdb。【我们可以理解为Redis为某一时刻的所有数据拍了张照】**
RDB持久化原理
RDB持久化三种触发机制:save、bgsave以及自动触发
save
手动在客户端执行save命令,调用服务端将此刻所有数据写入临时快照文件,当所有数据写入完成,如果存在旧快照文件,则替换掉旧快照文件。
缺点:执行save命令期间,会**阻塞当前Redis服务器**,Redis不能处理其他命令,直到RDB过程完成为止。
对于内存比较大的实例会造成长时间阻塞,线上环境不建议使用
bgsave
手动在客户端执行bgsave命令,服务端调用fork()创建子进程,由子进程将此刻所有数据写入临时快照文件,当所有数据写入完成,如果存在旧快照文件,则替换掉旧快照文件。
bgsave命令执行过程是异步的,RDB持久化由子进程执行,主进程仅在fork()阶段阻塞一小段时间。
基本上Redis内部所有的RDB操作都是采用bgsave命令
自动触发
自动触发RDB持久化由**配置文件来完成,通过在redis.conf配置相关项,由Redis按照指定周期规则触发执行bgsave命令进行RDB持久化**。
相关配置:**
# 周期性执行条件的设置格式
save <seconds> <changes>
# 默认的设置
save 900 1 # 900秒内有一条记录发生变化,触发一次快照
save 300 10 # 300秒内有10条记录发生变化,触发一次快照
save 60 10000 # 60秒内有10000条记录发生变化,触发一次快照
# 关闭RDB自动快照功能
save ""
# 如果快照操作出现异常(例如操作系统用户权限不够、磁盘空间写满等等)时,Redis就会禁止写操作,默认为yes
stop-writes-on-bgsave-error yes
# 是否使用LZF压缩算法压缩快照文件,被压缩后文件会更小,默认值为yes
rdbcompression yes
# 生成RDB快照文件的名称
dbfilename dumn.rdb
# 存放RDB快照文件的路径
dir ./
RDB持久化优点
1、RDB快照是一个紧凑的二进制文件,非常适用于备份,全量复制等场景【如主从复制的初始阶段会触发bgsave进行全量复制】
2、灾后恢复,Redis通过RDB恢复数据的速度远远快于AOF方式
RDB持久化缺点
1、RDB持久化不能做到实时持久化/秒级持久化,bgsave命令要求主进程fork一个子进程,而这个过程的执行成本过高,不适合频繁操作
2、当Redis故障或系统故障时,可能会丢失最近一段时间的Redis数据库数据【尚未触发持久化】
AOF持久化
AOF:Append Only File,仅进行新增的文件
AOF持久化:记录每次对服务器写的操作,当服务器重启的时候会重新执行这些命令来恢复原始的数据**,AOF命令以redis协议追加保存每次写的操作到文件末尾.Redis还能对AOF文件进行后台重写,使得AOF文件的体积不至于过大
简单理解就是,AOF持久化通过记录每一个对服务器的**写操作,类似于日志,当需要恢复数据的时候重新执行这些命令即可恢复原始数据,主要目的是为了解决数据持久化的实时性问题。
**
AOF持久化原理
工作流程:
1、客户端向服务端发送写命令
2、服务端调用系统write函数将写命令同步追加到AOF缓冲区【Redis使用单线程操作命令,为了提高性能,不直接操作硬盘,而是先写入缓冲区】
3、AOF缓冲区根据对应策略向硬盘做同步操作到AOF文件
4、当文件越来越大,需要定期对AOF文件进行重写,达到压缩的目的
持久化
AOF持久化也有三种触发机制,对应配置文件reids.conf中的appendfsync配置项:
1、always 每修改一次Redis就触发一次aof持久化,性能较差但数据完整性比较好
2、everysec 每秒就触发一次持久化,异步操作,如果一秒内故障,会丢失数据
3、no 从不同步,Redis不会将执行成功的操作命令刷入AOF文件,而是完成操作系统级别的写操作后就认为AOF文件记录成功了,后续的I/O操作完全依赖于操作系统的设定,一般30秒会刷一次。
一般选中everysec策略,最多损失1秒的数据。
持久化相关配置项:
# 是否打开AOF功能,默认no
appendonly yes
# AOF文件的名字
appendfilename "appendonly.aof"
# AOF持久化策略
appendfsync everysec
AOF文件重写
AOF重写过程可以手动触发和自动触发
自动触发:根据配置文件进行自动重写
手动触发:用户可以向Redis发送 BGREWRITEAOF命令 ,这个命令会通过移除AOF文件中的冗余命令来重写(rewrite)AOF文件来减小AOF文件的体积。
BGREWRITEAOF命令和BGSAVE创建快照原理十分相似,所以AOF文件重写也需要用到子进程,这样会导致性能问题和内存占用问题,和快照持久化一样。
更糟糕的是,如果不加以控制的话,AOF文件的体积可能会比快照文件大好几倍。
具体流程如下图【类似于bgsave命令】:
重写前后文件对比:
AOF重写相关配置:
# 触发AOF重写时文件最小体积,默认为64MB
auto-aof-rewrite-min-size 64mb
# 触发AOF重写的增长率,代表当前AOF文件大小 (aof_current_size)和上一次重写后AOF文件大小(aof_base_size)的比值
auto-aof-rewrite-percentage 100
AOF持久化优点
1、数据完整性保障,AOF提供三种持久化策略:每秒、写触发、从不,即便使用默认的每秒触发持久化,如果发生故障也只是丢失了1秒的数据
2、AOF比RDB文件更安全,没有任何磁盘寻找的开销,写入性能更高,文件不容易破损
3、AOF重写也不会阻塞主进程
4、AOF以一种非常可读的方式记录写操作,即便发生错误,也可以通过AOF快速查找问题命令,然后删除问题写命令记录,执行恢复即可。
AOF持久化缺点
1、同一份数据来说,AOF文件通常比RDB快照文件更大
2、据所使用的持久化策略,AOF 的速度可能会慢于 RDB 。 在一般情况下, 每秒触发持久化的性能依然非常高, 而关闭持久化可以让 AOF 的速度和 RDB 一样快, 即使在高负荷之下也是如此。 不过在处理巨大的写入载入时,RDB 可以提供更有保证的最大延迟时间
持久化选择
一般来说, 如果想达到足以媲美 PostgreSQL 的数据安全性, 你应该同时使用两种持久化功能。
如果你非常关心你的数据, 但仍然可以承受数分钟以内的数据丢失, 那么你可以只使用 RDB 持久化。
有很多用户都只使用 AOF 持久化, 但我们并不推荐这种方式: 因为定时生成 RDB 快照(snapshot)非常便于进行数据库备份, 并且 RDB 恢复数据集的速度也要比 AOF 恢复的速度要快, 除此之外, 使用 RDB 还可以避免之前提到的 AOF 程序的 bug 。