百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术教程 > 正文

分布式缓存 - Redis进阶(二)(持久化)

mhr18 2024-11-19 06:51 25 浏览 0 评论

1、总体介绍

Redis是一个基于内存的数据库,它的数据是存放在内存中,内存有个问题就是关闭服务或者断电会丢失。Redis的数据也支持写到硬盘中,这个过程就叫做持久化

Redis提供了2种不同形式的持久化方式。

  • RDB(Redis DataBase)
  • AOP(Append Of File)

2、RDB(Redis DataBase)

2.1、RDB是什么?

在指定的时间间隔内将内存中的数据集快照写入磁盘,也就是行话讲的Snapshot快照,它恢复时是键快照文件直接读到内存里。

2.2、备份是如何执行的

Redis会单独创建(fork)一个子进程进行持久化,会先将数据写入到一个临时文件中,待持久化过程都结束后,再用这个临时文件替换上次持久化好的文件。整个过程中,主进程是不进行任何IO操作的,这就是确保了极高的性能,如果需要进行大规模的恢复,且对数据恢复的完整性不是非常敏感,那RDB方式没有AOF方式更加的高效。RDB的缺点是最后一次持久化后的数据可能丢失。

2.3、Fork

  • Fork的作用是复制一个与当前进程一样的进程,新进程的所有数据(变量、环境变量、程序计数器等)数值都和原进程一致,它是一个全新的进程,并作为原进程的子进程。
  • 在Linux程序中,fork()会产生一个和父进程完全相同的子进程,但子进程在此后多会exec系统调用,处于效率考虑,linux中引入了“写时复制技术”。
  • 一般情况父进程和子进程会共用一段物理内存,只有进程空间的各段的内容要发生变化时,才会将父进程的内容复制一份给子进程。

2.4、RDB持久化流程

2.5、指定备份文件的名称

在redis.conf中,可以修改rdb备份文件的名称,默认为dump.rdb,如下:

dbfilename dump.rdb

2.6、指定备份文件存放的目录

在redis.conf中,rdb文件的保存的目录是可以修改的,默认为Redis启动命令所在的目录,如下:

2.7、触发RDB备份

方式1:自动备份,需配置备份规则

可在redis.conf中配置自动备份的规则,默认规则如下:

save用来配置备份的规则

save的格式:save秒钟写操作次数

默认是1分钟内修改了1万次,或5分钟内需修改了10次,或30分钟内修改了1次。

示例:设置20秒内有最少有3次key发生变化,则进行备份:

save 20 3

方式2:手动执行命令备份(save | bgsave)

有2个命令可以触发备份。

  • save:save时只管保存,其他不管,全部阻塞,手动保存,不建议使用。
  • bgsave:redis会在后台异步进行快照操作,快照同时还可以响应客户端情况。

可以通过 lastsave 命令获取最后一次成功生成快照的时间。

bgsave的写时复制(COW)机制:

Redis 借助操作系统提供的写时复制技术(Copy-On-Write, COW),在生成快照的同时,依然可以正常处理写命令。简单来说,bgsave 子进程是由主线程 fork 生成的,可以共享主线程的所有内存数据。bgsave 子进程运行后,开始读取主线程的内存数据,并把它们写入 RDB 文件。此时,如果主线程对这些数据也都是读操作,那么,主线程和 bgsave 子进程相互不影响。但是,如果主线程要修改一块数据,那么,这块数据就会被复制一份,生成该数据的副本。然后,bgsave 子进程会把这个副本数据写入 RDB 文件,而在这个过程中,主线程仍然可以直接修改原来的数据。
save与bgsave对比:

命令

save

bgsave

IO类型

同步

异步

是否阻塞redis其它命令

否(在生成子进程执行调用fork函

数时会有短暂阻塞)

复杂度

O(n)

O(n)

优点

不会消耗额外内存

不阻塞客户端命令

缺点

阻塞客户端命令

需要fork子进程,消耗内存

配置自动生成rdb文件后台使用的是bgsave方式。

