本篇文章给大家带来了关于redis的相关知识,其中主要介绍了关于持久化策略的相关内容,rdb持久化指的是在指定的时间间隔内将内存中的数据集快照写入磁盘,下面一起来看一下,希望对大家有帮助。

推荐学习:Redis视频教程
Redis(Remote Dictionary Server ),即远程字典服务,是一个开源的内存高速缓存数据存储服务。使用 ANSI C 语言编写,支持网络、可基于内存亦可持久化的日志型、Key-Value 数据存储,并提供多种语言的 API
Redis 是内存数据库,数据都是存储在内存中,为了避免进程退出导致数据的永久丢失,需要定期将 Redis 中的数据以某种形式(数据或命令)从内存保存到硬盘。当下次 Redis 重启时,利用持久化文件实现数据恢复。除此之外,为了进行灾难备份,可以将持久化文件拷贝到一个远程位置。Redis 的持久化机制有两种:
RDB 将当前数据保存到硬盘,AOF 则是将每次执行的写命令保存到硬盘(类似于 MySQL 的 Binlog)。AOF 持久化的实时性更好,即当进程意外退出时丢失的数据更少。
RDB ( Redis Data Base) 指的是在指定的时间间隔内将内存中的数据集快照写入磁盘,RDB 是内存快照(内存数据的二进制序列化形式)的方式持久化,每次都是从 Redis 中生成一个快照进行数据的全量备份。
优点:
缺点:

在默认情况下,Redis 将数据库快照保存在名字为 dump.rdb 的二进制文件中。RDB 文件结构由五个部分组成:
(1)长度为5字节的 REDIS 常量字符串。
(2)4字节的 db_version,标识 RDB 文件版本。
(3)databases:不定长度,包含零个或多个数据库,以及各数据库中的键值对数据。
(4)1字节的 EOF 常量,表示文件正文内容结束。
(5)check_sum: 8字节长的无符号整数,保存校验和。

数据结构举例,以下是数据库[0]和数据库[3]有数据的情况:

手动指令触发
手动触发 RDB 持久化的方式可以使用 s*e 命令和 bgs*e 命令,这两个命令的区别如下:
s*e:执行 s*e 指令,阻塞 Redis 的其他操作,会导致 Redis 无法响应客户端请求,不建议使用。
bgs*e:执行 bgs*e 指令,Redis 后台创建子进程,异步进行快照的保存操作,此时 Redis 仍然能响应客户端的请求。
自动间隔性保存
在默认情况下,Redis 将数据库快照保存在名字为 dump.rdb的二进制文件中。可以对 Redis 进行设置,让它在“ N 秒内数据集至少有 M 个改动”这一条件被满足时,自动保存一次数据集。
比如说, 以下设置会让 Redis 在满足“ 60 秒内有至少有 10 个键被改动”这一条件时,自动保存一次数据集:s*e 60 10。
Redis 的默认配置如下,三个设置满足其一即可触发自动保存:
s*e 60 10000 s*e 300 10 s*e 900 1
自动保存配置的数据结构
记录了服务器触发自动 BGS*E 条件的s*eparams属性。
lasts*e 属性:记录服务器最后一次执行 S*E 或者 BGS*E 的时间。
dirty 属性:以及自最后一次保存 RDB 文件以来,服务器进行了多少次写入。

RDB 持久化方案进行备份时,Redis 会单独 fork 一个子进程来进行持久化,会将数据写入一个临时文件中,持久化完成后替换旧的 RDB 文件。在整个持久化过程中,主进程(为客户端提供服务的进程)不参与 IO 操作,这样能确保 Redis 服务的高性能,RDB 持久化机制适合对数据完整性要求不高但追求高效恢复的使用场景。下面展示 RDB 持久化流程:

关键执行步骤如下
Redis 父进程首先判断:当前是否在执行 s*e,或 bgs*e/bgrewriteaof 的子进程,如果在执行则 bgs*e 命令直接返回。bgs*e/bgrewriteaof 的子进程不能同时执行,主要是基于性能方面的考虑:两个并发的子进程同时执行大量的磁盘写操作,可能引起严重的性能问题。
在生成 RDB 文件的步骤中,在同步到磁盘和持续写入这个过程是如何处理数据不一致的情况呢?生成快照 RDB 文件时是否会对业务产生影响?
上面说到了 RDB 持久化过程中,主进程会 fork 一个子进程来负责 RDB 的备份,这里简单介绍一下 fork:
在 Redis 中,RDB 持久化就是充分的利用了这项技术,Redis 在持久化时调用 glibc 函数 fork 一个子进程,全权负责持久化工作,这样父进程仍然能继续给客户端提供服务。fork 的子进程初始时与父进程(Redis 的主进程)共享同一块内存;当持久化过程中,客户端的请求对内存中的数据进行修改,此时就会通过 COW (Copy On Write) 机制对数据段页面进行分离,也就是复制一块内存出来给主进程去修改。

