当前位置: 首页 > news >正文

Redis八股

缓存

缓存穿透

当查询一个不存在的数据,mysql查询不到数据,无法写入缓存,导致每次都请求数据库

解决方法

  • 缓存空数据,当查询结果未空,将结果进行缓存。 简单但是会消耗内存,而且会出现不一致情况。
  • 布隆过滤器,检索一个元素是否在集合中,缓存预热时,也要预热过滤器。 内存占用少,不会产生多余key,但是实现复杂且存在误判情况。

缓存击穿

给key设置了过期时间,当该key过期时,出现大量针对该key的请求,可能会瞬间将数据库压垮。
在这里插入图片描述

解决方法

  • 添加互斥锁
    强一致性,但是性能差
  • 逻辑过期
    热点key不设置过期时间,设置一逻辑过期时间,对于逻辑过期的key,启用新线程更改数据,原线程仍然返回过期数据。
    在这里插入图片描述

缓存雪崩

同一时间大量key过期,或redis服务宕机,导致大量请求同时达到数据库。

解决方法

  • 给不同key的TTL添加随机值
  • Redis集群 (哨兵模式、集群模式)
  • 缓存业务添加降级限流机制
  • 业务多级缓存

双写一致性

设置前提,介绍背景业务

实现方法

高一致性
  1. 延迟双删
    在这里插入图片描述

修改数据库的同时也要更新缓存的数据,缓存于数据库保持一致。

读:命中直接返回,未命中则查询DB,将结果写入缓存,设定超时时间

写:延迟双删(依旧存在脏数据风险)

Quetion

-先删缓存还是先删数据库
无论先删除哪个都存在不一致性问题

  • 为何要删除两次
    防止在修改数据库期间,其他线程将旧的结果写入缓存
  • 为何延时删除
    保证redis集群的主从一致性。
  1. 分布式锁
    保证缓存和数据库的绝对一致性,但是性能低。适用于读多写少的情况。
    在这里插入图片描述
最终一致性

异步通知,保证数据的最终一致性
在这里插入图片描述

二进制日志记录(binlog)中记录所有 DDl(数据定义语言)和 DML(数据操纵语言),但不包括查询语言。
在这里插入图片描述

Redis持久化

RDB

RDB (Redis Database Backup file, Redis数据备份文件),也叫redis数据快照,将数据记录到磁盘中,每次redis实列故障重启后,都会从磁盘中读取快照,回复数据。

备份方式
  • 主动备份
save #主线程备份
bgsave #启用子线程备份
  • 内部触发
    通过redis.conf文件中修改配置项实现
save 900 1 #900s内有一次修改
save 300 10
save 60 10000
RDB执行原理

bgsave开始时,通过fork主进程得到子进程。子进程共享fork内部数据,完成fork后读取内存写入RDB文件。

fork操作采用copy-on-write技术

  • 当主进执行读操作时,访问共享内存
  • 当主进程执行写操作时,会拷贝一份数据,再进行写操作
    在这里插入图片描述

AOF

AOF(Append Only File, 追加文件),Redis处理的每一个写命令都会被记录再AOF文件中。
默认关闭,可以再redis.conf中配置选项。

AOF记录频率
模式频率优点缺点
always同步可靠性高,几乎不会出现数据丢失现象对性能影响大
everysec每秒适中最多丢失1s数据
no由操作系统控制最好可靠性差,可能丢失大量数据

由于是记录文件,会比RDB大很多。AOF会记录对于同一个key的多次写操作,但是只有最后一个才有意义。可以使用bgrewriteaof命令来使AOF执行重写操作,确保最少的命令达到相同效果。

也可以通过再conf文件中进行配置,使系统内部自动触发。

# AOF文件比上次增长百分之多少重写
auto-aof-rewrite-percentage 100
# AOF文件大小超过多少重写
auto-aof-rewrite-min-size 64mb

RDB与AOF之间比较

RDBAOF
持久化定期对内存进行快照记录每次执行的写操作
完整性不完整,两次备份之间会存在丢失相对完整,取决于刷新策略
文件大小
宕机恢复
数据恢复优先级
系统资源占用高,大量CPU和内存消耗低,主要为磁盘IO资源,但是重写时会占用大量内存资源
使用场景可容忍数分钟的数据丢失,追求更快的启动速度对数据安全性要求更高

数据过期策略

Redis中设置有效期后的key,在数据过期后,需要将数据从内存中删除。Redis中有惰性删除定期删除两种不同的数据过期策略,一般二者配合使用。

惰性删除

