redis持久化浅析

redis数据是保存在内存中,如果redis关闭数据就会丢失,为了避免这种情况,所以需要把redis数据进行持久化到磁盘。这样下次启动就可以使用持久化的数据文件将进行恢复了。

RDB

全量持久化

备份命令:

# 同步全量持久化
save
# 异步全量持久化
bgsave

save:同步执行,方法调用后会立即执行持久化方法,由于redis是单线程模型,主线程会阻塞,所以备份过程中是无法为其他客户端提供服务的。

bgsave:持久化过程会fork出一个子进程执行,只有fork时会阻塞主线程,真正的持久化任务是在子进程中进行执行的,所以并不会阻塞主进程执行其他任务,是异步的。

RDB方式的持久化是必然离不开了这两个命令的,不过触发方式可以分为手动触发和自动触发

手动触发:客户端手动执行命令

自动触发:设定相关的策略,在redis的配置文件redis.conf

save 900 1
save 300 10
save 60 10000

save 900 1表示:如果距离上一次创建RDB文件已经过去的900秒时间内,Redis中的数据发生了1次改动,则自动执行BGSAVE命令

save 300 10表示:如果距离上一次创建RDB文件已经过去的300秒时间内,Redis中的数据发生了10次改动,则自动执行BGSAVE命令

save 60 10000表示:如果距离上一次创建RDB文件已经过去了60秒时间内,Redis中的数据发生了10000次改动,则自动执行BGSAVE命令

当三个条件中的任意一个条件被满足时,Redis就会自动执行BGSAVE命令

RDB执行流程

  1. 执行save、basave、shutdowm命令时触发
  2. fork持久化子进程开始执行持久化任务。
  3. 遍历hashtable,利用copy on write,把整个内存dump下来。

rdb中有两个核心概念 fork 和copy-on-write ,执行数据备份的流程如下:

在执行basave的时候,redis首先会fork一个子进程得到一个新的子进程。子进程是共享主进程内存数据的,会将数据写入到磁盘上一个临时的rdb文件中,当子进程写完临时文件后,会将原来的.rdb文件替换掉,这个就是fork的概念。fork时主进程不进行任何磁盘IO操作,保证redis的高性能。

那cow全称就是 copy-on-write,当主进程执行读操作的时候是访问共享内存的,而主进程执行写操作的时候,则会copy一份数据,在新的内存区域中执行写操作。

AOF

增量持久化。

aof的安全性问题

aof会记录每一条数据修改的命令到aof文件中,但这并不意味着aof方式不会丢失数据。

在liunx系统中,系统调用write函数写入文件时,为了提高写入磁盘效率,系统通常不会将数据直接写入磁盘,而是先把数据保存到硬盘的缓冲区中,而当缓冲区中的内容未刷写到磁盘中时,这个时候系统宕机,则缓冲区中数据会丢失。

等缓冲区的数据被填满,或者用户执行fsync和fdatasync调用时,操作系统才会将存储在缓冲区里的内容真正写入到磁盘中。

对aof方式记录日志时,只有当命令记录被真正持久化到磁盘时,这条数据才不会丢失。

因此,aof持久化在宕机时丢失的数据量,取决于命令被写入到硬盘的时间,越早将命令写入到硬盘,写丢失数据的概率越小,越迟写入到磁盘则可能丢失的数据量就越大,而相应的数据存储效率就更慢。

aof执行策略:

为了控制redis 在意外停机时丢失的数据量,redis为aof持久化方式提高了appendfsync方式进行控制,配置的可选值如下:

appendfsync 可选值解释
always每条命令都会刷写到磁盘,但是写入时间是通过事件循环同步到磁盘中的,所以在redis意外宕机时,会丢失一个事件循环中执行的数据。
everysec每秒记录aof日志刷写到磁盘中,最多只丢失1s中记录的日志数据。
no服务器不主动调用fdatasync,由操作系统决定将系统缓冲区里面的数据刷写到磁盘中,这种模式下,redis宕机丢失的数据是无法确定的。最多丢失一个缓冲区中记录的日志。
从持久化数据的安全性上来讲,aways最安全,但是从数据存储效率上来讲,no方式是存储最快的。而redis的默认设置了折中的方式everysec,合情合理。

AOF的配置相关项

配置项可选值释义
appendonlyyes开启AOF持久化方式
append filenameappendonly.aof生成aof日志文件名称
appendfsynceverysecAOF日志刷盘策略:每秒钟刷新日志到磁盘
no-appendfsync-no-rewriteyes noAOF日志重写时:是否做append操作
yes:不做
no:做
不做append时可能丢失整个rewrite期间所有的AOF日志操作记录。

:::info

  1. 建议把appendfsync选项设定为everysec,进行持久化,这种情况下Redis宕机最多只会丢失一秒 钟的数据。
  2. 如果使用Redis做为缓存时,即使数据丢失也不会造成任何影响,只需要在下次加载时重新从数据 源加载就可以了。
  3. 不要占用redis 100%的内存,一般分配服务器60~70%的内存给redis使用,剩余的内存留给持久化的 fork 任务操作。

