问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

Redis持久化原理详解

创作时间:
作者:
@小白创作中心

Redis持久化原理详解

引用
CSDN
1.
https://blog.csdn.net/weixin_44991038/article/details/140390217

Redis持久化是将内存中的数据持久化保存到磁盘上,以便于redis服务器重启后恢复之前的内存数据。Redis提供了三种持久化机制:RDB、AOF和混合持久化。本文将深入讲解这三种机制的原理以及差异化。

一、概念

Redis持久化是将内存中的数据持久化保存到磁盘上,以便于redis服务器重启后恢复之前的内存数据。

二、机制

Redis提供了三种持久化机制,分别为RDB(Redis Database)、AOF(Append Only File)以及混合持久化方式。接下来深入讲解三种机制的原理以及差异化。

1、RDB(Redis Database)

RDB 机制是redis默认的持久化方式,会再某个时间点会将内存的数据快照写入二进制文件,这个文件称为RDB 文件。并将二进制文件写入到磁盘。一般为.rdb文件 默认为dump.rdb。

RDB实现持久化和数据恢复主要依靠两个核心函数rdbSave 和 rdbLoad。rdbSave函数将数据快照写入到RDB文件,rdbLoad函数将数据从文件加载到内存。

1. rdbSave函数机制

工作机制

a. save命令:执行SAVE命令时,redis服务器会阻塞客户端命令,直到rdbSave函数完成RDB文件的创建。在这个过程中,redis无法接受新的命令请求,直到文件创建完成后才可以。

b. bgsave命令:与SAVE命令不同,是采用的写时复制机制(Copy-On-Write,COW)。bgsave命令通过主线程的fork创建一个子进程来执行rdbSave函数,而父进程(redis服务器主进程)正常处理客户端的请求。这样redis持久化操作就不会影响到正常的服务提供。

内部实现

a.通过fork创建子进程,并继承主进程的内存空间(采用写时复制机制,减少内存空间)。

b.子进程遍历redis内存中所有的键值对,并使用rdbSvaeObject等函数将每个对象进行二进制序列化写入到RDB文件。

c.序列化过程中,redis会对数据进行进行压缩加快写入文件,减少文件体积。

d.RDB文件创建完成后,子进程会向父进程发送信号,通知父进程RDB文件创建完成。

配置选项

在redis的配置文件中可以通过SAVE指令来设置自动触发RDB快照的条件。如 “svae 60 10000” 表示在60s内有10000个写入操作,触发自动执行一次RDB数据快照保存。

命令
save
bgsave
IO类型
同步
异步
是否阻塞redis其他命令
否(调用fork函数生成子进程时会短暂阻塞)
复杂度
O(n)
O(n)
优点
不会消耗额外内存
不阻塞客户端命令
缺点
阻塞客户端命令
需要fork子进程,消耗内存

2. rdbLoad函数机制

rdbLoad函数负责在redis重启后将RDB文件中的数据加载到数据库的内存中。

工作机制

a.redis启动时会检查配置文件的指定目录下是否有RDB文件。

b.若存在RDB文件,redis会调用rdbLoad函数来加载文件。

c.rdbLoad函数会读取RDB文件中内容,并反序列化文件中redis对象到内存中,从而恢复数据量状态。

d.在加载RDB文件过程中,redis服务器处于阻塞状态,直到RDB文件加载完成。

3. RDB持久化的优缺点

优点

a. 恢复速度快:由于RDB文件是一个紧凑的二进制文件,文件体积小,加载速度快。因此恢复数据的速度比AOF快。

b. 文件体积小:RDB文件在写入前进行了压缩,因此文件体积小,有利于文件传输和备份。

c. 适合灾备恢复:RDB文件文件体积小,适合文件传输到其他存储介质上,非常适合用于灾备恢复。

缺点

a. 数据丢失风险:若redis在两次RDB持久化之间发生故障,则最后一次RDB持久化后的数据就会丢失(数据不一致)。

b. 内存占用:在fork创建的子进程进行RDB持久化过程中,子进程会占用与父进程相同的内存资源,可能会导致redis性能下降。

c. 版本兼容:RDB文件为一个二进制文件,不同版本的redis之间可能存在兼容性问题。

2、AOF(Append Only File)

