Redis学习[3] ——持久化

news2024/9/9 4:50:16

四. Redis 持久化

4.1 Redis 如何保证数据不丢失?

由于Redis的数据是保存在内存中,而内存中的数据会在Redis重启后丢失。因此,为了保证数据不丢失,Redis实现了数据持久化的机制。这个机制会将内存中的数据存储到磁盘,重启后可以从磁盘中恢复。

Redis共有三种数据持久化的方式:

  • AOF日志:每执行一条写操作命令,就把该命令以追加的方式写到一个文件里;
  • RDB快照:将某一时刻的内存数据,以二进制的方式写入磁盘;
  • 混合持久化方式:Redis 4.0新增,集成了AOF和RBD的优点。

4.2 AOF 日志是如何实现的?

4.2.1 AOF 日志写入

Redis在执行完一条写操作命令后,就会把该命令以追加写的方式写到一个文件中。当Redis重启后,会读取该文件记录的命令,逐个执行来恢复数据。

请添加图片描述

为什么是先执行命令,然后再把命令写入日志?

Reids 是先执行写操作命令后,才将该命令记录到 AOF 日志里的,这么做其实有两个好处:

  • 避免额外的检查开销:如果先写入再执行,那在写入的时候还无法确定是否能够执行。需要增加一步检查命令。
  • 不会阻塞当前写操作命令的执行:因为是完成写操作再去写入之日。

也会存在风险:

  • 数据可能会丢失:如果完成了写操作但还没来得及写入日志,服务器宕机了,会丢失这个数据;
  • 可能阻塞其他操作:AOF日志也是在主线程中执行的,会阻塞后续的操作等待写入完成;
4.2.2 AOF 日志写回策略

Redis写入AOF日志的过程可以由下图所示:

  1. Redis执行完写操作命令后,会将命令追加到一个缓冲区;
  2. 然后通过write()系统调用,将该缓冲区的命令写入到磁盘中的AOF文件中。实际上这一步只会让命令拷贝到了AOF文件的内核缓冲区,什么时候写入到硬盘由内核决定

Redis提供了3种写回硬盘的策略,控制什么时候将数据写入硬盘

  • Always:每次写操作执行完成后,直接将AOF日志数据写回硬盘;
  • Everysec:写操作执行完成后,数据会先存放在AOF文件的内核缓冲区,每隔一秒将缓冲区的内容写回到磁盘。
  • No:Redis不控制写回的执行,完全交给操作系统来控制

在这里插入图片描述

4.2.3 AOF 重写机制

随着执行的写操作越来越多,AOF日志文件会越来越大,在数据恢复时会越慢,影响性能。因此,Redis提供了重写机制,来避免AOF日志文件越写越大

AOF重写机制是根据K-V数据中的键值对,将每个键值对形成一个命令,记录到「新的 AOF 文件」中,完成后用这个「新的 AOF 文件」替换掉原有的AOF文件。

在这里插入图片描述

AOF重写机制的本质就是**只保留最新的在使用重写机制后,就会读取 name 最新的 value(键值对) ,然后用一条 「set name xiaolincoding」命令记录到新的 AOF 文件,之前的第一个命令就没有必要记录了,因为它属于「历史」命令,没有作用了。这样一来,一个键值对在重写日志中只用一条命令就行了**。

AOF重写是怎么完成的?

Redis是在每次需要AOF重写时,通过**新开辟一个子进程bgrewriteaof来完成AOF重写 **。这是由于:

  • 不会阻塞主进程,主进程可以继续处理命令请求;
  • 如果是多线程,由于共享数据,需要通过锁机制来保证数据安全,会影响性能。而子进程是拷贝数据的副本,创建子进程时,父子进程是共享内存数据的,不过这个共享的内存只能以只读的方式,而当父子进程任意一方修改了该共享内存,就会发生**「写时复制」,于是父子进程就有了独立的数据副本**,就不用加锁来保证数据安全

数据不一致问题?

因为在重写过程中,主进程仍然可以正常处理命令。如果发生了对已有key-value的修改,由于**「写时复制」子进程中关于这个key-value和主进程中的数据出现了不一致。为了解决这个问题,Redis设置了一个AOF重写缓冲区**。

在重写AOF期间,主进程对于所有的写操作命令除了将其加入到**「AOF 缓冲区」,还会加入到「AOF重写缓冲区」。当子进程完成重写时,会向主进程发送一个信号**(进程间的通信方式),主进程收到信号时会执行:

  • 将**「AOF重写缓冲区」中的所有内容追加到「新的 AOF 文件」**中;
  • 用**「新的 AOF 文件」**覆盖掉「旧的 AOF 文件」

截止到此,就完成了整个AOF重写的工作。

4.3 RDB 快照是如何实现的?

Redis使用AOF进行恢复时,如果AOF日志较多,需要逐个执行,势必会使Redis的恢复缓慢。为了解决这个问题,Redis增加了RDB快照。

RDB快照就是记录某一个瞬间的内存数据(是数据而不是命令),由于是直接记录的数据,因此在恢复时不需要执行操作命令,只需要将RDB文件读入内存即可,效率很高