需要使用某key时,检查其是否过期,如过期则删除该key,反之直接返回该key对应值。

  • 优点:CPU友好,只有需要使用该key时才会进行过期检查
  • 缺点: 对内存不友好,过期的key如果不被访问,会一直存在于内存中,永远不会释放。

定期删除

每隔一段时间,从一定数量的数据库中随机选择一部分key进行检查,并删除过期key。
定期删除有两种模式:

    SLOW: 定时任务,执行频率默认10hz,每次不超过25msFAST:执行频率不固定,但每次间隔不会低于2ms
优缺点
  • 优点: 限制删除操作的时长和频率,减少对CPU影响。定期删除能有效释放过期key占用的内存。
  • 缺点: 难以确定删除操作花费的时长和频率。

Redis数据淘汰策略

Redis内存不够时,接收到新的key,按照一定规则删除其中的数据。

8种淘汰策略

  • noeviction: 不淘汰任何key,但内存写满时不写入(默认模式)。
  • volatile-ttl: 对设置ttl的key,ttl越小越先淘汰
  • allkeys-random: 对所有key随机淘汰
  • volatile-random: 对所有设置ttl的key随机淘汰
  • allkeys-lru: 对所有key,基于LRU算法淘汰
  • volatile-lru: 对所有设置ttl的key,按照LRU算法淘汰
  • allkeys-lfu: 对所有key,基于LFU算法淘汰
  • volatile-lfu: 对设置了ttl的key,基于LFU算法淘汰。

LRU:最近最少使用;LFU:最少频率使用

使用场所

  • allkeys-lru: 有明显冷热数据区分
  • allkeys-random: 无明显冷热数据区分
  • volatile-lru: 有置顶需求,置顶数据不设过期时间
  • allkeys-lfu / volatile-lfu: 有短时高频访问数据

分布式锁

用于集群下定时、抢单功能

setnx

redis中自带命令,用于创建不存在的key, 如果key存在,返回null

获取锁

set lock value nx ex 10

释放锁

del key

在这里插入图片描述

如何控制有效时长

  • 根据业务执行时间预估
  • 给锁续期

如何实现

使用redisson实现分布式锁,底层为setnx和lua脚本。通过watchdog和给锁续期的方式来控制时长。

Redisson

实现分布式锁的流程

在这里插入图片描述

可重入性质

判断是否是同一个线程,同一个线程可重入。利用hash结构记录线程id和重入次数。
在这里插入图片描述

主从一致性

不能解决主从一致性问题,当主节点宕机后,watchdog(看门狗)会选择一个从节点提升为主节点。

红锁

在不止一个实例上加锁,一般加锁实例数量大于等于(n/2+1)。可以一定程度上实现主从一致性,但是实现复杂,并发性差,运维复杂。

如果必须要实现主从一致性,使用基于CP思想的缓存工具,如zookeeper。

Redis集群

主从复制

单节点Redis并发能力有上限,要进一步提高Redis并发能力,需要搭建组从集群,实现读写分离。一般是一主多从,主节点负责写数据,从节点负责读数据。
在这里插入图片描述

原理

全量同步

在这里插入图片描述

  • replid 数据集的标记,id一致说明数据集一致
  • offset:偏移量。slave的offset小于master的,说明slave的数据落后于master,需要同步
增量同步

slave重启或者后期数据变化
在这里插入图片描述

哨兵机制(sentinel)

Redis提供哨兵机制来实现主从集群的自动故障恢复。
在这里插入图片描述

特点

  • 监控: sentinel不断检查master和slave是否按预期工作
  • 自动恢复: 如果master节点故障,哨兵集群会将一个新的slave节点提升为master节点,并在之后一直以该master节点为主
  • 通知redis客户端: 哨兵充当客户端的服务通知来源,当集群发生故障转移时,会将最新信息推送道redis客户端。

作用机制

  • 服务状态监控
    哨兵基于心跳机制监测服务状态,每个1s向集群中的每个实例发送ping命令

  • 判断redis节点下线
    主观下线: 某个sentinel节点发现某一个实例未在规定时间内进行响应,认为该实例主观下线。
    客观下线: 超过指定数量(quorum,一般超过哨兵节点数量的一半)的哨兵节点都认为某一实例主观下线,则认为该实例已经客观下线。

  • 哨兵挑选新主节点规则

1. 判断主节点与从节点断开时间长短,排除超过阈值的从节点
2. 判断从节点的slave-priority值,值越小优先级越高
3. 如果slave-priority值相同,则判断从节点的offset值,offset值越大的优先级越高。
4. 在优先级相同的节点中随机选择一个节点。

如何解决redis集群脑裂

