系列七、Redis持久化

news2024/11/28 16:32:01

一、是什么

        将内存中的数据写入到硬盘的过程。

二、持久化方式

        RDB、AOF

2.1、RDB(Redis Database)

2.1.1、概述

       在指定的时间间隔,执行数据集的时间点快照。实现类似照片记录效果的方式,就是把某一时刻的数据和状态以文件的形式写到磁盘上,也就是快照。这样一来即使机器因故障宕机,快照文件也不会丢失,数据的可靠性就得到了保证。这个快照文件就被称为RDB文件(dump.rdb)。

2.1.2、能干嘛

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

        一锅端:Redis的数据都在内存中,保存备份时它执行的是全量快照,也就是说,把内存中的所有数据都记录到磁盘中,一锅端。

        RDB保存的是dump.rdb文件。

2.1.3、触发时机

自动触发:在redis.conf配置文件中的 SNAPSHOTTING 下配置save参数,来触发redis的RDB持久化条件,格式:save m n,表示m秒内数据集存在n次修改,自动触发bgsave

save 900 1 :每隔900s(15min),如果有超过1个key发生变化,就写一份新的RDB文件
save 300 10 :每隔300s(5min),如果有超过10个key发生变化,就写一份新的RDB文件 
save 60 10000 : 每隔60s(5min),如果有超过10000个key发生变化,就写一份新的RDB文件

2.1.4、案例演示(自动触发)

步骤:

(1)修改redis.conf  SNAPSHOTTING/save 配置 

(2)本次案例5秒2次修改,即触发自动保存

(3)修改dump文件的保存路径

注意事项:/myredis/dumpfiles文件夹需要提前在 / 目录建好,命令为:mkdir -p myredis/dumpfiles

(4)修改dump文件名称

(5)重启redis服务

(6)触发备份

①初始条件 /myredis/dumpfiles 目录没有任何rdb文件

②5s内执行了两次set操作,/myredis/dumpfiles 目录的文件情况

③5s内只执行一次set操作,观察/myredis/dumpfiles 目录的文件情况

(7)恢复

①备份 /myredis/dumpfiles 目录的 dump6379.rdb文件,指令:cp dump6379.rdb dump6379.rdb.bak

②清空当前库,flushdb,观察/myredis/dumpfiles 目录的文件情况

结论:执行情况库的操作时,也会生成dump.rdb文件

③删除/myredis/dumpfiles 目录的dump6379.rdb文件

④关闭redis服务,观察/myredis/dumpfiles 目录的文件情况

结论:关闭redis服务时,也会生成dump.rdb文件

⑤再次删除 /myredis/dumpfiles 目录的dump6369.rdb文件,并拷贝dump6369.rdb.bak文件进行恢复

⑥重启redis服务,观察数据是否恢复

⑦注意事项

不可以把备份文件dump.rdb文件和生成redis服务器放在同一台机器上,必须分开各自存储!以防生产机物理损坏后,备份文件也挂了,那就无法恢复了。

2.1.5、案例演示(手动触发)

实现方式:bgsave、save

bgsave(默认):redis会在后台异步进行快照操作,不阻塞快照,同时还可以响应客户端的请求,该触发方式会fork一个子进程,由子进程在后台完成持久化过程,这就允许主进程同时可以修改数据。

save:在主程序中执行会阻塞当前redis服务器,直到持久化工作完成,在执行save命令期间,redis不能处理其他命令,线上禁止使用

2.1.6、查看最近一次快照保存时间

lastsave:得到一串时间戳

date -d @时间戳:格式化时间戳,年月日 星期 十分秒

2.1.7、RDB的优势

  • 适合大规模的数据恢复
  • 按照业务定时备份
  • 对数据完整性和一致性要求不高
  • RDB文件在内存中的加载速度要比AOF快得多

2.1.8、RDB的劣势

  • 在一定间隔时间做一次备份,所以如果redis意外宕机的话,就会丢失从当前至最近一次快照期间的数据
  • 由于同步是全量同步,如果数据量太大的话,会导致大量IO,严重影响服务器的性能
  • RDB依赖于主进程的fork进程,即子进程,在更大的数据集中,这可能会导致服务请求的瞬间延迟
  • fork的时候,内存中的数据被克隆了一份,将会出现大致2倍的膨胀性,需要考虑

