Redis持久化
一、Redis概述
Redis(Remote Dictionary Server):远程字典服务器,是一个可基于内存亦可持久化的日志型、key-value数据库,Redis支持两种持久化方式RDB和AOF.
二、RDB
2.1、什么是RDB
RDB:Redis DataBase,在指定的时间间隔内将内存中的数据集快照写入到磁盘中,也就是所谓的snapshot,它恢复时是将快照直接读入内存中.
2.2、RDB实现原理
Redis会单独创建(fork)一个子进程来进行持久化,它会将数据写入到一个临时文件中,待持久化过程完成后,再用这个临时文件替换掉上次持久化好的文件,整个过程中主进程是不会进行任何的IO操作的,这样就确保了极高的性能,如果需要进行大规模的数据恢复,并且对数据的完整性不是非常敏感,那么使用RDB方式就要比AOF方式更加的高效,RDB的缺点是最后一次的持久化数据有可能会丢失(最后一次数据未触发RDB持久化策略,也没有手动持久化,然后宕机了,这样最后一次的持久化数据就丢失了).
2.3、fork原理
fork就是复制出一个全新的进程,新进程所有的数据和原进程一模一样,并且是原进程的一个子进程.
2.4、如何触发RDB持久化
1、自动触发
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | ################################ SNAPSHOTTING ################################ # # Save the DB on disk: # # save <seconds> <changes> # # Will save the DB if both the given number of seconds and the given # number of write operations against the DB occurred. # # In the example below the behaviour will be to save: # after 900 sec ( 15 min) if at least 1 key changed # after 300 sec ( 5 min) if at least 10 keys changed # after 60 sec if at least 10000 keys changed # # Note: you can disable saving completely by commenting out all "save" lines. # # It is also possible to remove all the previously configured save # points by adding a save directive with a single empty string argument # like in the following example: # # save "" // 如果你只是想使用Redis的缓存功能,不需要使用持久化,那么你可以注释掉所有的save行,然后只打开 save ""这一行配置,这就代表禁用RDB持久化功能 save 900 1 // 900s内有一个写操作,Redis就会触发RDB持久化,将内存中的数据持久化到磁盘上. save 300 10 // 300s内有10个写操作,Redis就会触发RDB持久化,将内存中的数据持久化到磁盘上. save 60 10000 // 60s内有10000个写操作,Redis就会触发RDB持久化,将内存中的数据持久化到磁盘上. |
2、手动触发
save:该命令会阻塞当前Redis服务器,执行命令期间Redis不能处理其它命令,直到RDB持久化过程完成为止.
bgsave:为了解决save命令对于内存比较大的实例会造成长时间的阻塞,Redis提供了bgsave命令,执行该命令时,Redis会在后台异步进行快照操作,快照操作的同时还能响应客户端的请求,具体的操作是Redis进程执行fork操作创建子进程,RDB持久化过程由子进程负责,阻塞只发生在fork阶段,一般持续很短的时间.
flushall:使用该命令也会手动触发RDB持久化,对应的dump.rdb是空的.
1 | -rw-r--r--. 1 root root 92 7 月 30 00 : 24 redis- 6379 -dump.rdb //dump.rdb的大小为92,代表dump.rdb是一个空文件 |
shutdown:客户端执行shutdown关闭Redis后台服务
2.5、RDB常用配置详解
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | #RDB核心规则配置 save <指定时间间隔> <执行指定次数更新操作>,满足条件就将内存中的数据同步到硬盘中. 官方出厂配置默认是: 900 秒内有 1 个更改 300 秒内有 10 个更改 60 秒内有 10000 个更改 如果满足上面设置的触发条件,则将内存中的数据快照写入磁盘. 若不想用RDB方案,可以把 save "" 的注释打开,代表禁用RDB持久化方案. # save "" save 900 1 // 900s内如果有一个更改则触发RDB保存,文件名为xxx.dump save 300 10 // 300s内如果有10个更改,则触发保存 save 60 10000 // 60s内如果有10000个更改则触发保存 #当RDB持久化出现错误后,是否依然继续进行工作 yes:不能进行工作 no:可以继续进行工作 可以通过info中的rdb_last_bgsave_status了解RDB持久化是否有错误 stop-writes-on-bgsave-error yes #配置存储至本地数据库时是否压缩数据,默认为yes。 Redis采用LZF压缩方式,但占用了一点CPU的时间.若关闭该选项,但会导致数据库文件变的非常巨大.建议开启. rdbcompression yes #是否校验rdb文件,从rdb格式的第五个版本开始,在rdb文件的末尾会带上CRC64的校验和. 这样做有利于文件的容错性,但是在保存rdb文件的时候,会有大概 10 %的性能损耗. 所以如果你追求高性能,可以关闭该配置. rdbchecksum yes #指定本地数据库文件名,一般采用默认的dump.rdb dbfilename dump.rdb #数据目录,数据库的写入会在这个目录.rdb、aof文件也会写在这个目录. 例如 dir配置为./ dbfilename配置为dump.rdb,那么你的持久化数据保存在 ./dump.rdb路径下 例如 dir配置为/opt/myredis/var dbfilename配置为dump6379.rdb那么redis使用rdb持久化的数据保存在 /opt/myredis/var/dump6379.rdb路径下. dir ./ |
三、AOF
3.1、什么是AOF
AOF:Append Only File,以日志的形式记录每一个写操作,将Redis执行过的所有写指令记录下来(读指令不记录),只允许追加文件但是不能改写文件,Redis启动之初会读取该文件然后重新构建数据,换言之,Redis重启就是根据日志文件的内容将所有的写指令重新执行一次,以完成数据的恢复工作.
3.2、如何开启AOF方式持久化Redis数据
Redis默认情况下是不开启AOF持久化方式的,如果要开启AOF持久化方式需要在Redis配置文件中进行配置,将下面配置修改为yes(默认是no).
1 | appendonly yes |
3.3、同时开启RDB和AOF,那么Redis重新启动恢复数据的时候到底会采用哪种方式恢复数据呢.
Redis默认情况下使不开启AOF持久化方式的,如果RDB和AOF同时开启的情况下,Redis恢复数据会优先采用AOF的方式恢复数据,这样丢失的数据会更少.
3.4、AOF重写原理和机制
1、为什么会重写
AOF采用文件追加的方式,随着时间的推移,.aof文件会越来越大,为了避免这种情况,AOF方式增加了重写机制,当AOF文件的大小超过所设定的阈值时,Redis就会启动AOF文件的内容压缩,只保留可以恢复数据的最小指令集,可以使用命令bgrewriteof来手动重写.
2、重写原理
AOF文件持续增长而过大时,会fork出一条新的进程来将文件重写(也是先写临时文件,然后再rename),遍历新进程内存中的数据,然后根据内存中的数据而创建出可以恢复数据的最小指令集,重写AOF文件操作的时候,并没有读取旧的AOF文件,而是将真个内存中的数据库内容用命令的方式重写了一个新的AOF文件.
3、如何触发重写
重写虽然可以节约大量的磁盘空间,恢复数据时也可以减少时间,但是每次重写还是有负担的,需要满足下列条件才能触发重写机制
1 2 3 4 5 6 7 8 | auto-aof-rewrite-percentage 100 auto-aof-rewrite-min-size 64mb 系统载入时或者上次重写完毕时,Redis会记录此时AOF文件的大小,假设为base_size, 如果当前RedisAOF文件 大小>=base_size*( 100 + 100 )% 大小>64mb 同时满足这两个条件时便会触发重写机制 |
4、AOF常用配置详解
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | ################################# APPEND ONLY MODE ################################# #Redis 默认不开启AOF.它的出现是为了弥补RDB的不足(未触发RDB持久化策略,然后宕机的情况下,最后一次未持久化的数据可能会丢失可能会丢失). 所以它采用日志的形式来记录每个写操作,并追加到文件中.Redis重启的会根据日志文件的内容将写指令从前到后执行一次 以完成数据的恢复工作,默认redis使用的是rdb方式持久化,这种方式在许多应用中已经足够用了.但是redis如果中途宕机, 会导致可能有几分钟的数据丢失,根据save策略来进行持久化. Append Only File是另一种持久化方式,可以提供更好的持久化特性.Redis会把每次写入的数据在接收后都写入 appendonly.aof 文件 每次启动时Redis都会先把这个文件的数据读入内存中,如果开启rdb则使用appendonly no,如果开启aof则使用 appendonly yes appendonly no #指定aof模式下本地数据库文件名,默认值为 appendonly.aof appendfilename "appendonly.aof" #aof持久化策略的配置: no表示不执行fsync,由操作系统保证数据同步到磁盘,速度最快 everysec表示每秒执行一次fsync,可能会导致丢失这1s数据 always表示每次写入都执行fsync,以保证数据同步到磁盘,速度最慢 默认使用 everysec appendfsync always appendfsync everysec appendfsync no # 在aof重写或者写入rdb文件的时候,会执行大量IO,此时对于everysec和always的aof模式来说,执行 fsync会造成阻塞过长时间,no-appendfsync-on-rewrite字段设置为默认设置为no.如果对延迟要求很高的 应用,这个字段可以设置为yes,否则还是设置为no,这样对持久化特性来说这是更安全的选择.设置为yes表 示rewrite期间对新写操作不fsync,暂时存在内存中,等rewrite完成后再写入,默认为no,建议yes.Linux的 默认fsync策略是 30 秒。可能丢失 30 秒数据 no-appendfsync-on-rewrite no #aof自动重写配置.当目前aof文件大小超过上一次重写的aof文件大小的百分之多少进行重写, 即当aof文件增长到一定大小的时候Redis能够调用bgrewriteaof对日志文件进行重写. 当前AOF文件大小是上次日志重写得到AOF文件大小的二倍(设置为 100 )时,自动启动新的日志重写过. auto-aof-rewrite-percentage 100 #设置允许重写的最小aof文件大小,避免了达到约定百分比但.aof文件尺寸仍然很小的情况还要重写 auto-aof-rewrite-min-size 64mb #aof文件可能在尾部是不完整的,当redis启动的时候,aof文件的数据被载入内存. 重启可能发生在redis所在的主机操作系统宕机后,尤其在ext4文件系统没有加上data=ordered选项 (redis宕机或者异常终止不会造成尾部不完整现象.)出现这种现象,可以选择让redis退出, 或者导入尽可能多的数据.如果选择的是yes,当截断的aof文件被导入的时候, 会自动发布一个log给客户端然后load.如果是no,用户必须手动redis-check-aof修复AOF文件才可以 aof-load-truncated yes #加载redis时,可以识别AOF文件以“redis”开头.字符串并加载带前缀的RDB文件,然后继续加载AOF尾巴 aof-use-rdb-preamble yes |
4、RDB和AOF的区别以及选择
RDB | AOF | |
区别 | RDB持久化是指在指定的时间间隔内将内存中的数据集快照写入磁盘,实际操作过程是fork一个子进程,先将数据集写入临时文件,写入成功后,再替换之前的文件,用二进制压缩存储. | AOF持久化以日志的形式记录服务器所处理的每一个写、删除操作,查询操作不会记录,以文本的方式记录,可以打开文件看到详细的操作记录. |
优点 | 这种文件非常适合用于进行备份: 比如说,你可以在最近的 24 小时内,每小时备份一次 RDB 文件,并且在每个月的每一天,也备份一个 RDB 文件。 这样的话,即使遇上问题,也可以随时将数据集还原到不同的版本。RDB 非常适用于灾难恢复(disaster recovery)。 | 使用 AOF 持久化会让 Redis 变得非常耐久(much more durable):你可以设置不同的 fsync 策略,比如无 fsync ,每秒钟一次 fsync ,或者每次执行写入命令时 fsync 。 AOF 的默认策略为每秒钟 fsync 一次,在这种配置下,Redis 仍然可以保持良好的性能,并且就算发生故障停机,也最多只会丢失一秒钟的数据( fsync 会在后台线程执行,所以主线程可以继续努力地处理命令请求)。 |
缺点 | 如果你需要尽量避免在服务器故障时丢失数据,那么 RDB 不适合你。 虽然 Redis 允许你设置不同的保存点(save point)来控制保存 RDB 文件的频率, 但是, 因为RDB 文件需要保存整个数据集的状态, 所以它并不是一个轻松的操作。 因此你可能会至少 5 分钟才保存一次 RDB 文件。 在这种情况下, 一旦发生故障停机, 你就可能会丢失好几分钟的数据。 | 对于相同的数据集来说,AOF 文件的体积通常要大于 RDB 文件的体积。根据所使用的 fsync 策略,AOF 的速度可能会慢于 RDB。 在一般情况下, 每秒 fsync 的性能依然非常高, 而关闭 fsync 可以让 AOF 的速度和 RDB 一样快, 即使在高负荷之下也是如此。 不过在处理巨大的写入载入时,RDB 可以提供更有保证的最大延迟时间(latency)。 |
选择 |
如果你非常关心你的数据,但仍然可以承受数分钟以内的数据丢失, 那么你可以选择使用 RDB 持久化. |
如果你非常关心你的数据的完整性,并且可以接受处理巨大的写入而导致Redis 的性能降低的负面影响,那么你可以选择使用AOF持久化. |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?