集群脑裂是由于主节点、从节点和sentinel集群不在同一分区,使得sentinel无法通过心跳感知到主节点,通过选举提升了一个新的主节点。同时,由于旧主节点没有真实下线,客户端还在向旧主节点写入数据,新主节点无法同步数据。当网络回复后,sentinel讲旧的主节点降为从节点,再从新主节点中同步数据。这会导致客户端向旧主节点中写入的数据丢失。

解决方法: 可以通过修改redis配置文件,设置最少从节点数量和主从数据同步要求(数据复制和同步的延迟阈值),达不到要求就拒绝请求,由此避免大量数据的损失。

分片集群

用于解决海量数据存储和高并发写的问题

特点

  1. 集群中有多个master,每个master节点保存不同数据
  2. 每个master节点有多个slave节点
  3. master节点之间通过ping值监测彼此的健康状态
  4. 客户端可以向任意节点发送请求,最终都会被转发到正确节点

redis分片集群如何读写

  1. 引入哈希槽的概念,redis集群有16384个哈希槽
  2. 将16384个插槽分配到不同实例
  3. 读写数据时,利用key的有效部分计算hash,对16384取余,余数作为插槽,最后寻找插槽所属实例。

其它

Redis是单线程的,但是为什么速度快?

  • 最主要原因是Redis是纯内存操作,执行速度快
  • 采用单线程,避免了不必要的上下文切换可竞争条件
  • 使用多路I/O复用模型,非阻塞IO。例如,bgsave和bgwriteaof都是在后台执行,不影响主线程的正常使用,不会产生阻塞

I/O多路复用模型

I/O多路复用模型是指利用单个线程来同时监听多个socket,并在某个Socket可读、可写时得到通知,从而避免了无效的等待,充分利用CPU资源。目前的I/O多路复用模型都是通过epoll实现,它会在通知用户Socket就绪的同时,将已就绪的Socket写入用户空间,不需要挨个遍历Socket来判断是否就绪,提升了性能。

其中Redis的网络模型就是使用I/O多路复用结合时间的处理器来应对多个Socket的请求,比如,提供了连接应答处理器、命令回复处理器,命令请求处理器;在Reids6.0之后,为了更好提升性能,在命令回复处理器中使用了多线程来处理回复事件,在命令请求处理器中,将命令的转换使用了多线程,增加命令转换速度,在命令执行的时候,也依然是单线程。

相关文章:

Redis八股

缓存 缓存穿透 当查询一个不存在的数据,mysql查询不到数据,无法写入缓存,导致每次都请求数据库 解决方法 缓存空数据,当查询结果未空,将结果进行缓存。 简单但是会消耗内存,而且会出现不一致情况。布隆…...

vue3--通用 popover 气泡卡片组件实现

背景 在日常开发中,我们一般都是利用一些诸如:element-ui、element-plus、ant-design等组件库去做我们的页面或者系统 这些对于一些后台管理系统来说是最好的选择,因为后台管理系统其实都是大同小异的,包括功能、布局结构等 但是对于前台项目,比如官网、门户网站这些 …...

Bluetooth Channel Sounding中关于CS Step及Phase Based Ranging相应Mode介绍

目录 BLE CS中Step定义 BLE CS中交互的数据包/波形格式 BLE CS中Step的不同Mode BLE CS中Step的执行过程 Mode0介绍 Mode0 步骤的作用 Mode0步骤的执行过程 Mode0步骤的执行时间 Mode0步骤的时间精度要求 Mode2介绍 Mode2步骤的作用和执行过程 Mode2步骤的执行时间 B…...

简易STL实现 | Queue 的实现

封装: std::queue 在底层容器的基础上 提供了封装。默认情况下,std::queue 使用 std::deque 作为其底层容器,但也可以配置为使用 std::list 或 其他符合要求的容器 时间复杂度: 入队和出队操作 通常是 常数时间复杂度&#xff08…...

【hot100-java】LRU 缓存

