Redis底层原理

持久化

Redis虽然是个内存数据库,但是Redis支持RDB和AOF两种持久化机制,将数据写往磁盘,可以有效地避免因进程退出造成的数据丢失问题,当下次重启时利用之前持久化的文件即可实现数据恢复。

RDB

RDB持久化是把当前进程数据生成快照保存到硬盘的过程。所谓内存快照,就是指内存中的数据在某一个时刻的状态记录。这就类似于照片,当你给朋友拍照时,一张照片就能把朋友一瞬间的形象完全记下来。RDB 就是Redis DataBase 的缩写。

给哪些内存数据做快照?

Redis 的数据都在内存中,为了提供所有数据的可靠性保证,它执行的是全量快照,也就是说,把内存中的所有数据都记录到磁盘中。但是,RDB 文件就越大,往磁盘上写数据的时间开销就越大。

RDB文件的生成是否会阻塞主线程

Redis 提供了两个手动命令来生成 RDB 文件,分别是 save 和 bgsave。

save:在主线程中执行,会导致阻塞;对于内存比较大的实例会造成长时间阻塞,线上环境不建议使用。bgsave:创建一个子进程,专门用于写入 RDB 文件,避免了主线程的阻塞,这也是Redis RDB 文件生成的默认配置。

命令实战演示

除了执行命令手动触发之外,Redis内部还存在自动触发RDB 的持久化机制,例如以下场景:

1)使用save相关配置,如“save m n”。表示m秒内数据集存在n次修改时,自动触发bgsave。

2)如果从节点执行全量复制操作,主节点自动执行bgsave生成RDB文件并发送给从节点。

3)执行debug reload命令重新加载Redis 时,也会自动触发save操作。

4)默认情况下执行shutdown命令时,如果没有开启AOF持久化功能则自动执行bgsave。

关闭RDB持久化,在课程讲述的Redis版本(6.2.4)上,是将配置文件中的save配置改为 save “”

bgsave执的行流程

为了快照而暂停写操作,肯定是不能接受的。所以这个时候,Redis 就会借助操作系统提供的写时复制技术(Copy-On-Write, COW),在执行快照的同时,正常处理写操作。

bgsave 子进程是由主线程 fork 生成的,可以共享主线程的所有内存数据。bgsave 子进程运行后,开始读取主线程的内存数据,并把它们写入 RDB 文件。

如果主线程对这些数据也都是读操作(例如图中的键值对 A),那么,主线程和bgsave 子进程相互不影响。但是,如果主线程要修改一块数据(例如图中的键值对 B),那么,这块数据就会被复制一份,生成该数据的副本。然后,bgsave 子进程会把这个副本数据写入 RDB 文件,而在这个过程中,主线程仍然可以直接修改原来的数据。

这既保证了快照的完整性,也允许主线程同时对数据进行修改,避免了对正常业务的影响。

RDB文件

RDB文件保存在dir配置指定的目录下,文件名通过dbfilename配置指定。

可以通过执行config set dir {newDir}和config set dbfilename (newFileName}运行期动态执行,当下次运行时RDB文件会保存到新目录。

Redis默认采用LZF算法对生成的RDB文件做压缩处理,压缩后的文件远远小于内存大小,默认开启,可以通过参数config set rdbcompression { yes |no}动态修改。虽然压缩RDB会消耗CPU,但可大幅降低文件的体积,方便保存到硬盘或通过网维示络发送给从节点,因此线上建议开启。如果 Redis加载损坏的RDB文件时拒绝启动,并打印如下日志:

Short read or OOM loading DB. Unrecoverable error,aborting now.

这时可以使用Redis提供的redis-check-rdb工具(老版本是redis-check-dump)检测RDB文件并获取对应的错误报告。

RDB的优缺点
RDB的优点

RDB是一个紧凑压缩的二进制文件,代表Redis在某个时间点上的数据快照。非常适用于备份,全量复制等场景。

比如每隔几小时执行bgsave备份,并把 RDB文件拷贝到远程机器或者文件系统中(如hdfs),,用于灾难恢复。

Redis加载RDB恢复数据远远快于AOF的方式。

RDB的缺点

RDB方式数据没办法做到实时持久化/秒级持久化。因为bgsave每次运行都要执行fork操作创建子进程,属于重量级操作,频繁执行成本过高。

RDB文件使用特定二进制格式保存,Redis版本演进过程中有多个格式的RDB版本,存在老版本Redis服务无法兼容新版RDB格式的问题。

Redis中RDB导致的数据丢失问题

针对RDB不适合实时持久化的问题,Redis提供了AOF持久化方式来解决。