方式3:flushall命令

执行flushall命令,也会产生dump.rdb文件,但里面是空的,无意义。

2.8、redis.conf 其他一些配置

stop-writes-on-bgsave-error:当磁盘满时,是否关闭redis的写操作

stop-writes-on-bgsave-error用来指定当redis无法写入磁盘的话,是否直接关掉redis的写操作,推荐yes。

rdbcompression:rdb备份是否开启压缩

对于存储到磁盘中的rdb快照文件,可以设置是否进行压缩,如果是的话,redis会采用LZF算法进行压缩。

如果你不想小号CPU来进行压缩的话,可以设置为关闭此功能,推荐yes。

rdbchecksum:是否检查rdb备份文件的完整性

存储快照后,还可以让redis使用CRC64算法来进行数据校验,但是这样做会增加大约10%的性能消耗,如果希望获取最大的性能提升,可以关闭此功能。

推荐yes。

2.9、rdb的备份和恢复

  • 1. 先通过config get dir 查询rdb文件的目录
  • 2. 然后将rdb的备份文件 *.rdb 文件拷贝到别的地方
cpdump.rdbdump2.rdb
  • 3. rdb的恢复
  • a) 关闭redis
  • b) 先把备份的文件拷贝到工作目录cpdump2.rdbdump.rdb
  • c) 启动redis,备份数据直接加载,数据被恢复

2.10、优势与劣势

优势:

  • 适合大规模数据恢复
  • 对数据完整性和一致性要求不高更适合使用
  • 节省磁盘空间
  • 恢复速度快

劣势:

  • Fork的时候,内存中的数据会被克隆一份,大致2倍的膨胀,需要考虑。
  • 虽然Redis在fork的时候使用了写时拷贝技术,但是如果数据庞大时还是比较消耗性能。
  • 在备份周期在一定间隔时间做一次备份,所以如果Redis意外down的话,就会丢失最后一次快照后所有修改。

2.11、停止RDB

动态停止RDB: redis-cli config set save " " #save后给空值,表示禁用保存策略。

3、AOP(Append Of File)

3.1、AOP是什么?

以日志的形式来记录每个写操作(增量保存),将redis执行过的所有写指令记录下来(读操作不记录),只允追加文件但不可改写文件,redis启动之初会读取该文件重新构造数据,换言之,redis重启的话就根据日志文件的内容将写指令从前到后执行一次以完成数据的恢复工作。

3.2、AOF持久化流程

  • 客户端的请求写命令会被append追加到AOF缓冲区内
  • AOF缓冲区会根据AOF持久化策略[always,everysec,no]将操作sync同步到磁盘的AOF文件中
  • AOF文件大小超过重写策略或手动重写时,会对AOF文件进行重写(rewrite),压缩AOF文件容量
  • redis服务器重启时,会重新load加载AOF文件中的写操作达到数据恢复的目的

3.3、AOF默认不开启

可以在 redis.conf 文件中对AOF进行配置

appendonly no   # 是否开启AOF,yes:开启,no:不开启,默认为no
appendfilename "appendonly.aof"   # aof文件名称,默认为appendonly.aof
dir ./   # aof文件所在目录,默认./,表示执行启动命令时所在的目录,比如我们在/opt目录中,去执行
redis-server /etc/redis.conf 来启动redis,那么dir此时就是/opt目录

3.4、AOF和RDB同时开启,redis听谁的?

AOF和RDB同时开启,系统默认取AOF的数据(数据不会存在丢失)

3.5、AOF启动/修复/恢复

AOF的备份机制和性能虽然和RDB不同,但是备份和恢复的操作同RDB一样,都是拷贝备份文件,需要恢复时再拷贝到Redis工作目录下,启动系统即加载。

  • a) 正常恢复

修改默认的appendonly no,改为yes

将有数据的aof文件复制一份保存到对应的目录(查看目录:config get dir)

恢复:重启redis然后重新加载


  • b) 异常恢复