4.3.1 RDB快照生成方法

Redis提供了两个命令来生成RDB快照:savebgsave,它们的区别在于生成快照是否在「主进程」里执行

  • save命令:在主进程中生成RDB快照,如果写入时间太长,会导致主线程阻塞,影响性能;
  • bgsave命令:会创建一个**子进程来生成RDB快照**,避免主线程的阻塞。

Redis 的快照是全量快照,也就是说每次执行快照,都是把内存中的**「所有数据」都记录到磁盘中。所以执行快照是一个比较重的操作,如果频率太频繁,可能会对 Redis 性能产生影响。如果频率太低,服务器故障时,丢失的数据会更多。**

4.3.2 RDB快照如何保证数据一致性?

如果是使用bgsave命令来执行生成快照,此时主进程仍然可以继续处理操作,但是由于快照是在一瞬间的数据,所以不需要去关注是否数据发生了变化。因此,RDB快照不存在数据一致性问题

如果主线程执行写操作,则被修改的数据会复制一份副本,然后 bgsave 子进程会**把原来副本数据写入 RDB 文件(不去管新的),在这个过程中,主线程仍然可以直接修改原来的数据。因此,借助写时复制技术(Copy-On-Write, COW)**,RDB不用关注数据一致性问题。

4.3 为什么会有混合持久化?

😊 RDB 优点是数据恢复速度快,但是快照的频率不好把握。频率太低,丢失的数据就会比较多,频率太高,就会影响性能。

😊 AOF 优点是丢失数据少,但是数据恢复不快。

为了集成了两者的优点, Redis 4.0 提出了混合使用 AOF 日志和RDB快照,也叫混合持久化,既保证了 Redis 重启速度,又降低数据丢失风险。

混合持久化是如何实现的?

  • 使用了混合持久化,AOF 文件的前半部分是 RDB 格式的全量数据,后半部分是 AOF 格式的增量数据

    当开启了混合持久化,在AOF重写日志时,重写子进程就不是把数据转换成命令写入了,而是**直接生成当时数据库的RDB快照并写入到AOF文件中。然后,主进程中记录在AOF重写缓冲区的命令继续以AOF日志的格式写入到AOF日志文件中**,替换旧的的 AOF 文件。

在这里插入图片描述

混合持久化优点:

  • 混合持久化结合了 RDB 和 AOF 持久化的优点,开头为 RDB 的格式,使得 Redis 可以更快的启动,同时结合 AOF 的优点,有减低了大量数据丢失的风险

混合持久化缺点:

  • AOF 文件中添加了 RDB 格式的内容,使得 AOF 文件的可读性变得很差
  • 兼容性差,如果开启混合持久化,那么此混合持久化 AOF 文件,就不能用在 Redis 4.0 之前版本了

资料参考

内容大多参考自:图解Redis介绍 | 小林coding (xiaolincoding.com)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1961356.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【JVM】内存区域、垃圾回收和内存分配策略

文章目录 运行时数据区域程序计数器Java虚拟机栈栈帧Java堆方法区运行时常量池 直接内存 揭秘对象对象的内存布局对象头实例数据对齐填充 对象的访问定位 OutOfMemoryError异常Java堆溢出虚拟机栈和本地方法栈溢出方法区和运行时常量池溢出本机直接内存溢出 对象已死&#xff1…

剪画小程序:什么?刷到陈楚生的视频转换成音频这么简单!

在这个信息爆炸的时代,我们常常在各种平台上刷到自己喜欢的视频,尤其是那些有陈楚生精彩表现的视频。 而有时候,我们可能只想单纯地聆听他的歌声,不想被视频画面所干扰。 你是否曾想过,把刷到的陈楚生的视频转换成音频…

爬虫实战:数据请求与解析(4种不同方式的数据解析)

根据目标网页的结构和内容的复杂性,我们可以选择多种不同的库或工具来提取所需的数据。本文将通过实战案例,介绍如何使用正则表达式、BeautifulSoup、pyquery、XPath 这四种方法从网页中解析数据。 一、准备工作 1.1 确定目标 我们测试的数据是崔庆才…

项目:基于gRPC进行项目的微服务架构改造

文章目录 写在前面基本使用封装客户端封装服务端Zookeeper 写在前面 最近学了一下gRPC进行远程调用的原理,所以把这个项目改造成了微服务分布式的架构,今天也是基本实现好了,代码已提交 这里补充一下文档吧,也算记录一下整个过程…

029-GeoGebra中级篇—一般对象之复数

GeoGebra 支持复数运算和可视化,允许用户在复平面上进行各种操作。用户可以定义复数、进行加减乘除等基本运算,并使用 GeoGebra 的图形工具在复平面上绘制复数的表示,探索复数的几何意义。这使得 GeoGebra 成为学习和研究复数及其应用的有力工…

合并K个有序链表

题目 给你一个链表数组,每个链表都已经按升序排列。 请你将所有链表合并到一个升序链表中,返回合并后的链表。 示例1: 输入: 输出: 示例2: 输入: 输出: 示例3: 输入&…

【Vue3】组件生命周期