如下图所示,我们先在 T0 时刻做了一次快照(下一次快照是T4时刻),然后在T1时刻,数据块 5 和 8 被修改了。如果在T2时刻,机器宕机了,那么,只能按照 T0 时刻的快照进行恢复。此时,数据块 5 和 8 的修改值因为没有快照记录,就无法恢复了。

所以这里可以看出,如果想丢失较少的数据,那么T4-T0就要尽可能的小,但是如果频繁地执行全量快照,也会带来两方面的开销:

1、频繁将全量数据写入磁盘,会给磁盘带来很大压力,多个快照竞争有限的磁盘带宽,前一个快照还没有做完,后一个又开始做了,容易造成恶性循环。

2、另一方面,bgsave 子进程需要通过 fork 操作从主线程创建出来。虽然子进程在创建后不会再阻塞主线程,但是,fork 这个创建过程本身会阻塞主线程,而且主线程的内存越大,阻塞时间越长。如果频繁fork出bgsave 子进程,这就会频繁阻塞主线程了。

所以基于这种情况,我们就需要AOF的持久化机制。

AOF

AOF(append only file)持久化:以独立日志的方式记录每次写命令,重启时再重新执行AOF文件中的命令达到恢复数据的目的。AOF的主要作用是解决了数据持久化的实时性,目前已经是Redis持久化的主流方式。理解掌握好AOF持久化机制对我们兼顾数据安全性和性能非常有帮助。

使用AOF

开启AOF功能需要设置配置:appendonly yes,默认不开启。

AOF文件名通过appendfilename配置设置,默认文件名是appendonly.aof。保存路径同RDB持久化方式一致,通过dir配置指定。

AOF的工作流程

AOF的工作流程主要是4个部分:

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

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

相关文章

网络爬虫中的代理IP应用与高效管理策略探析

在网络爬虫技术日益普及的今天,面对目标网站对访问频率、IP地址等的严格限制,如何合理、有效地利用和管理代理IP资源成为了一项至关重要的任务。本文将深入探讨代理IP在爬虫项目中的应用,并提出一套科学高效的管理策略。 一、代理IP在网络爬…

分布式I/O应用于智慧停车场的方案介绍

客户案例背景 目前车位检测技术有磁电技术、超声波技术、红外线技术、图像识别车位技术。考虑到例如电磁干扰、信号干扰等的环境因素影响,通常会采用组合使用的方式进行,如采用不同的传感器、应用不同的协议等,以便提高车位检测的准确性和实时…

xilinix 7系列器件生成已加密文件和已经过身份验证的文件