链表篇 灵神题解 class LRUCache {private static class Node{int key,value;Node prev,next;Node (int k,int v){keyk;valuev;}}private final int capacity;//哨兵节点private final Node dummynew Node(0,0);private final Map<Integer,Node> keyToNode new HashMap&l…...

Centos7安装ZLMediaKit

一 获取代码 git clone https://gitee.com/xia-chu/ZLMediaKit cd ZLMediaKit git submodule update --init git submodule update --init 命令用于初始化和更新 Git 仓库中的子模块&#xff08;submodules&#xff09;。这个命令在 Git 仓库中包含对其他 Git 仓库作为依赖时…...

面试问我LLM中的RAG,咱就是说秒过!!!

前言 本篇文章涉及了 RAG 流程中的数据拆分、向量化、查询重写、查询路由等等&#xff0c;在做 RAG 的小伙伴一定知道这些技巧的重要性。推荐仔细阅读&#xff0c;建议收藏&#xff0c;多读几遍&#xff0c;好好实践。 本文是对检索增强生成&#xff08;Retrieval Augmented …...

python程序操作pdf

python代码进行多个图片合并为pdf&#xff1a; #python代码进行多个图片合并为pdf&#xff1a; from PIL import Image from fpdf import FPDF import osdef images_to_pdf(image_paths, output_pdf, quality85):"""将多个图片合并为一个PDF文件&#xff0c;并…...

【Python报错】ImportError: DLL load failed while importing _network: 找不到指定的模块。

【Python报错】ImportError: DLL load failed while importing _network: 找不到指定的模块。 问题描述报错原因解决方案参考 问题描述 此段Python代码&#xff08;在Conda环境下运行&#xff09;昨天还能运行&#xff0c;但在我手痒更新conda&#xff08;我有罪&#xff09;之…...

外包干了5天,技术明显退步

我是一名本科生&#xff0c;自2019年起&#xff0c;我便在南京某软件公司担任功能测试的工作。这份工作虽然稳定&#xff0c;但日复一日的重复性工作让我逐渐陷入了舒适区&#xff0c;失去了前进的动力。两年的时光匆匆流逝&#xff0c;我却在原地踏步&#xff0c;技术没有丝毫…...

正则表达式 | Python、Julia 和 Shell 语法详解

正则表达式在网页爬虫、脚本编写等众多任务中都有重要的应用。为了系统梳理其语法&#xff0c;以及 Python、Julia 和 Shell 中与正则表达式相关的工具&#xff0c;本篇将进行详细介绍。 相关学习资源&#xff1a;编程胶囊。 基础语法 通用语法 在大多数支持正则表达式的语…...

JavaScript全面指南(一)

​ &#x1f308;个人主页&#xff1a;前端青山 &#x1f525;系列专栏&#xff1a;JavaScript篇 &#x1f516;人终将被年少不可得之物困其一生 依旧青山,本期给大家带来JavaScript篇专栏内容:JavaScript全面指南(一) 1、介绍一下JS的内置类型有哪些&#xff1f; 基本数据类型…...

docker-compose与docker

“docker-compose” 是一个用于定义和运行多容器 Docker 应用程序的工具。它使用一个名为 docker-compose.yml 的配置文件来描述应用程序的服务、网络和卷&#xff0c;然后通过简单的命令就可以管理整个应用。 以下是一些常用的 docker-compose 命令及其用法&#xff1a; 启动…...

DDPM浅析

在机器学习和人工智能领域&#xff0c;生成模型一直是一个备受关注的研究方向。近年来&#xff0c;一种新型的生成模型——扩散概率模型&#xff08;Diffusion Probabilistic Models&#xff0c;简称DDPM&#xff09;引起了广泛的关注。本文将探讨DDPM的原理、优势以及应用。 …...

力扣刷题-算法基础

hello各位小伙伴们,为了进行算法的学习,小编特意新开一个专题来讲解一些算法题 1.移除元素. - 力扣(LeetCode) 本题大概意思是给定一个数组和一个数val删除与val相同的元素,不要改变剩余元素的顺序,最后返回剩余元素的个数。 我们在这里使用双指针,这里的双指针并不是…...

理解 Python 中的 Hooks 和装饰器

Python 中的 hooks 和装饰器&#xff0c;虽然它们看起来都有些魔法加成&#xff0c;但实际上各有妙用。下面看看他们到底是做什么的吧。 什么是 Hooks&#xff1f; Hooks 是指在某些操作或事件发生时&#xff0c;可以将自定义的代码插入和执行的一种机制。它们常用于扩展和修…...

Android 原生程序使用gdb, addr2line, readelf调试

Platform: RK3368 OS: Android 6.0 Kernel: 3.10.0 文章目录 一 gdb1. 原生程序添加调试符号2. 主机上adb push 编译好的原生程序到设备3. 设备上使用gdbserver运行原生程序4. 主机上设置adb端口转发5. 主机上运行gdb调试 二 addr2line三 readelf 一 gdb GDB&#xff08;GNU…...

PHP 函数 func_num_args() 的作用

func_num_args() 是 PHP 中的一个内置函数&#xff0c;用于获取传递给当前用户定义函数的参数个数。这个函数特别有用于处理可变数量的参数&#xff08;也称为可变参数列表&#xff09;。 语法 int func_num_args ( void ) 返回值 func_num_args() 返回一个整数&#xff0c…...

深入解析单片机原理及其物联网应用:附C#示例代码

深入解析单片机原理及其物联网应用&#xff1a;附C#示例代码 随着物联网技术的快速发展&#xff0c;单片机作为嵌入式系统的核心&#xff0c;已经广泛应用于各类智能设备中。本文将从单片机的原理出发&#xff0c;结合C#编程的物联网示例&#xff0c;带你深入了解如何利用单片…...

HTTP 和 WebSocket

目录 HTTP是什么HTTP局限性&#xff08;HTTP1.1&#xff09;请求和响应HTTP的主要特点&#xff1a;HTTP版本&#xff1a; HTTP与TCP关系数据封装传输过程1. **协议层次模型**&#xff1a;2. **封装过程**&#xff1a;1. **应用层&#xff08;HTTP&#xff09;**&#xff1a;2. …...

[特殊字符] 智能合约中的数据是如何在区块链中保持一致的?

&#x1f9e0; 智能合约中的数据是如何在区块链中保持一致的&#xff1f; 为什么所有区块链节点都能得出相同结果&#xff1f;合约调用这么复杂&#xff0c;状态真能保持一致吗&#xff1f;本篇带你从底层视角理解“状态一致性”的真相。 一、智能合约的数据存储在哪里&#xf…...

生成xcframework

打包 XCFramework 的方法 XCFramework 是苹果推出的一种多平台二进制分发格式&#xff0c;可以包含多个架构和平台的代码。打包 XCFramework 通常用于分发库或框架。 使用 Xcode 命令行工具打包 通过 xcodebuild 命令可以打包 XCFramework。确保项目已经配置好需要支持的平台…...

逻辑回归:给不确定性划界的分类大师

想象你是一名医生。面对患者的检查报告&#xff08;肿瘤大小、血液指标&#xff09;&#xff0c;你需要做出一个**决定性判断**&#xff1a;恶性还是良性&#xff1f;这种“非黑即白”的抉择&#xff0c;正是**逻辑回归&#xff08;Logistic Regression&#xff09;** 的战场&a…...

dedecms 织梦自定义表单留言增加ajax验证码功能

增加ajax功能模块&#xff0c;用户不点击提交按钮&#xff0c;只要输入框失去焦点&#xff0c;就会提前提示验证码是否正确。 一&#xff0c;模板上增加验证码 <input name"vdcode"id"vdcode" placeholder"请输入验证码" type"text&quo…...

工程地质软件市场:发展现状、趋势与策略建议

一、引言 在工程建设领域&#xff0c;准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具&#xff0c;正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...

c#开发AI模型对话

AI模型 前面已经介绍了一般AI模型本地部署&#xff0c;直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型&#xff0c;但是目前国内可能使用不多&#xff0c;至少实践例子很少看见。开发训练模型就不介绍了&am…...

Spring AI与Spring Modulith核心技术解析

Spring AI核心架构解析 Spring AI&#xff08;https://spring.io/projects/spring-ai&#xff09;作为Spring生态中的AI集成框架&#xff0c;其核心设计理念是通过模块化架构降低AI应用的开发复杂度。与Python生态中的LangChain/LlamaIndex等工具类似&#xff0c;但特别为多语…...

SAP学习笔记 - 开发26 - 前端Fiori开发 OData V2 和 V4 的差异 (Deepseek整理)

上一章用到了V2 的概念&#xff0c;其实 Fiori当中还有 V4&#xff0c;咱们这一章来总结一下 V2 和 V4。 SAP学习笔记 - 开发25 - 前端Fiori开发 Remote OData Service(使用远端Odata服务)&#xff0c;代理中间件&#xff08;ui5-middleware-simpleproxy&#xff09;-CSDN博客…...

Unsafe Fileupload篇补充-木马的详细教程与木马分享(中国蚁剑方式)

在之前的皮卡丘靶场第九期Unsafe Fileupload篇中我们学习了木马的原理并且学了一个简单的木马文件 本期内容是为了更好的为大家解释木马&#xff08;服务器方面的&#xff09;的原理&#xff0c;连接&#xff0c;以及各种木马及连接工具的分享 文件木马&#xff1a;https://w…...

初探Service服务发现机制

1.Service简介 Service是将运行在一组Pod上的应用程序发布为网络服务的抽象方法。 主要功能&#xff1a;服务发现和负载均衡。 Service类型的包括ClusterIP类型、NodePort类型、LoadBalancer类型、ExternalName类型 2.Endpoints简介 Endpoints是一种Kubernetes资源&#xf…...