2.1.9、如何检查修复dump.rdb文件

redis-check-rdb /myredis/dumpfiles/dump6379.rdb

2.1.10、什么时候会触发RDB快照

  • 配置文件中默认的快照配置
  • 手动执行 save/bgsave 命令
  • 执行 flushdb/flushall 命令时也会产生dump.rdb文件,但是里面是空的,无意义
  • 执行shutdown且没有设置开启AOF持久化
  • 主从复制时,主节点自动触发

2.1.11、如何禁用快照

方式一:动态停止所有RDB保存规则

redis-cli config set save ""

方式二:快照禁用

2.1.12、RDB优化配置项详解

redis.conf SNAPSHOTTING 模块

(1)save <seconds> <changes>

(2)dbfilename

(3)dir

(4)stop-writes-on-bgsave-error

        默认yes(推荐),如果配置成no,表示你不在乎数据不一致或者有其他的手段发现和控制这种不一致,那么在快照写入失败时,也能确保redis继续接受新的写请求。

(5)rdbcompression

        默认yes(推荐),对于存储到磁盘中的快照,可以设置是否进行压缩存储,如果是的话,redis会采用LZF算法进行压缩,如果你不想消耗CPU的性能来进行压缩的话,可以设置为no,关闭此功能,

(6)rdbchecksum

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

(7)rdb-del-sync-files(redis7及以上版本支持)

        在没有持久性的情况下,删除复制中使用的RDB文件启用,默认情况下no,此选项是禁用的。

2.1.13、小总结

2.2、AOF(Append Only File)

2.2.1、概述

        以日志的形式来记录每个写操作,将redis执行过程中的所有写指令记录下来(读操作不记录),只许追加文件但不可以改写文件,redis启动之初会读取该文件重新构建数据,换言之,redis重启的话就根据日志文件的内容将写指令从前到后执行一次,以完成数据的恢复工作。默认情况下,redis是没有开启AOF的,开启AOF功能需要设置配置:appendonly yes

2.2.2、AOF持久化工作流程

        

第一步:Client作为命令的来源,会有多个源头以及源源不断的请求命令;

第二步:在这些命令到达Redis Server后并不是直接写入AOF文件,而是将这些命令先放入AOF缓存中进行保存。这里AOF缓冲区实际上是内存中的一片区域,存在的目的是当这些命令达到一定量后再写入磁盘,避免频繁的IO操作;

第三步:AOF缓冲会根据AOF缓冲区同步文件的三种回写策略将命令写入磁盘上的AOF文件;

第四步:随着写入AOF内容的增加,为避免文件膨胀,会根据规则进行命令的合并(又称AOF重写),从而起到AOF文件压缩的目的

2.2.3、三种回写策略

redis.conf/appendfsync

always:同步写回,每个写命令执行完后,立刻同步地将日志写回磁盘

everysec(默认):每秒写回,每个写命令执行完,只是先将日志写到AOF文件的内存缓冲区,每隔1s把缓冲区的内容写入磁盘

no:操作系统控制写回,每个写命令执行完,只是先把日志写到AOF文件的内存缓冲区,由操作系统决定何时将缓冲区内容写回磁盘

 

2.2.4、AOF案例演示

#1、删除/myredis目录的子文件夹dumpfiles

#2、拷贝/myredis目录的redis.conf文件
[root@centos701 myconf]# cp redis.conf redis_aof.conf

#3、修改redis_aof.conf文件配置,修改项如下
dir /myredis
appendonly no ==> appendonly yes

#4、重启redis服务

#5、执行操作,观察/myredis目录文件的变化情况

#6、flushdb,关闭redis服务,模拟机器宕机,删除/myredis目录的dump6379.rdb文件(防止干扰),然后再重新启动redis服务,观察数据是否恢复

#7、结果
数据没有恢复

#8、原因
执行flushdb指令时,该操作也会被记录在appenonly.aof文件中,所以当重新启动redis服务时,虽然将写命令重新执行了一遍,但是最后又执行了一次flushdb,所以重启之后数据还是空的