修改默认的appendonly no,改为yes

如遇到aof文件损坏,通过 /usr/local/bin/redis-check-aof --fix appendonly.aof 进行恢复

3.6、AOF同步频率设置

可以在redis.config中配置AOF同步的频率

  • appendfsync always:每次写入立即同步

始终同步,每次redis的写入都会立刻记入日志;性能较差但数据完整性比较好。

  • appendfsync everysec:每秒同步

每秒同步,每秒记录日志一次,如果宕机,本秒数据可能丢失;更新的命令会放在内存中AOF缓冲区,每秒将缓冲区的命令追加到AOF文件。

  • appendfsync no:不主动同步

redis不主动进行同步,把同步交给操作系统。

推荐(并且也是默认)的措施为每秒 fsync 一次, 这种 fsync 策略可以兼顾速度和安全性。

3.7、rewrite压缩(AOF文件压缩)

rewrite压缩是什么?

AOF采用文件追加方式,文件会越来越大,为了避免出现此情况,新增了重写机制,当AOF文件的大小超过锁审定的阈值时,Redis就会启动AOF文件的内容压缩,只保留可以恢复数据的最小指令集,可以使用命令bgrewriteaof触发重写。

重写原理,如何实现重写?

AOF文件持续增长而过大时,会fork出一条新进程来将文件重写(也是先写临时文件,最后在rename替换旧文件),redis4.0版本后的重写,是指就把rdb的快照,以二进制的形式附在新的aof头部,作为已有的历史数据,替换掉原来的流水账操作。

触发机制,何时重写?

  • bgrewriteaof:手动触发重写

a)从 Redis 2.4 开始, AOF 重写由 Redis 自行触发, bgrewriteaof 仅仅用于手动触发重写操作。

b)redis会记录上次重写的aof大小,默认配置是当aof文件大小是上次rewrite后大小的2倍且文件大于64M时触发。

c)重写虽然可以节约大量磁盘空间,减少恢复时间,但是每次重写还是有一定负担的,因此设置redis满足一定条件才会进行重新。

d)AOF重写redis会fork出一个子进程去做(与bgsave命令类似),不会对redis正常命令处理有太多影响。

  • auto-aof-rewrite-percentage:设置重写基准值

设置重写的基准值,默认100,当文件达到100%时开始重写(文件是原来重写后文件的2倍时重写)。

  • auto-aof-rewrite-min-size:设置重写基准值

设置重写的基准值,默认64MB,AOF文件大小超过这个值开始重写。

举个例子

文件达到70MB开始重写,降到50MB,下次什么时候开始重写?100MB

系统载入时或者上次重写完毕时,redis会记录此时AOF大小,设置base_size。

如果Redis的AOF当前大小>=base_size+base_size*100%( auto-aof-rewrite-percentage 默认值) 且 当前大小>=64mb( auto-aof-rewrite-min-size 默认值)的情况下,redis会对AOF进行重写。

重写流程:

127.0.0.1:6379> bgrewriteaof
Background append only file rewriting started
  • 手动执行 bgrewriteaof 命令触发重写,判断是否当前有bgfsave或bgrewriteaof在运行,如果有,则等待该命令结束后再继续执行。
  • 主进程fork出子进程执行重写操作,保证主进程不会阻塞。
  • 子进程遍历redis内存中的数据到临时文件,客户端的写请求同时写入aof_buf缓冲区和aof_rewrite_buf重写缓冲区保证原AOF文件完整性以及新AOF文件生成期间的新的数据修改动作不会丢失。
  • 子进程写完新的AOF文件后,向主进程发送信号,父进程更新统计信息。
  • 主进程把aof_rewrite_buf中的数据写入到新的AOF文件。
  • 使用新的AOF文件覆盖旧的AOF文件,完成AOF重写。

no-appendfsync-on-rewrite:重写时,不会执行appendfsync操作