AOF持久化机制是通过包含redis服务器所执行的写命令来记录数据库状态。AOF文件以追加的方式记录redis所执行过的所有修改的命令,将每一条修改命令记录进文件appendonly.aof中(先写入os cache,每个一段时间fsync到磁盘)。redis服务重启时会重新执行AOF文件中的命令来实现数据恢复到内存中。可以修改配置文件来打开AOF功能: #appendonly yes

1. 持久化原理

a. 记录写操作:AOF以日志的形式记录redis所有执行的修改命令(读操作不记录),且只需追加文件内容不能改写文件。每当有一个修改命令操作时,该命令就会被追加到AOF文件末尾。

b. 数据恢复:redis重启时,会读取AOF文件并重新执行文件中的写命令,从而将数据恢复到重启前状态。

2. 持久化实现步骤

AOF持久化功能实现主要分为命令追加、文件写入、文件同步、文件重写、重启加载五部分。

a. 命令追加:当AOF持久化开启时,服务器在执行完一个写命令后,redis不会直接阻塞服务器来等待AOF文件写入完成。redis采用异步写入策略,会将这个命令以RESP协议格式追加到AOF缓冲区(aof_buf 一个内存中的数据结构)中。

b. 文件写入:redis服务器进程是一个事件循环,在每个事件循环结束前,会使用后台一个线程(或进程)会调用flushAppendOnlyFile函数将AOF缓冲区(aof_buf)中的命令内容写到AOF文件中。这个后台过程不会阻塞redis主线程处理新的命令。

c. 文件同步:AOF文件会根据appendfsync参数设置的持久化策略同步到磁盘,appendfsync参数有三种设置:

  1. appendfsync always:每次有新命令写入到AOF缓冲区时,执行一次fsync将命令追加到AOF文件中,非常慢,也非常安全。

2)appendfsync everysec:每次写命令写入到aof_buf后,每隔一秒同步到磁盘(默认设置推荐),足够快并且在故障时只会丢失1秒的数据。

  1. appendfsync no:每次写命令写入到aof_buf后,从不fsync,将数据交给操作系统来处理,更快,也更不安全。

d. 文件重写:随着服务器运行时间增加,AOF文件会越来越大,这会影响redis重启时间。因此redis提供了AOF重写机制,通过创建一个新的AOF文件来替代就文件,新文件只包含恢复当前数据集所需的最小命令集。重写过程也是异步进行的,并且不会阻塞redis处理新命令。

  1. 重写操作由后台子进程进行,不阻塞主进程处理客户端的命令。

  2. 重写期间,新的写命令会被同时追加到现在AOF文件和重写文件的AOF缓存区(aof_buf)中。

  3. 重写完成后,主进程会将重写缓存区中的命令追加到新的AOF文件中,并替代旧文件。

通过两个参数来配置AOF重写频率

auto_aof_rewrite_min_size 64mb // aof文件至少达到64M才会自动重写,文件太小本来恢复速度就很快,从写意义不大

auto_aof_rewrite_percentage 100 // aof文件自上次重写后文件大小增加了100%则再次触发重写

e. 重启加载:redis重启后,会加载AOF文件,并重新执行文件中写命令来恢复内存数据。

3. AOP持久化的优缺点

优点

a. 提供多种持久化策略,可以根据需要选择合理的策略。

b. AOF文件是一个纯文本文件,易于理解、修改和恢复。

c. 对于误操作的数据可以通过修改AOF文件来恢复。

d. 数据更加安全,即使出现宕机,也只是丢失最近一次AOF文件写入之后的数据。

缺点

a. 文件大,相对RDB文件,AOF文件大。

b. 恢复速度慢,由于文件比RDB大,恢复速度就会比RDB慢。

c. 性能较差,AOF文件写入性能通常比RDB差,特别是有大量写入操作的场景下。

RDB与AOF对比

命令
RDB
AOF
启动优先级
体积
恢复速度
数据安全性
容易丢数据
根据策略决定

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

3、Redis4.0 混合持久化

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

采用混合持久化方式的前提是必须先开启AOF方式。通过#aof-use-rdb-preamble yes 配置来开启混合持久化。所以混合持久化可称为AOF方式升级。

1、混合持久化作用

AOF重写

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

Redis重启

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

4、总结

通过对Redis持久化方式分析,我们知道不同的持久化方式是有不同的优缺点的,在使用时需要根据具体的业务场景分析选择合适的持久化方式将数据写入到磁盘。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号