#9、解决
删除appendonly.aof文件中,flushdb相关指令,然后再重新启动redis服务,即可恢复数据

2.2.5、appendonly.aof和dump.rdb文件的加载顺序

问题:当前redis_aof.conf文件中既配置了rdb方式的持久化,又配置了aof方式的持久化,那么当redis服务出现宕机需要进行数据恢复时,优先加载哪个配置文件?

# 思路
编辑当前appendonly.aof文件,在末尾随便填写一些"乱七八糟"的数据,破坏该文件,然后重新启动redis服务,接着使用redis-cli客户端工具进行连接,观察能否连接上,如果能够连接的上,说明redis服务启动时,优先加载的是rdb文件,否则说明优先加载的是appendonly.aof文件
# 1、破坏appendonly.aof文件

# 2、重启redis服务

# 3、使用redis-cli客户端连接

# 4、结果
连接被拒绝

# 5、结论
redis服务宕机,进行数据恢复时,优先加载的文件是appendonly.aof文件

 2.2.6、aof文件的修复

场景:当开启aof的持久化方式后,默认情况下,会每隔1s种记录一次写操作,极端情况下,在这1s钟会出现数据没有写完,即只写了一部分数据的情况,这种情况下,如何修复appendonly.aof文件?可以使用redis给我们提供的redis-check-aof指令进行修复。

./redis-check-aof --fix  /myredis/appendonly.aof

2.2.7、Rewrite

是什么

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

重写原理

        AOF文件持续增长而过大时,会fork出一条新进程来将文件重写(也是先写临时文件,最后再rename),遍历新进程的内存中的数据,每条记录有一条set语句,重写aof文件的操作,并没有读取旧的aof文件,而是将整个内存中的数据库内容用命令的方式重写了一份新的aof文件,这点儿和快照有点类似。

触发机制

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

 

2.2.8、优势

每秒同步(appendfsync always):同步持久化,每次发生数据变更会被立即记录到磁盘,性能较差但是数据完整性比较好

每修改同步(appendfsync everysec):异步操作,每秒记录,如果1s内宕机,会丢失这1s中的数据

不同步(appendfsync no):从不同步

2.2.9、劣势

  • 对于相同数据集的数据而言,aof文件要远大于rdb文件,恢复速度慢于rdb
  • aof运行效率要慢于rdb,每秒同步策略效率较好,不同步效率和rdb相同

2.2.10、小总结

三、怎么选择

3.1、分析

RDB持久化方式:能够在指定的时间间隔内对你的数据进行快照存储

AOF持久化方式:记录每次对服务器的写操作,当服务器重启的时候会重新执行这些命令来恢复原始的数据,aof命令以redis协议追加每次的写操作至文件末尾,redis还能对AOF文件进行后台重写,使得AOF文件的大小不至于过大

3.2、只做缓存

        如果你只希望你的数据在服务器运行的时候存在,你也可以不使用任何持久化方式

3.3、同时开启两种持久化方式

        在这种情况下,当redis服务重启的时候会优先加载aof文件来恢复原始数据,因为在通常情况下aof文件保存的数据集要比rdb文件保存的数据集更完整。rdb的数据不实时,同时使用两者时服务器也只会找aof文件。那要不要只使用aof文件呢?作者建议不要,因为rdb文件更适合于备份数据库(aof文件不断变化,不好备份),建议留着作为一个万一的手段。

3.4、性能建议

        因为rdb文件只用作后备用途,建议只在slave上持久化rdb文件,而且只要15分钟备份一次就够了,只保留save 900 1这条规则即可。

        如果开启了aof的持久化,好处是在恶劣情况下也只会丢失不会超过2s的数据,启动脚本比较简单,只加载自己的aof文件就可以了。代价是带来了持续的IO,二是aof rewrite过程中产生的新数据写到新文件造成的阻塞几乎是不可避免的,只要硬盘许可,应该尽量减少aof rewrite的频率,aof重写的基础大小默认为64MB太小了,可以设置到5GB以上。默认超过原大小100%时重写。

        如果没有开启aof的持久化,仅靠Master-Slave Replication实现高可用性也可以。能省掉一大笔IO,也减少了rewrite时带来的系统波动。代价是如果Master、Slave同时宕机,将会丢失十几分钟的数据,启动脚本也要比较Master/Slave中的rdb文件,加载最新的那个。新浪微博采用的就是这种架构。

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

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