该参数表示在正在进行AOF重写时不会将AOF缓冲区中的数据同步到旧的AOF文件磁盘,也就是说在进行AOF重写的时候,如果此时有写操作进来,此时写操作的命令会放在aof_buf缓存中(内存中),而不会将其追加到旧的AOF文件中,这么做是为了避免同时写旧的AOF文件和新的AOF文件对磁盘产生的压力。

默认是ON,表示关闭,即在AOF重写时,会对AOF缓冲区中的数据做同步磁盘操作,这在很大程度上保证了数据的安全性。

但在数据量很大的场景,因为两者都会消耗磁盘IO,对磁盘的影响较大,可以将其设置为“yes”减轻磁盘压力,但在极端情况下可能丢失整个AOF重写期间的数据。

如果no-appendfsync-on-rewrite为yes,不写入aof文件,只写入缓存,用户请求不会阻塞,但是在这段时间如果宕机会丢失这段时间的缓存数据。(降低数据安全性,提高性能)

如果no-appendfsync-on-rewrite为no,还是会把数据库往磁盘里刷,但是遇到重写操作,可能会发生阻塞。(数据安全,但是性能降低)

3.8、AOF优势与劣势

优势:

  • 备份机制更稳健,丢失数据概率更低
  • 可读的日志文本,通过操作AOF文件,可以处理误操作

劣势:

  • 比RDB占用更多的磁盘空间
  • 恢复备份速度要慢
  • 每次读写都同步的话,有一定的性能压力
  • 存在个别bug,造成不能恢复

4、RDB 和 AOF应如何选择

命令

RDB

AOF

启动优先级

体积

恢复速度

数据安全性

容易丢数据

根据策略决定

生产环境可以都启用,redis启动时如果既有rdb文件又有aof文件则优先选择aof文件恢复数据,因为aof一般来说数据更全一点。

5、Redis 4.0 混合持久化

重启 Redis 时,我们很少使用 RDB来恢复内存状态,因为会丢失大量数据。我们通常使用 AOF 日志重放,但是重放 AOF 日志性能相对 RDB来说要慢很多,这样在 Redis 实例很大的情况下,启动需要花费很长的时间。 Redis 4.0 为了解决这个问题,带来了一个新的持久化选项——混合持久化。通过如下配置可以开启混合持久化(必须先开启aof):

# aof‐use‐rdb‐preamble yes

如果开启了混合持久化,AOF在重写时,不再是单纯将内存数据转换为RESP命令写入AOF文件,而是将重写这一刻之前的内存做RDB快照处理,并且将RDB快照内容和增量的AOF修改内存数据的命令存在一起,都写入新的AOF文件,新的文件一开始不叫appendonly.aof,等到重写完新的AOF文件才会进行改名,覆盖原有的AOF文件,完成新旧两个AOF文件的替换。

于是在 Redis 重启的时候,可以先加载 RDB 的内容,然后再重放增量 AOF 日志就可以完全替代之前的AOF 全量文件重放,因此重启效率大幅得到提升。

混合持久化AOF文件结构如下:

6、Redis数据备份策略:

  • 1. 写crontab定时调度脚本,每小时都copy一份rdb或aof的备份到一个目录中去,仅仅保留最近48小时的备份。
  • 2. 每天都保留一份当日的数据备份到一个目录中去,可以保留最近1个月的备份
  • 3. 每次copy备份的时候,都把太旧的备份给删了。
  • 4. 每天晚上将当前机器上的备份复制一份到其他机器上,以防机器损坏。

相关推荐

【推荐】一个开源免费、AI 驱动的智能数据管理系统,支持多数据库

如果您对源码&技术感兴趣,请点赞+收藏+转发+关注,大家的支持是我分享最大的动力!!!.前言在当今数据驱动的时代,高效、智能地管理数据已成为企业和个人不可或缺的能力。为了满足这一需求,我们推出了这款开...

Pure Storage推出统一数据管理云平台及新闪存阵列

PureStorage公司今日推出企业数据云(EnterpriseDataCloud),称其为组织在混合环境中存储、管理和使用数据方式的全面架构升级。该公司表示,EDC使组织能够在本地、云端和混...