通过 fork 创建的子进程能够获得和父进程完全相同的内存空间,父进程对内存的修改对于子进程是不可见的,两者不会相互影响;
通过 fork 创建子进程时不会立刻触发大量内存的拷贝,采用的是写时拷贝 COW (Copy On Write)。内核只为新生成的子进程创建虚拟空间结构,它们来复制于父进程的虚拟究竟结构,但是不为这些段分配物理内存,它们共享父进程的物理空间,当父子进程中有更改相应段的行为发生时,再为子进程相应的段分配物理空间;
AOF (Append Only File) 是把所有对内存进行修改的指令(写操作)以独立日志文件的方式进行记录,重启时通过执行 AOF 文件中的 Redis 命令来恢复数据。类似MySql bin-log 原理。AOF 能够解决数据持久化实时性问题,是现在 Redis 持久化机制中主流的持久化方案。

优点:
缺点:
被写入 AOF 文件的所有命令都是以 RESP 格式保存的,是纯文本格式保存在 AOF 文件中。
Redis 客户端和服务端之间使用一种名为
RESP(REdis Serialization Protocol)的二进制安全文本协议进行通信。
下面以一个简单的 SET 命令进行举例:
redis> SET mykey "hello" //客户端命令OK
客户端封装为以下格式(每行用 \r\n分隔)
*3$3SET$5mykey$5hello
AOF 文件中记录的文本内容如下
一览妙笔
自媒体、编剧、营销人员写作工具
50
查看详情
*2\r\n$6\r\nSELECT\r\n$1\r\n0\r\n //多出一个SELECT 0 命令,用于指定数据库,为系统自动添加 *3\r\n$3\r\nSET\r\n$5\r\nmykey\r\n$5\r\nhello\r\n
AOF 持久化方案进行备份时,客户端所有请求的写命令都会被追加到 AOF 缓冲区中,缓冲区中的数据会根据 Redis 配置文件中配置的同步策略来同步到磁盘上的 AOF 文件中,追加保存每次写的操作到文件末尾。同时当 AOF 的文件达到重写策略配置的阈值时,Redis 会对 AOF 日志文件进行重写,给 AOF 日志文件瘦身。Redis 服务重启的时候,通过加载 AOF 日志文件来恢复数据。