相关文章

vue3后台管理框架之收获

前端⼯程化概念 在学VUE和webpack打包的时候&#xff0c;了解到前端⼯程的基本概念&#xff0c;如下&#xff1a; 实际的前端开发&#xff0c;遵循四个现代化&#xff1a; 1.模块化&#xff08;js的模块化、css的模块化、其他资源的模块化&#xff09; 2.组件化&#xff08;复⽤…

05-React组件的组合使用

05-React组件的组合使用 1.TodoList案例 需求&#xff1a;TodoList组件化实现此功能 显示所有todo列表输入文本, 点击按钮显示到列表的首位, 并清除输入的文本 1).实现&#xff1a; 完成TodoList组件的静态页面以及拆解组件 动态初始化列表 //App.jsx export default class …

[初始java]——java为什么这么火,java如何实现跨平台、什么是JDK/JRE/JVM

java的名言&#xff1a; ”一次编译、到处运行“ 一、编译语言与解释语言 编译&#xff1a; 是将整份源代码转换成机器码再进行下面的操作&#xff0c;最终形成可执行文件 解释&#xff1a; 是将源代码逐行转换成机器码并直接执行的过程&#xff0c;不需要生成目标文件 jav…

10.14~10.15verilog操作流程与Block Design

后面的那个是延时精度 verilog文件结构 文件名称与写的模板没有关系&#xff0c;这个文件名为P1,但模板名为andgate 但是如果是仿真文件&#xff0c;就需要开头的模板名和仿真文件名相同 .v是源文件&#xff0c;设计文件 .v在设计与sim里都有&#xff0c;静态共享&#xff0…

卡顿分析与布局优化

卡顿分析与布局优化 大多数用户感知到的卡顿等性能问题的最主要根源都是因为渲染性能。Android系统每隔大概16.6ms发出VSYNC信 号&#xff0c;触发对UI进行渲染&#xff0c;如果每次渲染都成功&#xff0c;这样就能够达到流畅的画面所需要的60fps&#xff0c;为了能够实现60fp…

CISA 彻底改变了恶意软件信息共享:网络安全的突破

在现代网络安全中&#xff0c;战术技术和程序&#xff08;TTP&#xff09;的共享对于防范网络事件至关重要。 因此&#xff0c;了解攻击向量和攻击类型之间的关联如今是让其他公司从其他公司遭受的 IT 事件中受益&#xff08;吸取经验教训&#xff09;的重要一步。 美国主要网…

多模态大模型升级:LLaVA→LLaVA-1.5,MiniGPT4→MiniGPT5

Overview LLaVA-1.5总览摘要1.引言2.背景3.LLaVA的改进4.讨论附录 LLaVA-1.5 总览 题目: Improved Baselines with Visual Instruction Tuning 机构&#xff1a;威斯康星大学麦迪逊分校&#xff0c;微软 论文: https://arxiv.org/pdf/2310.03744.pdf 代码: https://llava-vl.…

无法解析符号 ‘SpringBootApplication’

刚打开一个项目出现"SpringBootApplication"无法解析&#xff1a; 通过以下步骤&#xff0c;修改maven路径即可&#xff1a; 文件---->设置&#xff08;File--->Settings&#xff09; 构建、执行、部署--->构建工具--->Maven--->Maven主路经&#xf…

07-ConfigurationClassPostProces的解析

文章目录 如何解析Component,Service,Configurationd,Bean,Import等注解1. 源码描述2. 类继承结构图3. 解析流程4. 具体的注解解析 如何解析Component,Service,Configurationd,Bean,Import等注解 1. 源码描述 BeanFactoryPostProcessor used for bootstrapping processing of…

论文笔记[156]PARAFAC. tutorial and applications

原文下载&#xff1a;https://www.sciencedirect.com/science/article/abs/pii/S0169743997000324 摘要 本文介绍了PARAFAC的多维分解方法及其在化学计量学中的应用。PARAFAC是PCA对高阶数组的推广&#xff0c;但该方法的一些特性与普通的二维情况截然不同。例如&#xff0c;…