:::

AOF执行流程

每执行一次数据操作命令,就记录一次,如果appendfsync配置为aways,则至多丢失一次数据记录。

AOF文件重写

为了解决AOF文件体积不断增大的问题,用户可以使用bgrewriteaof命令,将aof文件进行重写压缩,也可以在配置文件中配置,自动触发。

auto-aof-rewrite-precentage 100
auto-aof-rewrite-min-size 64mb

通过append方式写入文件,即使记录过程总宕机,可以通过redis-check-aof工具解决数据一次性问题。

aof机制的rewrite模式,aof文件大小在触发重写机制时,可以重写内存中所有的数据,从而大幅缩小文件体积。

比rdb持久化启动效率低,因为日志文件通常比较大,而且所有命令需要执行,当数据极大时更加明显。

需要定期重写来降低文件体积。

优劣势对比

优势和劣势RDBAOF混合方式
备份方式某一点的内存数据全量备份。每条数据操作命令的增量备份
优势数据整块备份,整块恢复,备份文件小,数据恢复快。
rdb是一个紧凑的二进制文件,rdb重启时加载的效率比AOF更高,在数据量大时优势更明显。
只需记录数据操作,最高可每条记录都刷盘,安全性极高。
劣势备份数据时,需保存内存所有数据,备份耗费cpu,内存资源多,耗时久。因此无法高频率备份。数据频繁操作时,记录日志文件大,存储占用空间大,恢复日志耗时长。
自动触发策略save 900 1
save 300 10
save 60 10000
1. aways:修改同步
2. everysec:每秒同步
3. no:不主动调用fsync同步
数据恢复流程redis server 重启时
1. 优先使用aof日志恢复
2. 不存在aof则使用rdb文件恢复
从redis启动之初,记录每一条写操作开始执行,直至执行完所有aof日志,数据恢复很慢
文件保存方式dunp.rdb保存到appnedonly.aof文件中,具有可读性
数据完整性最后一次持久化之后新增修改的数据会丢失。aof利用apendfsync持久化机制,如果采用每秒记录日志的策略,如果一秒将结束时宕机,会丢失1秒钟的数据。
数据完整性要大于RDB方式。

:::info

  1. 如果能接受分钟及的数据丢失,可以选择使用rdb方式。
  2. 如果数据都是缓存,可从数据库恢复时,也可以不使用任何持久化方式。

总结:如果想达到数据恢复快速和数据的安全性来说,应该同时使用两种持久化方式。

:::

数据恢复流程

  1. 如果只配置 AOF ,重启时加载 AOF 文件恢复数据。
  2. 如果只配置 RDB,启动将加载 dump文件恢复数据。
  3. 如果同时配置了 RDB 和 AOF ,启动只加载 AOF 文件恢复数据;

Redis 启动时加载数据的流程:

  1. AOF持久化开启且存在AOF文件时,优先加载AOF文件。
  2. AOF关闭或者AOF文件不存在时,加载RDB文件。
  3. 加载AOF/RDB文件成功后,Redis启动成功。
  4. AOF/RDB文件存在错误时,Redis启动失败并打印错误信息。

画板

混合持久化方式

RDB和AOF都有各自的缺点:

  1. RDB是每隔一段时间持久化一次, 故障时就会丢失宕机时刻与上一次持久化之间的数据,无法保证数据完整性。
  2. AOF存储的是指令序列, 恢复重放时要花费很长时间并且文件更大。

因为bg save 会耗费很长时间,不够实时,在redis突然宕机时不能完全备份到所有数据,所以需要AOF的方式来补充全量备份数据之后产生的数据。

Redis 4.0 提供了更好的混合持久化选项:

创建出一个同时包含 RDB 数据和 AOF 数据的 AOF 文件, 其中 RDB 数据位于 AOF 文件的开头, 它们储存了服务器开始执行重写操作时的数据库状态,

至于那些在重写操作执行之后执行的 Redis 命令, 则会继续以 AOF 格式追加到 AOF 文件的末尾, 也即是 RDB 数据之后。

Redis4.0的持久化方式(混合持久化执行流程)

持久化总结

在实际使用中需要根据Redis作为主存还是缓存、数据完整性和缺失性的要求、CPU和内存情况等诸多因素来确定适合自己的持久化方案,一般来说稳妥的做法包括:

  1. RDB与AOF同时使用:最安全的做法,即使AOF损坏无法修复,还可以用RDB来恢复数据,当然在持久化时对性能也会有影响。
  2. 只使用RDB:在Redis当简单缓存,没有缓存也不会造成缓存雪崩的情况下可只使用RDB即可。
  3. 单独使用AOF:不推荐,因为AOF对于数据的恢复载入比RDB慢,所以使用AOF的时候,最好还是有RDB作为备份。
  4. 采用新版本Redis 4.0的持久化新方案。

本文由博客一文多发平台 OpenWrite 发布!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值