【Redis】持久化机制

目录

前言:

RDB

触发RDB持久化方法有俩种:

1.手动触发

2.自动触发

RDB文件的优缺点:

AOF:

AOF工作机制:​编辑

​编辑重写机制:


前言:

Redis是一个内存数据库,将数据存储在内存中,追求速度快,但内存中的数据是不持久的,遇到突发情况,一旦重启内存中数据就没了~

为了保证速度快,数据一定要存储在内存中,但为了持久,数据也得存储在硬盘中;

插入一个新的数据,内存和硬盘都要写入,当查询数据的时候,从内存中读取即可;

硬盘上的数据为了Redis重启的时候,用来恢复内存中的数据;虽然同一份数据存储了俩遍,但硬盘比较便宜,无所谓~

Redis实现持久化方式:
1.RDB(Redis DataBase)定期备份
2.AOF (Append Only File) 实时备份


RDB

RDB持久化将内存中的所有数据,写入到硬盘中,生成一个"快照",一旦重启之后,后面可以根据这个"快照"将数据恢复到内存中

快照路径: cd /var/lib/redis

文件是一个二进制文件,里面的内容不可乱修改,如果后续再启动Redis的时候,发现格式有错误,有可能数据加载失败,导致启动不了Redis

rdb文件中的数据,不是插入了数据,就会立即更新的!!!

此次的数值可以修改的 但是生成一个rdb快照本身就是一个比较高的成本,不能让这个操作执行太频繁~

假设此时在 10:00:00 生成了一次rdb

10:00:01 这时redis插入了10000条数据

10:01:00 生成下一个"快照"

此时如果在10:00:01时间点服务器挂了 那么后面的数据将全部丢失

所以在RDB机制下可能会丢失数据

触发RDB持久化方法有俩种:

1.手动触发

  • save命令:执行sava命令时候,redis将全力以赴的执行快照生成操作,将会阻塞redis其他客户端的命令,直到RDB过程完成,将会造成长时间的阻塞(不推荐使用)

  • bgsave命令:background(后面)不会影响redis服务器处理其他客户端的命令和请求,会执行"fork"操作,生成一个子进程;父进程继续处理客户端请求,让这个子进程负责持久化操作;子进程会生成一个新的RDB文件,将数据写入这个新的文件;子进程完成数据写入并关闭文件时,父进程会接受到信号,通知RDB文件更新完成;最后父进程会使用新的RDB文件,确保持久化的内容是新的,如果持久化发生错误,那么Redis会保持原来的RDB文件,确保数据一致性;

由于持久化速度太快,很难凭肉眼观看是否文件已经持久化,可以通过linux中的stat命令,查看文件的inode编号~~

2.自动触发

1. 使用 save 配置。如 "save m n" 表示 m 秒内数据集发生了 n 次修改,自动 RDB 持久化。


2. 从节点进行全量复制操作时,主节点自动进行 RDB 持久化,随后将 RDB 文件内容发送给从结点。
3. 执行 shutdown 命令(类似service redis-server restart)关闭 Redis 时,执行 RDB 持久化。

RDB文件的优缺点:

  • RDB 是一个紧凑压缩的二进制文件,代表 Redis 在某个时间点上的数据快照。非常适用于备份,全量复制等场景。比如每 6小时执行 bgsave 备份,并把 RDB 文件复制到远程机器或者文件系统中(如 hdfs)用于灾备。
  • Redis 加载 RDB 恢复数据远远快于 AOF 的方式。

RDB使用二进制的方式组织数据,AOF利用文本的方式组织数据

  • RDB 方式数据没办法做到实时持久化 / 秒级持久化。因为 bgsave 每次运行都要执行 fork 创建子进程,属于重量级操作,频繁执行成本过高。
  • RDB 文件使用特定二进制格式保存,Redis 版本演进过程中有多个 RDB 版本,兼容性可能有风险

RDB最大的问题在于不能实时化保存数据,在俩次快照之间,实时的数据可能会丢失的情况;


AOF:

AOF (Append Only File)持久化主要作用是解决了数据持久化的实时性

类似MySQL中的binlog,将用户的每次操作,记录到文件中,实时的记录了每一条数据,当Redis重新启动,会读取AOF文件中的数据,用来恢复数据;

当开启AOF的时候,RDB不再生效;

所在的位置跟RDB文件地址一样 /var/lib/redis

AOF工作机制:

为什么AOF又写内存还写硬盘,会影响Redis运行速度吗?

实际上是没有影响的

1.AOF机制并非直接把数据写入硬盘,而是写入内存缓冲区,累积一波,再统一写入硬盘,大大减低了写硬盘的次数;

2.AOF是顺序写入数据,读取数据的时候是比随机写入快很多的

如果在AOF写入内存缓冲区的时候,Redis掉电,那么数据也会丢失,但Redis提供了一些选项,供你选择缓冲区的刷新策略:

重写机制:

当AOF文件持续增大时,就会影响到Redis下次启动时间~

AOF文件中有一些内容是冗余的

例如

set key 111 set key 222 set key 333 -> set key 333

set key 111 del key set key2 222 del key2 -> 啥都不做即可

因此Redis存在一个机制,可以将AOF文件进行整理操作,能够剔除其中的冗余操作,达到合并的效果,给AOF文件达到瘦身的效果

父进程fork创建子进程,父进程仍然接收客户端的请求,子进程针对AOF文件重写,与RDB类似

此时子节点继承了父进程的内存状态,但fork之后新来的请求,子节点并不知道;所以父节点准备了一个aof_rewrite_buf缓冲区专门放fork之后收到的数据,最后,当子节点把AOF数据写入完通知信号给父进程时,父进程再把 aof_rewrite_buf缓冲区内容一起写入新的AOF文件中~
所以AOF是实时备份;


选择:

因为AOF按文本的方式写入文件,但文本格式后续加载成本太高
最后Redis采用了"混合持久化"的方法,结合AOF和RDB的优点,有文本也有二进制数据

在Redis重启根据持久化恢复数据,会以AOF为主,因为数据更全

相关推荐
S-X-S5 分钟前
集成Sleuth实现链路追踪
java·开发语言·链路追踪
快乐就好ya13 分钟前
xxl-job分布式定时任务
java·分布式·spring cloud·springboot
沉默的煎蛋20 分钟前
MyBatis 注解开发详解
java·数据库·mysql·算法·mybatis
Aqua Cheng.21 分钟前
MarsCode青训营打卡Day10(2025年1月23日)|稀土掘金-147.寻找独一无二的糖葫芦串、119.游戏队友搜索
java·数据结构·算法
呼啦啦啦啦啦啦啦啦21 分钟前
【Redis】事务
数据库·redis·缓存
石明亮(JT)37 分钟前
docker部署jenkins
java·docker·jenkins
翻晒时光1 小时前
Java 多线程与并发:春招面试核心知识
java·jvm·面试
小张认为的测试1 小时前
Jenkins邮件通知的详细配置含邮件通知模板!
java·servlet·ci/cd·jenkins·邮件通知
灯火不休ᝰ1 小时前
[java] java基础-字符串篇
java·开发语言·string
励志去大厂的菜鸟1 小时前
系统相关类——java.lang.Math (三)(案例详细拆解小白友好)
java·服务器·开发语言·深度学习·学习方法