对Java学习的10条建议(对java课程的建议)

不少Java的初学者一开始都是信心满满准备迎接挑战,但是经过一段时间的学习之后,多少都会碰到各种挫败,以下北风网就总结一些对于初学者非常有用的建议,希望能够给他们解决现实中的问题。Java编程的准备:...

SQLShift 重大更新:Oracle→PostgreSQL 存储过程转换功能上线!

官网:https://sqlshift.cn/6月,SQLShift迎来重大版本更新!作为国内首个支持Oracle->OceanBase存储过程智能转换的工具,SQLShift在过去一...

JDK21有没有什么稳定、简单又强势的特性?

佳未阿里云开发者2025年03月05日08:30浙江阿里妹导读这篇文章主要介绍了Java虚拟线程的发展及其在AJDK中的实现和优化。阅前声明:本文介绍的内容基于AJDK21.0.5[1]以及以上...

「松勤软件测试」网站总出现404 bug?总结8个原因,不信解决不了

在进行网站测试的时候,有没有碰到过网站崩溃,打不开,出现404错误等各种现象,如果你碰到了,那么恭喜你,你的网站出问题了,是什么原因导致网站出问题呢,根据松勤软件测试的总结如下:01数据库中的表空间不...

Java面试题及答案最全总结(2025版)

大家好,我是Java面试陪考员最近很多小伙伴在忙着找工作,给大家整理了一份非常全面的Java面试题及答案。涉及的内容非常全面,包含:Spring、MySQL、JVM、Redis、Linux、Sprin...

数据库日常运维工作内容(数据库日常运维 工作内容)

#数据库日常运维工作包括哪些内容?#数据库日常运维工作是一个涵盖多个层面的综合性任务,以下是详细的分类和内容说明:一、数据库运维核心工作监控与告警性能监控:实时监控CPU、内存、I/O、连接数、锁等待...

分布式之系统底层原理(上)(底层分布式技术)

作者:allanpan,腾讯IEG高级后台工程师导言分布式事务是分布式系统必不可少的组成部分,基本上只要实现一个分布式系统就逃不开对分布式事务的支持。本文从分布式事务这个概念切入,尝试对分布式事务...

oracle 死锁了怎么办?kill 进程 直接上干货

1、查看死锁是否存在selectusername,lockwait,status,machine,programfromv$sessionwheresidin(selectsession...

SpringBoot 各种分页查询方式详解(全网最全)

一、分页查询基础概念与原理1.1什么是分页查询分页查询是指将大量数据分割成多个小块(页)进行展示的技术,它是现代Web应用中必不可少的功能。想象一下你去图书馆找书,如果所有书都堆在一张桌子上,你很难...

《战场兄弟》全事件攻略 一般事件合同事件红装及隐藏职业攻略

《战场兄弟》全事件攻略,一般事件合同事件红装及隐藏职业攻略。《战场兄弟》事件奖励,事件条件。《战场兄弟》是OverhypeStudios制作发行的一款由xcom和桌游为灵感来源,以中世纪、低魔奇幻为...

LoadRunner(loadrunner录制不到脚本)

一、核心组件与工作流程LoadRunner性能测试工具-并发测试-正版软件下载-使用教程-价格-官方代理商的架构围绕三大核心组件构建,形成完整测试闭环:VirtualUserGenerator(...

Redis数据类型介绍(redis 数据类型)

介绍Redis支持五种数据类型:String(字符串),Hash(哈希),List(列表),Set(集合)及Zset(sortedset:有序集合)。1、字符串类型概述1.1、数据类型Redis支持...

RMAN备份监控及优化总结(rman备份原理)

今天主要介绍一下如何对RMAN备份监控及优化,这里就不讲rman备份的一些原理了,仅供参考。一、监控RMAN备份1、确定备份源与备份设备的最大速度从磁盘读的速度和磁带写的带度、备份的速度不可能超出这两...

取消回复欢迎 发表评论: