当前位置: 首页 > 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. …...

第19节 Node.js Express 框架

Express 是一个为Node.js设计的web开发框架&#xff0c;它基于nodejs平台。 Express 简介 Express是一个简洁而灵活的node.js Web应用框架, 提供了一系列强大特性帮助你创建各种Web应用&#xff0c;和丰富的HTTP工具。 使用Express可以快速地搭建一个完整功能的网站。 Expre…...

2025年能源电力系统与流体力学国际会议 (EPSFD 2025)

2025年能源电力系统与流体力学国际会议&#xff08;EPSFD 2025&#xff09;将于本年度在美丽的杭州盛大召开。作为全球能源、电力系统以及流体力学领域的顶级盛会&#xff0c;EPSFD 2025旨在为来自世界各地的科学家、工程师和研究人员提供一个展示最新研究成果、分享实践经验及…...

1688商品列表API与其他数据源的对接思路

将1688商品列表API与其他数据源对接时&#xff0c;需结合业务场景设计数据流转链路&#xff0c;重点关注数据格式兼容性、接口调用频率控制及数据一致性维护。以下是具体对接思路及关键技术点&#xff1a; 一、核心对接场景与目标 商品数据同步 场景&#xff1a;将1688商品信息…...

使用van-uploader 的UI组件,结合vue2如何实现图片上传组件的封装

以下是基于 vant-ui&#xff08;适配 Vue2 版本 &#xff09;实现截图中照片上传预览、删除功能&#xff0c;并封装成可复用组件的完整代码&#xff0c;包含样式和逻辑实现&#xff0c;可直接在 Vue2 项目中使用&#xff1a; 1. 封装的图片上传组件 ImageUploader.vue <te…...

Psychopy音频的使用

Psychopy音频的使用 本文主要解决以下问题&#xff1a; 指定音频引擎与设备&#xff1b;播放音频文件 本文所使用的环境&#xff1a; Python3.10 numpy2.2.6 psychopy2025.1.1 psychtoolbox3.0.19.14 一、音频配置 Psychopy文档链接为Sound - for audio playback — Psy…...

Linux-07 ubuntu 的 chrome 启动不了

文章目录 问题原因解决步骤一、卸载旧版chrome二、重新安装chorme三、启动不了&#xff0c;报错如下四、启动不了&#xff0c;解决如下 总结 问题原因 在应用中可以看到chrome&#xff0c;但是打不开(说明&#xff1a;原来的ubuntu系统出问题了&#xff0c;这个是备用的硬盘&a…...

Maven 概述、安装、配置、仓库、私服详解

目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...

华为OD机考-机房布局

import java.util.*;public class DemoTest5 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseSystem.out.println(solve(in.nextLine()));}}priv…...

C#学习第29天:表达式树(Expression Trees)

目录 什么是表达式树&#xff1f; 核心概念 1.表达式树的构建 2. 表达式树与Lambda表达式 3.解析和访问表达式树 4.动态条件查询 表达式树的优势 1.动态构建查询 2.LINQ 提供程序支持&#xff1a; 3.性能优化 4.元数据处理 5.代码转换和重写 适用场景 代码复杂性…...

在鸿蒙HarmonyOS 5中使用DevEco Studio实现企业微信功能

1. 开发环境准备 ​​安装DevEco Studio 3.1​​&#xff1a; 从华为开发者官网下载最新版DevEco Studio安装HarmonyOS 5.0 SDK ​​项目配置​​&#xff1a; // module.json5 {"module": {"requestPermissions": [{"name": "ohos.permis…...