AOF 的执行流程包括:
命令追加(append)
Redis 先将写命令追加到缓冲区 aof_buf,而不是直接写入文件,主要是为了避免每次有写命令都直接写入硬盘,导致硬盘 IO 成为 Redis 负载的瓶颈。
struct redisServer {
//其他域... sds aof_buf; // sds类似于J*a中的String //其他域...}文件写入(write)和文件同步(sync)
根据不同的同步策略将 aof_buf 中的内容同步到硬盘;
Linux 操作系统中为了提升性能,使用了页缓存(page cache)。当我们将 aof_buf 的内容写到磁盘上时,此时数据并没有真正的落盘,而是在 page cache 中,为了将 page cache 中的数据真正落盘,需要执行 fsync / fdatasync 命令来强制刷盘。这边的文件同步做的就是刷盘操作,或者叫文件刷盘可能更容易理解一些。
AOF 缓存区的同步文件策略由参数 appendfsync 控制,有三种同步策略,各个值的含义如下:
always:命令写入 aof_buf 后立即调用系统 write 操作和系统 fsync 操作同步到 AOF 文件,fsync 完成后线程返回。这种情况下,每次有写命令都要同步到 AOF 文件,硬盘 IO 成为性能瓶颈,Redis 只能支持大约几百TPS写入,严重降低了 Redis 的性能;即便是使用固态硬盘(SSD),每秒大约也只能处理几万个命令,而且会大大降低 SSD 的寿命。可靠性较高,数据基本不丢失。no:命令写入 aof_buf 后调用系统 write 操作,不对 AOF 文件做 fsync 同步;同步由操作系统负责,通常同步周期为30秒。这种情况下,文件同步的时间不可控,且缓冲区中堆积的数据会很多,数据安全性无法保证。everysec:命令写入 aof_buf 后调用系统 write 操作,write 完成后线程返回;fsync 同步文件操作由专门的线程每秒调用一次。everysec 是前述两种策略的折中,是性能和数据安全性的平衡,因此是 Redis 的默认配置,也是我们推荐的配置。文件重写(rewrite)
定期重写 AOF 文件,达到压缩的目的。
AOF 重写是 AOF 持久化的一个机制,用来压缩 AOF 文件,通过 fork 一个子进程,重新写一个新的 AOF 文件,该次重写不是读取旧的 AOF 文件进行复制,而是读取内存中的Redis数据库,重写一份 AOF 文件,有点类似于 RDB 的快照方式。
文件重写之所以能够压缩 AOF 文件,原因在于:
前面提到 AOF 的缺点时,说过 AOF 属于日志追加的形式来存储 Redis 的写指令,这会导致大量冗余的指令存储,从而使得 AOF 日志文件非常庞大,比如同一个 key 被写了 10000 次,最后却被删除了,这种情况不仅占内存,也会导致恢复的时候非常缓慢,因此 Redis 提供重写机制来解决这个问题。Redis 的 AOF 持久化机制执行重写后,保存的只是恢复数据的最小指令集,我们如果想手动触发可以使用如下指令:
bgrewriteaof
文件重写时机
相关参数:
同时满足下面两个条件,则触发 AOF 重写机制:
AOF 重写流程如下:
bgrewriteaof 触发重写,判断是否存在 bgs*e 或者 bgrewriteaof 正在执行,存在则等待其执行结束再执行
子进程遍历 Redis 内存快照中数据写入临时 AOF 文件,同时会将新的写指令写入 aof_buf 和 aof_rewrite_buf 两个重写缓冲区,前者是为了写回旧的 AOF 文件,后者是为了后续刷新到临时 AOF 文件中,防止快照内存遍历时新的写入操作丢失
子进程结束临时 AOF 文件写入后,通知主进程
主进程会将上面 3 中的 aof_rewirte_buf 缓冲区中的数据写入到子进程生成的临时 AOF 文件中

在实际中,为了避免在执行命令时造成客户端输入缓冲区溢出,重写程序会检查集合元素数量是否超过 REDIS_AOF_REWRITE_ITEMS_PER_CMD 常量的值,如果超过了,则会使用多个命令来记录,而不单单使用一条命令。
Redis 2.9版本中该常量为64,如果一个命令的集合键包含超过了64个元素,重写程序会拆成多个命令。

AOF重写是一个有歧义的名字,该功能是通过直接读取数据库的键值对实现的,程序无需对现有AOF文件进行任何读入、分析或者写入操作。
Redis 为什么考虑使用 AOF 而不是 WAL 呢?
很多数据库都是采用的 Write Ahead Log(WAL)写前日志,其特点就是先把修改的数据记录到日志中,再进行写数据的提交,可以方便通过日志进行数据恢复。
但是 Redis 采用的却是 AOF(Append Only File)写后日志,特点就是先执行写命令,把数据写入内存中,再记录日志。
如果先让系统执行命令,只有命令能执行成功,才会被记录到日志中。因此,Redis 使用写后日志这种形式,可以避免出现记录错误命令的情况。
另外还有一个原因就是:AOF 是在命令执行后才记录日志,所以不会阻塞当前的写操作。
在版本号大于等于2.4的 Redis 中,BGS*E 执行的过程中,不可以执行 BGREWRITEAOF。反过来说,在 BGREWRITEAOF 执行的过程中,也不可以执行 BGS*E。这可以防止两个 Redis 后台进程同时对磁盘进行大量的 I/O 操作。
如果 BGS*E 正在执行,并且用户显示地调用 BGREWRITEAOF 命令,那么服务器将向用户回复一个 OK 状态,并告知用户,BGREWRITEAOF 已经被预定执行:一旦 BGS*E 执行完毕 BGREWRITEAOF 就会正式开始。
当 Redis 启动时,如果 RDB 持久化和 AOF 持久化都被打开了,那么程序会优先使用 AOF 文件来恢复数据集,因为 AOF 文件所保存的数据通常是最完整的。
Redis4.0 后大部分的使用场景都不会单独使用 RDB 或者 AOF 来做持久化机制,而是兼顾二者的优势混合使用。其原因是 RDB 虽然快,但是会丢失比较多的数据,不能保证数据完整性;AOF 虽然能尽可能保证数据完整性,但是性能确实是一个诟病,比如重放恢复数据。
Redis从4.0版本开始引入 RDB-AOF 混合持久化模式,这种模式是基于 AOF 持久化模式构建而来的,混合持久化通过 aof-use-rdb-preamble yes 开启。
那么 Redis 服务器在执行 AOF 重写操作时,就会像执行 BGS*E 命令那样,根据数据库当前的状态生成出相应的 RDB 数据,并将这些数据写入新建的 AOF 文件中,至于那些在 AOF 重写开始之后执行的 Redis 命令,则会继续以协议文本的方式追加到新 AOF 文件的末尾,即已有的 RDB 数据的后面。
换句话说,在开启了 RDB-AOF 混合持久化功能之后,服务器生成的 AOF 文件将由两个部分组成,其中位于 AOF 文件开头的是 RDB 格式的数据,而跟在 RDB 数据后面的则是 AOF 格式的数据。
当一个支持 RDB-AOF 混合持久化模式的 Redis 服务器启动并载入 AOF 文件时,它会检查 AOF 文件的开头是否包含了 RDB 格式的内容。
其日志文件结构如下:

最后来总结这两者,到底用哪个更好呢?
推荐学习:Redis视频教程
以上就是Redis持久化策略浅析的详细内容,更多请关注其它相关文章!
# 重启
# seo优化做些什么
# 如何做营销推广书模板
# 定西自动化推广招聘网站
# 企业营销推广薄弱
# 专业seo外包报价
# 宝安网站推广信科免费
# 英文seo寄生虫程序
# 日照营销网站推广
# 东莞关键词seo机构
# 抖音必备几个网站推广
# Redis
# 情况下
# 自动保存
# 都是
# 的是
# 区中
# 过程中
# 是一个
# 客户端
# 重写
相关栏目:
【
Google疑问12 】
【
Facebook疑问10 】
【
优化推广96088 】
【
技术知识133117 】
【
IDC资讯59369 】
【
网络运营7196 】
【
IT资讯61894 】
相关推荐:
win11怎么更改账户类型 Win11标准用户和管理员权限切换【教程】
VS Code如何设置默认配置
可米酷漫画在线阅读入口_ 可米酷漫画官网直达链接
嘀嗒顺风车如何开具电子发票
动漫岛汉化官网网 动漫岛官方动漫汉化地址
《咸鱼之王》新版孙坚技能解析
如何自定义苹果手机铃声
iphone16系列配置参数介绍
AffinityDesigner图层蒙版怎么用_AffinityDesigner图层蒙版设计应用
《雅迪智行》用手机开锁方法
sublime如何配置PHP开发环境_在sublime中运行与调试PHP代码
空腹吃苹果好吗 苹果空腹摄入指南
在J*a中如何实现类的继承与方法重用_OOP继承方法重用技巧分享
b站怎么设置动态仅粉丝可见_b站动态粉丝可见设置方法
小米civi如何设置锁屏时间
2025考研成绩查询时间入口分享
b站如何管理订阅_b站订阅标签分类管理
多闪APP官方下载安装入口_多闪最新版本获取入口
Win10显卡驱动安装失败怎么办 Win10使用DDU彻底卸载驱动【解决】
PHP安全加载非公开目录图片与动态内容类型处理指南
Dash应用多值文本输入处理与类型转换教程
《搜书吧》阅读书籍方法
优酷官网登录入口电脑版 优酷官网网址入口
猫眼电影app如何设置电影上映提醒_猫眼电影上映提醒设置教程
HTML中多图片上传与预览:解决ID冲突的专业指南
京东快递物流信息不更新怎么办_物流停滞原因与处理方法
《图怪兽》退出登录方法
Golang中的rune与byte类型区别是什么_Golang字符与字节处理详解
从HTML表单获取逗号分隔值并转换为NumPy数组进行预测
《暗黑破坏神4》国服回归送狂欢礼包 价值6916元
search中maxlength属性用法解析
如何测试您的网站全球打开速度-网站海外测速工
菜鸟驿站的取件码忘了怎么办 手机快速查询指南
奥克斯空调不制热啥毛病_奥克斯空调不制热原因分析及解决技巧
荣耀Magic6 Pro拍照成像偏暗_荣耀Magic6 Pro夜景优化
Coolpad5890 ROM刷机包
教育查询官方网站入口 教育个人档案查询免费官网
高效调试PHP大型嵌套数组:JSON序列化与可视化工具实践
学习通网页版课程打不开_课程无法访问时的解决方法
c++如何链接Boost库_c++准标准库的集成与使用
4399正版网页版入口高清直达链接
纯CSS实现滚动时动态时间轴线条颜色填充效果
qq音乐官方网站入口_qq音乐在线听歌网页版链接
Composer reinstall命令重装损坏的包
iPhone14开启Apple TV遥控设置
c++类和对象到底是什么_c++面向对象编程基础
Dash应用中自定义HTML页面标题与网站图标(F*icon)的实用指南
键盘保修需要什么_键盘售后维修流程
《健康大兴》注册方法介绍
漫蛙manwa官网浏览入口_漫蛙漫画网页版访问链接
2022-11-09
运城市盐湖区信雨科技有限公司是一家深耕海外推广领域十年的专业服务商,作为谷歌推广与Facebook广告全球合作伙伴,聚焦外贸企业出海痛点,以数字化营销为核心,提供一站式海外营销解决方案。公司凭借十年行业沉淀与平台官方资源加持,打破传统外贸获客壁垒,助力企业高效开拓全球市场,成为中小企业出海的可靠合作伙伴。