注释 :如需了解更多信息,请参阅《使用加密确保 7 系列 FPGA 比特流的安全》(XAPP1239)。 要生成加密比特流,请在 Vivado IDE 中打开已实现的设计。在主工具栏中,依次选择“Flow” → “Bitstream Settings”(流程 >…

Go语言学习笔记(二)

Go语言的学习资源 以下是一些推荐的Go语言学习资源的链接: Go语言教程:https://golang.org/doc/Go by Example:Go by ExampleGolang Tutorials:https://golangtutorials.com/Go语言第一课(慕课网)&#x…

每周三提前预知:绝地求生27.2版本最早1月10日上线,交易所系统、召唤掩体等新功能上线

嗨,我是闲游盒 27.2新版本预计最早1月10日上线,届时会停机更新约9小时,大家注意合理安排游戏时间! 这次更新带来了很多荣都地图的新玩法,主打的交易所系统即将上线! PUBG官方已经发布了预告 交易所系统 而这次的交易所系统玩法…

常见排序算法及其稳定性分析

前言: 排序算法可以说是每一个程序员在学习数据结构和算法时必须要掌握的知识点,同样也是面试过程中可能会遇到的问题,在早些年甚至还会考冒泡排序。由此可见呢,掌握一些常见的排序算法是一个程序员的基本素养。虽然现在的语言标…

k8s的node亲和性和pod亲和性和反亲和性 污点 cordon drain

node亲和性和pod亲和性和反亲和性 污点 cordon drain 集群调度: schedule的调度算法 预算策略 过滤出合适的节点 优先策略 选择部署的节点 nodeName:硬匹配,不走调度策略,node01 nodeSelector:根据节点的标签选择,会走调度的算法 只…

PSoc62™开发板之PWM呼吸灯

实验目的 利用PWM动态调节输出功率达到控制LED呼吸变化的效果 实验准备 PSoc62™开发板(开发板已经板载LED) 板载资源 板载有多少pwm 创建工程例程,在libraries/HAL_Drivers/drv_pwm.h中查看BSP支持的pwm数量及对应的GPIO,可…

pgsql中epoch用法

问题描述 提示:这里描述项目中遇到的问题: 昨天又被叫回来加班,説是数据问题,又回来加班搞,到了以后发现数据没问题,那就是查询接口的事了,写查询接口的人用时间戳去查询,明明直接可以直接用日期查询,非得改成时间戳查询,结果还是有问题,接下来复盘一下…

centos安装gradle

1.将gradle.zip拷到centos 解压 2.配置环境变量 vim /etc/profile 在最后添加 export GRADLE_HOME/zx/gradle-8.5 export PATH$PATH:$GRADLE_HOME/bin:${PATH} 之后source /etc/profile gradle -version 安装成功

RK3566环境搭建

环境:vmware16,ubuntu 18.04 获取SDK前需要安装 sudo apt update sudo apt install -y repo git python 下载完成后先验证一下MD5码 md5sum rk356x_linux_release_v1.3.0b_20221213_split_dir/*firefly_split* 解压 rk3566ubuntu:/path/to$ mkdir ~…

【7-zip密码】7-Zip如何取消文件加密的密码

7z压缩包设置了密码,解压的时候就需要输入正确的密码才能顺利解压出文件,正常当我们解压文件或者删除密码的时候,虽然方法多,但是都需要输入正确的密码才能完成。忘记密码就无法进行操作。 那么,忘记了7z压缩包的密码…

Linux网络命令

文章目录 Linux网络网络配置命令1、ifconfig:查看网络接口信息(显示所有活动网卡)1.1 常用命令格式1.2 命令格式(图文详解)1.2.1 临时修改网卡名称1.2.2 永久修改网卡名称1.2.3 永久修改单个网卡 2、hostname&#xff…

JAVA面向对象基础-容器

一、泛型 我们可以在类的声明处增加泛型列表&#xff0c;如&#xff1a;<T,E,V>。 此处&#xff0c;字符可以是任何标识符&#xff0c;一般采用这3个字母。 【示例9-1】泛型类的声明 1 2 3 4 5 6 7 8 9 10 class MyCollection<E> {// E:表示泛型; Object[] o…

ESP32_ADC(Arduino)

ADC模数转换 ESP32集成了12位的逐次逼近式ADC&#xff0c;分别为ADC1模块ADC2模块&#xff0c;共支持18个模拟输入通道: ADC1模块&#xff1a;8个通道&#xff0c;32~39ADC2模块&#xff1a;10个通道&#xff0c;0&#xff0c;2&#xff0c;4&#xff0c;12 ~ 15&#xff0c;…

调试器加载错误,从任务栏打开可能会导致该问题 2024/1/8

&#x1f9e7;喜欢将常用软件固定在任务栏的用户肯定很苦恼这个问题 &#x1f9e7;问题复现 &#x1f9e7;这里先查找一下原因 &#x1f9e7;查看一下固定在任务栏的微信小程序开发工具的属性 如果不会打开任务栏图标属性界面的小伙伴请先翻到文章最后 &#x1f9e7;再使用同样…

CRM功能定制,哪些功能是需要格外注意的?

​到了2023年&#xff0c;在如今的商业环境中&#xff0c;千篇一律的方法很少能带来成功。这对于CRM管理系统尤其如此。虽然标准化的CRM解决方案为企业提供了一个简单的“入坑”门槛&#xff0c;但它们往往缺乏为企业带来真正竞争优势所需的灵活性&敏捷性。企业想要拥有适合…

【Python程序开发系列】一文总结API的基本概念、功能分类、认证方式、使用方法和开发流程

这是Python程序开发系列原创文章&#xff0c;我的第195篇原创文章。 一、什么是API&#xff1f; API是软件开发中非常重要的概念&#xff0c;它简化了不同组件之间的交互和集成&#xff0c;提供了对其他软件或服务功能的访问和调用方式。 API是应用程序编程接口&#xff08;Ap…

计算机配件杂谈-鼠标

目录 基础知识鼠标的发展鼠标的左右手鼠标的显示样式鼠标的移动和可见性移动可见性 现在的我们的生活工作都基本上离不开电脑了&#xff0c;不管是你平时玩玩游戏&#xff0c;上班工作等等&#xff1b; 今天将关于鼠标的一些小的技巧分享出来&#xff0c;共勉&#xff01; 基础…

Git删除远程仓库某次提交记录后的所有提交

1、鼠标右键->git bash here&#xff0c;然后cd切换到代码目录&#xff1b; 2、git log查看提交记录&#xff0c;获取commit id 3、git reset commit id&#xff08;commit id指要保留的最新的提交记录id&#xff09; 4、git push --force&#xff0c;强制push 如果出现…