O2O优惠券预测

O2O优惠券预测 赛题理解赛题类型解题思路 数据探索理论知识数据可视化分布 特征工程赛题特征工程思路 模型训练与验证 赛题理解 赛题类型 本赛题要求提交的结果是预测15 天内用券的概率&#xff0c;这是一个连续值&#xff0c;但是因为用券只有用与不用两种情况&#xff0c;而…

IDEA中为Maven配置使用vpn工具连接的网络

IDEA中为Maven配置使用vpn工具连接的网络 在电脑上使用VPN工具连接上特定网络后&#xff0c;发现idea中使用maven工具还是无法访问相关的网络&#xff0c;这时需要在idea中进行相关配置&#xff0c;开启ipv4代理 -Djava.net.preferIPv4Stacktrue maven配置 这时&#xff0c;…

JavaScript基础知识13——运算符:一元运算符,二元运算符

哈喽&#xff0c;大家好&#xff0c;我是雷工。 JavaScript的运算符可以根据所需表达式的个数&#xff0c;分为一元运算符、二元运算符、三元运算符。 一、一元运算符 1、一元运算符&#xff1a;只需要一个表达式就可以运算的运算符。 示例&#xff1a;正负号 一元运算符有两…

Golang 协程 与 Java 线程池的联系

Golang 协程 与 Java 线程池的联系 引言Java 线程池缺陷Golang 协程实现思路0.x 版本1.0 版本1.1 版本Goroutine 抢占式执行基于信号的抢占式调度 队列轮转系统调用工作量窃取GOMAXPROCS设置对性能的影响 小结 引言 如何理解Golang的协程&#xff0c;我觉得可以用一句话概括: …

【大数据】Hive SQL语言(学习笔记)

一、DDL数据定义语言 1、建库 1&#xff09;数据库结构 默认的数据库叫做default&#xff0c;存储于HDFS的&#xff1a;/user/hive/warehouse 用户自己创建的数据库存储位置&#xff1a;/user/hive/warehouse/database_name.db 2&#xff09;创建数据库 create (database|…

c#设计模式-行为型模式 之 备忘录模式

&#x1f680;简介 备忘录模式&#xff08;Memento Pattern&#xff09;是一种行为型设计模式&#xff0c;它保存一个对象的某个状态&#xff0c;以便在适当的时候恢复对象。所谓备忘录模式就是在不破坏封装的前提下&#xff0c;捕获一个对象的内部状态&#xff0c;并在该对象…

Android 14 正式发布,已经在 AOSP 中上线

本心、输入输出、结果 文章目录 Android 14 正式发布,已经在 AOSP 中上线前言总结主要更新内容机型支持优化性能的数据体现字体放大、多媒体支持加强Android 14 增加了对 10 位高动态范围 (HDR) 图像的支持提供了新的图形和尺寸管理用户体验 与隐私安全弘扬爱国精神Android 14…

Vue3 + Nodejs 实战 ,文件上传项目--实现拖拽上传

目录 1.拖拽上传的剖析 input的file默认拖动 让其他的盒子成为拖拽对象 2.处理文件的上传 处理数据 上传文件的函数 兼顾点击事件 渲染已处理过的文件 测试效果 3.总结 博客主页&#xff1a;専心_前端,javascript,mysql-CSDN博客 系列专栏&#xff1a;vue3nodejs 实战-…

【JVM】JVM的内存区域划分

JVM的内存区域划分 堆Java虚拟机栈程序计数器方法区运行时常量池 堆 程序中创建的所有对象都保存在堆中 Java虚拟机栈 Java虚拟机栈的生命周期和线程相同,描述的是Java方法执行的内存模型,每个方法在执行的时候都会同时创建一个栈帧用于存储局部变量表,操作栈,动态链接,方法…

C语言 —— 结构体

生活中有许多复杂对象是无法用基本数据类型来描述的, 于是为了描述复杂对象, C语言就会使用到结构体. 1. 结构体的声明与定义 1.1 结构的基础知识 结构是一些值的集合&#xff0c;这些值称为成员变量。结构的每个成员可以是不同类型的变量。 1.2 结构的声明与定义 struct tag {…