【Vue3】组件生命周期 背景简介开发环境开发步骤及源码 背景 随着年龄的增长,很多曾经烂熟于心的技术原理已被岁月摩擦得愈发模糊起来,技术出身的人总是很难放下一些执念,遂将这些知识整理成文,以纪念曾经努力学习奋斗的日子。本…

Java从入门初级开发到精通百万级架构师:全套教程 | 学习路线(免费白嫖)

以下是一篇关于Java编程从入门到精通的文章,旨在帮助初学者和有一定基础的程序员系统地学习Java语言及其应用: Java语言编程从入门到精通:Java从入门到项目实战全套教程 Java作为一种广泛使用的编程语言,拥有强大的生态系统和丰富…

「 LaTeX 」如何修改公式底纹颜色

一、前言 小白在论文返修过程中,需要标注出部分公式的修正,因此用到这个代码指令。 二、技术实现 指令代码如下: \mathcolorbox{yellow}{ TEXT } 三、实例 \begin{figure*} \begin{equation} \centering \begin{aligned}\begin{bmatrix}{…

食家巷胡麻饼酥脆滋味,难以抗拒

在美食的浩瀚星空中,食家巷胡麻饼宛如一颗璀璨的明珠,散发着独特而迷人的魅力。食家巷胡麻饼,那金黄酥脆的外皮,宛如一层精心雕琢的铠甲,闪烁着诱人的光泽。上面点缀着密密麻麻的胡麻籽,犹如繁星点点&#…

终端pip安装包后,Pycharm却导入失败?新手别慌,3招搞定!

很多小伙伴在学习Python的过程中,都会遇到这种情况:明明在终端用pip安装好了需要的包,但在Pycharm中导入时却报错。难道是安装姿势不对? 例如在cmd中已经有了pandas,但是去pycharm中导入pandas显示没有 先别急着怀疑人生,这很可能是因为pip安装包的路径和Pycharm项目使用…

Docker容器下面home assistant忘记账号密码怎么重置?

环境: docker ha 问题描述: Docker容器下面home assistant忘记账号密码怎么重置? 解决方案: 你可以按照以下步骤来找回或重置密码: 方法一 (未解决) 停止并删除当前的Home Assistant容器(确保你已经保…

设计模式16-代理模式

设计模式16-代理模式 动机定义与结构模式定义结构 代码推导特点应用总结实例说明1. 远程代理2. 虚拟代理3. 保护代理4. 智能引用代理 动机 在面向对象系统中有一些对象由于某种原因比如对象创建的开销很大或者某些操作需要安全控制,或者需要进程外的访问等情况。直…

Mac电脑流氓软件怎么卸载不了 MacBook删除恶意软件 电脑流氓软件怎么彻底清除

对于Mac用户来说,尽管MacOS系统以其较高的安全性而闻名,但依然不可避免地会遭遇流氓软件或恶意软件的困扰。本文将详细介绍Mac电脑流氓软件怎么卸载,Mac电脑如何移除移除恶意软件,确保你的设备运行安全、流畅。 一、Mac电脑流氓软…

【论文共读】【翻译】【GAN】Generative Adversarial Nets

论文原文地址:https://arxiv.org/pdf/1406.2661 翻译:Generative Adversarial Nets 生成对抗网络 0. 摘要 提出了一种新的对抗过程估计生成模型的框架,其中我们同时训练两个模型:一个是捕获数据分布的生成模型G,另一…

【基础夯实】TCP/IP 协议是怎么控制数据收发

【基础夯实】TCP/IP 协议是怎么控制数据收发 网址输入到页面完整显示,对于此问题,粗略的解释可以分为以下几个步骤: 客户端通过 HTTP 协议对数据进行一次包装通过 DNS 服务器(本地无缓存)解析网址的 ip 地址通过 TCP…

layui 乱入前端

功能包含 本实例代码为部分傻瓜框架,插入引用layui。因为样式必须保证跟系统一致,所以大部分功能都是自定义的。代码仅供需要用layui框架,但原项目又不是layui搭建的提供解题思路。代码较为通用 自定义分页功能自定义筛选列功能行内编辑下拉、…

【React】详解如何获取 DOM 元素

文章目录 一、基础概念1. 什么是DOM?2. 为什么需要获取DOM? 二、使用 ref 获取DOM元素1. 基本概念2. 类组件中的 ref3. 函数组件中的 ref 三、 ref 的进阶用法1. 动态设置 ref2. ref 与函数组件的结合 四、处理特殊情况1. 多个 ref 的处理2. ref 与条件渲…

跟着丑萌气质狗学习WPF——Style样式

Style样式 1. 用法介绍2. 样式多样性3. 全局样式说明和资源字典的使用 1. 用法介绍 提前写好样式&#xff0c;让他作用于所有按钮 <Window x:Class"WPF_Study_Solution.window3"xmlns"http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmln…

typescript 解构时配置类型

以下三种写法&#xff0c;可以参考&#xff1a; const handleMenuClick ({item, key, keyPath}: {item: Object, key: string, keyPath:string}) > {} const handleMenuClick ({item, key, keyPath}: any) > {} interface SomeObj {item: Objectkey: stringkeyPath:st…