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

黑马redis

Redis的多IO线程只是用来处理网络请求的,对于读写操作命令Redis仍然使用单线程来处理

Redisson分布式锁实现15问

文章目录

  • 主线程和IO线程是如何协作的
  • Unix网络编程中的五种IO模型
  • Linux世界一切皆文件
  • 生产上限制keys *、flushdb、flushall等危险命令
    • keys * 遍历查询100W数据花费时长
    • 配置禁用这些命令
  • BigKey案例
  • 缓存更新策略
    • Redis内存不足的缓存淘汰策略
    • 先删缓存再操作数据库
      • 理想情况
      • 多线程竟态条件下
      • 多线程竟态条件下
    • 先操作数据库再删除缓存【胜出】
      • 理想情况
    • 总结
  • 项目实践【黑马点评】
    • 目标
    • 缓存一致性
    • 缓存穿透
      • 缓存穿透解决方案调研
      • 实战解决商铺信息缓存穿透
      • 总结
    • 缓存雪崩
    • 缓存击穿
      • 缓存击穿解决方案调研
      • 实战解决缓存击穿
        • 互斥锁(setnx)
  • 优惠券秒杀-单机锁
    • 全局唯一ID
      • 自增ID存在的问题
      • 分布式ID的实现
    • 实战优惠券秒杀
      • 总结
  • 优惠券秒杀-分布式锁
    • 自定义的分布式锁
    • 将单机 synchronized 替换为自定义分布式锁
    • 分布式锁误删问题🍖
      • 问题原因分析
      • 代码实现
    • 判断锁标识和释放锁非原子性🥩
    • 存在的问题
      • 锁不可重入
      • 不可重试
      • 超时释放
      • 主从一致性
  • Redis集群方案
    • 主从复制—全量同步、增量同步
      • 全量同步
      • 增量同步
      • 面试题
    • 哨兵模式
      • 服务状态监控
      • redis集群(哨兵模式)脑裂
      • 面试题
    • 分片集群
      • 分片集群结构
      • 分片集群结构——数据读写
      • 存在的问题
      • 面试题1
      • 面试题2
  • Big Key
    • 大key的影响
    • 大key的查找
    • 删除大key注意事项
    • 大key的处理
    • 分拆方案
      • 一、单个简单的key存储的value很大
      • 二、value中存储过多的元素
      • 方案一:使用时间戳作为附加属性
      • 方案二:通过在 `key` 拼接上基于时间分拆
      • 代码解释
        • 方案一代码解释
        • 方案二代码解释

主线程和IO线程是如何协作的

  • 阶段一:服务端和客户端建立Socket连接,并分配处理线程
    首先,主线程负责接收建立连接请求,当有客户端请求和实例建立Socket连接时,主线程会创建和客户端的连接,并把 Socket放入全局等待队列中。紧接着,主线程通过轮询方法把Socket连接分配给IO线程

  • 阶段二:IO线程读取并解析请求
    主线程一旦把Socket分配给IO线程,就会进入阻塞状态,等待IO线程完成客户端请求读取和解析。因为有多个IO线程在并行处理,所以,这个过程很快就可以完成。

  • 阶段三:主线程执行请求操作
    等到IO线程解析完请求,主线程还是会以单线程的方式执行这些命令操作
    在这里插入图片描述

  • 阶段四:IO线程回写Socket和主线程清空全局队列
    当主线程执行完请求操作后,会把需要返回的结果写入缓冲区,然后,主线程会阻塞等待IO线程,把这些结果回写到Socket中,并返回给客户端。和IO线程读取和解析请求一样,IO线程回写Socket时,也是有多个线程在并发执行,所以回写Socket的速度也很快。等到IO线程回写Socket完毕,主线程会清空全局队列,等待客户端的后续请求。
    在这里插入图片描述

Unix网络编程中的五种IO模型

Blocking IO - 阻塞IO

NoneBlocking IO - 非阻塞IO

IO multiplexing - IO多路复用 ★★★

signal driven IO - 信号驱动IO(偏C)

asynchronous IO - 异步IO(偏C)

Linux世界一切皆文件

文件描述符、简称FD,句柄

FileDescriptor:
文件描述符(File descriptor)是计算机科学中的一个术语,是一个用于表述指向文件的引用的抽象化概念。文件描述符在形式上是一个非负整数。实际上,它是一个索引值,指向内核为每一个进程所维护的该进程打开文件的记录表。当程序打开一个现有文件或者创建一个新文件时,内核向进程返回一个文件描述符。在程序设计中,文件描述符这一概念往往只适用于UNIX、Linux这样的操作系统

I/O 的读和写本身是堵塞的,比如当 socket 中有数据时,Redis 会通过调用先将数据从内核态空间拷贝到用户态空间,再交给 Redis 调用,而这个拷贝的过程就是阻塞的,当数据量越大时拷贝所需要的时间就越多,而这些操作都是基于单线程完成的

生产上限制keys *、flushdb、flushall等危险命令

keys * 遍历查询100W数据花费时长

在这里插入图片描述

配置禁用这些命令

redis.conf 在 SECURITY 这一项中

rename-command keys ""
rename-command flushdb ""
rename-command FLUSHALL ""

BigKey案例

多大算Big
参考《阿里云Redis开发规范》

在这里插入图片描述

缓存更新策略

在这里插入图片描述

Redis内存不足的缓存淘汰策略

  • noeviction:当内存使用超过配置的时候会返回错误,不会驱逐任何键
  • allkeys-lru:加入键的时候,如果过限,首先通过LRU算法驱逐最久没有使用的键
  • volatile-lru:加入键的时候如果过限,首先从设置了过期时间的键集合中驱逐最久没有使用的键
  • allkeys-random:加入键的时候如果过限,从所有key随机删除
  • volatile-random:加入键的时候如果过限,从过期键的集合中随机驱逐
  • volatile-ttl:从配置了过期时间的键中驱逐马上就要过期的键
  • volatile-lfu:从所有配置了过期时间的键中驱逐使用频率最少的键 allkeys-lfu:从所有键中驱逐使用频率最少的键
    在这里插入图片描述
    在这里插入图片描述

先删缓存再操作数据库

理想情况

在这里插入图片描述

多线程竟态条件下

在这里插入图片描述

多线程竟态条件下

好巧不巧,缓存失效了,此时线程2要采用先更新数据库再删除缓存的策略,但由于更新数据库没有线程1查询数据库快,所以查到的还是未更新前的旧值10;
线程2更新完毕之后删除了redis缓存,线程1获取时间片后又将10写回了缓存,导致数据库缓存不一致的情况
在这里插入图片描述

先操作数据库再删除缓存【胜出】

理想情况

在这里插入图片描述
在这里插入图片描述

总结

给缓存设置过期时间,定期清理缓存并回写,是保证最终一致性的解决方案

我们可以对存入缓存的数据设置过期时间,所有的写操作以数据库为准,对缓存操作只是尽最大努力即可。
也就是说如果数据库写成功,缓存更新失败,那么只要到达过期时间,则后面的读请求自然会从数据库中读取新值然后回填缓存,达到一致性,切记,要以数据落库DB为准

项目实践【黑马点评】

目标

在这里插入图片描述

缓存一致性

com.sddp.service.impl.ShopServiceImpl#update
事务保证原子性,如果在微服务系统中,这两步不在一个方法当中,甚至不在一个服务当中,那么就需要mq消息通知删除缓存的服务,可以借助TCC来保证分布式事务的原子性
在这里插入图片描述

缓存穿透

缓存穿透是指客户端请求的数据在缓存中和数据库中都不存在,这样缓存永远不会生效,这些请求都会打到数据库。如果被恶意用户利用,对服务器会造成负载,严重会导致服务不可用
常见的解决方案有两种:

com.sddp.service.impl.ShopServiceImpl#queryById

在这里插入代码片

缓存穿透解决方案调研

在这里插入图片描述

实战解决商铺信息缓存穿透

如果提交的商铺id本身就是瞎写的,查询数据库之后必然没有数据,那此时,redis则将此id存在redis并赋值为null,下次在查询此id时直接走redis返回null即可
在这里插入图片描述

总结

在这里插入图片描述

缓存雪崩

TTL随机数分散降低机率
Redis宕机:利用集群提高服务的可用性
快速失败、拒绝服务

在这里插入图片描述

缓存击穿

缓存击穿问题也叫热点Key问题,就是一个被高并发访问并且缓存重建业务较复杂下图第 2 步比较耗时,导致多线程访问的时候短时间为写入缓存,期间的流量都打到DB上了)的key突然失效了,无数的请求访问会在瞬间给数据库带来巨大的冲击。
在这里插入图片描述

缓存击穿解决方案调研

互斥锁:CP(强一致)
逻辑过期:AP(高可用)
在这里插入图片描述
在这里插入图片描述

实战解决缓存击穿

多个线程同时去查询数据库的这条数据,那么我们可以在第一个查询数据的请求上使用一个 互斥锁 来锁住它。

其他的线程走到这一步拿不到锁就等着,等第一个线程查询到了数据,然后做缓存。

后面的线程进来发现已经有缓存了,就直接走缓存


/*** @auther zzyy* @create 2021-05-01 14:58*/
@Service
@Slf4j
public class UserService {public static final String CACHE_KEY_USER = "user:";@Resourceprivate UserMapper userMapper;@Resourceprivate RedisTemplate redisTemplate;/*** 业务逻辑没有写错,对于小厂中厂(QPS《=1000)可以使用,但是大厂不行* @param id* @return*/public User findUserById(Integer id){User user = null;String key = CACHE_KEY_USER+id;//1 先从redis里面查询,如果有直接返回结果,如果没有再去查询mysqluser = (User) redisTemplate.opsForValue().get(key);if(user == null){//2 redis里面无,继续查询mysqluser = userMapper.selectByPrimaryKey(id);if(user == null){//3.1 redis+mysql 都无数据//你具体细化,防止多次穿透,我们业务规定,记录下导致穿透的这个key回写redisreturn user;}else{//3.2 mysql有,需要将数据写回redis,保证下一次的缓存命中率redisTemplate.opsForValue().set(key,user);}}return user;}/*** 加强补充,避免突然key失效了,打爆mysql,做一下预防,尽量不出现击穿的情况。* @param id* @return*/public User findUserById2(Integer id){User user = null;String key = CACHE_KEY_USER+id;//1 先从redis里面查询,如果有直接返回结果,如果没有再去查询mysql,// 第1次查询redis,加锁前user = (User) redisTemplate.opsForValue().get(key);if(user == null) {//2 大厂用,对于高QPS的优化,进来就先加锁,保证一个请求操作,让外面的redis等待一下,避免击穿mysqlsynchronized (UserService.class){//第2次查询redis,加锁后user = (User) redisTemplate.opsForValue().get(key);//3 二次查redis还是null,可以去查mysql了(mysql默认有数据)if (user == null) {//4 查询mysql拿数据(mysql默认有数据)user = userMapper.selectByPrimaryKey(id);if (user == null) {return null;}else{//5 mysql里面有数据的,需要回写redis,完成数据一致性的同步工作redisTemplate.opsForValue().setIfAbsent(key,user,7L,TimeUnit.DAYS);}}}}return user;}
}

在这里插入图片描述

互斥锁(setnx)
public boolean tryLock(String key){Boolean flag = stringRedisTemplate.opsForValue().setIfAbsent(key, "1", 10, TimeUnit.SECONDS);

相关文章:

黑马redis

Redis的多IO线程只是用来处理网络请求的,对于读写操作命令Redis仍然使用单线程来处理 Redisson分布式锁实现15问 文章目录 主线程和IO线程是如何协作的Unix网络编程中的五种IO模型Linux世界一切皆文件生产上限制keys *、flushdb、flushall等危险命令keys * 遍历查询100W数据花…...

HCIA-Access V2.5_1_2 PON技术的特点、优势与典型应用

PON接入技术优势 它的接入方式有两种,点到点光接入和点到多点光接入。 点到点 PON口的资源被一个用户独占,该用户可以享受到更好的带宽体验,同时故障好排查,出现问题,重点检测这一条链路以及终端用户,同…...

css部分

前面我们学习了HTML,但是HTML仅仅只是做数据的显示,页面的样式比较简陋,用户体验度不高,所以需要通过CSS来完成对页面的修饰,CSS就是页面的装饰者,给页面化妆,让它更好看。 1 层叠样式表&#…...

【TCP 网络通信(发送端 + 接收端)实例 —— Python】

TCP 网络通信(发送端 接收端)实例 —— Python 1. 引言2. 创建 TCP 服务器(接收端)2.1 代码示例:TCP 服务器2.2 代码解释: 3. 创建 TCP 客户端(发送端)3.1 代码示例:TCP…...

LSTM+改进的itransformer时间序列预测模型代码

代码在最后 本次设计了一个LSTM基于差分多头注意力机制的改进的iTransformer时间序列预测模型结合了LSTM(长短期记忆网络)和改进版的iTransformer(差分多头注意力机制),具备以下优势: 时序特征建模能力&am…...

Apache-HertzBeat 开源监控默认口令登录

0x01 产品描述: HertzBeat(赫兹跳动) 是一个开源实时监控系统,无需Agent,性能集群,兼容Prometheus,自定义监控和状态页构建能力。HertzBeat 的强大自定义,多类型支持,高性能,易扩展,希望能帮助用户快速构建自有监控系统。0x02 漏洞描述: HertzBeat(赫兹跳动) 开源实时…...

Delete Number

翻译: 主要思路解释 整体思路概述: 本题的目标是给定整数(要删除的数字个数)和整数(以字符串形式表示的数字),通过合理删除个数字,使得最终得到的新数字最小。程序采用了一种贪心算…...

Linux常用快捷键

目录 ​编辑 剪切/复制/粘贴/删除等快捷键 终端及标签页快捷键 历史命令快捷键 移动光标快捷键 控制命令 剪切/复制/粘贴/删除等快捷键 快捷键 功能 ShiftCtrlC 复制 ShiftCtrlV 粘贴 CtrlInsert 复制命令行内容 ShiftInsert 粘贴命令行内容 Ctrlk 剪切&#…...

针对xpath局限的解决方案

上篇《网页数据提取利器 -- Xpath》我们对xpath的介绍中提到了xpath的几点局限性: 结构依赖性强性能动态网页支持不足 本篇是针对这些局限提出的解决方案和补充方法,以提升 XPath 的实用性和适应性。 1. 动态网页的处理 局限: XPath 无法…...

深入解析 HTML Input 元素:构建交互性表单的核心

🤍 前端开发工程师、技术日更博主、已过CET6 🍨 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 🕠 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 🍚 蓝桥云课签约作者、上架课程《Vue.js 和 E…...

ffmpeg转码与加水印

文章目录 转码 与加水印引入jar包代码ffmpeg安装错误解决方法 转码 与加水印 引入jar包 <dependency><groupId>net.bramp.ffmpeg</groupId><artifactId>ffmpeg</artifactId><version>0.6.2</version></dependency>代码 impo…...

Leetcode 104. 二叉树的最大深度(Java-深度遍历)

题目描述&#xff1a; 给定一个二叉树 root &#xff0c;返回其最大深度。 二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。 示例&#xff1a; 输入&#xff1a;root [3,9,20,null,null,15,7] 输出&#xff1a;3示例 2&#xff1a; 输入&#xff1a;…...

阳明心学-传习录学习总结

资料 王阳明介绍&#xff1a;明代杰出的思想家、军事家、教育家&#xff1b;自刑部主事历任贵州龙场驿丞、庐陵知县、右佥都御史、南赣巡抚、两广总督等职&#xff0c;接连平定南赣、两广盗乱及宸濠之乱&#xff0c;因功获封“新建伯”&#xff0c;成为明代因军功封爵的三位文…...

macOS sequoia 15.1中应用程序“程序坞”没有权限打开

在macOS sequoia 15.1版本中新安装的应用程序在访达中打开报错显示应用程序“程序坞”没有权限打开“(null)”。 解决办法 在启动台中找到终端&#xff0c;点击打开&#xff0c;切换到应用目录下&#xff0c;输入 cd /Applications/ 找到需要打开的应用程序目录&#xff0…...

使用 MinIO 和 KKFileView 实现在线文件预览功能

在项目开发中&#xff0c;文件的在线预览是常见的需求&#xff0c;尤其是对 PDF、Word、Excel 等格式的文件进行无客户端依赖的直接查看。本文将介绍如何通过 MinIO 和 KKFileView 搭建在线文件预览服务&#xff0c;并通过 docker-compose 一键部署。 一、环境准备 1. Docker …...

Conda-Pack打包:高效管理Python环境

在Python开发中&#xff0c;环境管理是一个不可忽视的重要环节。Conda是一个流行的包管理器和环境管理器&#xff0c;它允许用户创建隔离的环境&#xff0c;以避免不同项目之间的依赖冲突。Conda-pack是一个工具&#xff0c;可以帮助我们将一个conda环境打包成一个可移植文件&a…...

云服务器上搭建 WordPress 全流程指南

WordPress 是全球最受欢迎的开源内容管理系统&#xff08;CMS&#xff09;&#xff0c;通过 WordPress&#xff0c;你可以轻松搭建博客、企业网站或电子商务平台。而通过云服务器搭建 WordPress&#xff0c;可以使网站获得更好的性能和灵活性。本文将为你提供详细的步骤&#x…...

图像超分辨率技术新进展:混合注意力聚合变换器HAAT

目录 1. 引言&#xff1a; 2. 混合注意力聚合变换器&#xff08;HAAT&#xff09;&#xff1a; 2.1 Swin-Dense-Residual-Connected Block&#xff08;SDRCB&#xff09;&#xff1a; 2.2 Hybrid Grid Attention Block&#xff08;HGAB&#xff09;&#xff1a; 3. 实验结…...

文件IO——01

1. 认识文件 1&#xff09;文件概念 “文件”是一个广义的概念&#xff0c;可以代表很多东西 操作系统里&#xff0c;会把很多的硬件设备和软件资源抽象成“文件”&#xff0c;统一管理 但是大部分情况下的文件&#xff0c;都是指硬盘的文件&#xff08;文件相当于是对“硬…...

【opencv入门教程】5. Mat 类用法

文章选自&#xff1a; 一、BackGround Mat对象是一种图像数据结构&#xff0c;它是一个容器&#xff0c;存储任何通道任何数的图片数据以及对应的矩阵&#xff0c;使用完成后&#xff0c;内存自动释放。二、Code void Samples::MatFunc() {1. 图像处理// 方法1&#xff1a;…...

云原生核心技术 (7/12): K8s 核心概念白话解读(上):Pod 和 Deployment 究竟是什么?

大家好&#xff0c;欢迎来到《云原生核心技术》系列的第七篇&#xff01; 在上一篇&#xff0c;我们成功地使用 Minikube 或 kind 在自己的电脑上搭建起了一个迷你但功能完备的 Kubernetes 集群。现在&#xff0c;我们就像一个拥有了一块崭新数字土地的农场主&#xff0c;是时…...

ES6从入门到精通:前言

ES6简介 ES6&#xff08;ECMAScript 2015&#xff09;是JavaScript语言的重大更新&#xff0c;引入了许多新特性&#xff0c;包括语法糖、新数据类型、模块化支持等&#xff0c;显著提升了开发效率和代码可维护性。 核心知识点概览 变量声明 let 和 const 取代 var&#xf…...

ssc377d修改flash分区大小

1、flash的分区默认分配16M、 / # df -h Filesystem Size Used Available Use% Mounted on /dev/root 1.9M 1.9M 0 100% / /dev/mtdblock4 3.0M...

vue3 字体颜色设置的多种方式

在Vue 3中设置字体颜色可以通过多种方式实现&#xff0c;这取决于你是想在组件内部直接设置&#xff0c;还是在CSS/SCSS/LESS等样式文件中定义。以下是几种常见的方法&#xff1a; 1. 内联样式 你可以直接在模板中使用style绑定来设置字体颜色。 <template><div :s…...

DiscuzX3.5发帖json api

参考文章&#xff1a;PHP实现独立Discuz站外发帖(直连操作数据库)_discuz 发帖api-CSDN博客 简单改造了一下&#xff0c;适配我自己的需求 有一个站点存在多个采集站&#xff0c;我想通过主站拿标题&#xff0c;采集站拿内容 使用到的sql如下 CREATE TABLE pre_forum_post_…...

QT开发技术【ffmpeg + QAudioOutput】音乐播放器

一、 介绍 使用ffmpeg 4.2.2 在数字化浪潮席卷全球的当下&#xff0c;音视频内容犹如璀璨繁星&#xff0c;点亮了人们的生活与工作。从短视频平台上令人捧腹的搞笑视频&#xff0c;到在线课堂中知识渊博的专家授课&#xff0c;再到影视平台上扣人心弦的高清大片&#xff0c;音…...

小智AI+MCP

什么是小智AI和MCP 如果还不清楚的先看往期文章 手搓小智AI聊天机器人 MCP 深度解析&#xff1a;AI 的USB接口 如何使用小智MCP 1.刷支持mcp的小智固件 2.下载官方MCP的示例代码 Github&#xff1a;https://github.com/78/mcp-calculator 安这个步骤执行 其中MCP_ENDPOI…...

C++11 constexpr和字面类型:从入门到精通

文章目录 引言一、constexpr的基本概念与使用1.1 constexpr的定义与作用1.2 constexpr变量1.3 constexpr函数1.4 constexpr在类构造函数中的应用1.5 constexpr的优势 二、字面类型的基本概念与使用2.1 字面类型的定义与作用2.2 字面类型的应用场景2.2.1 常量定义2.2.2 模板参数…...

【多线程初阶】单例模式 指令重排序问题

文章目录 1.单例模式1)饿汉模式2)懒汉模式①.单线程版本②.多线程版本 2.分析单例模式里的线程安全问题1)饿汉模式2)懒汉模式懒汉模式是如何出现线程安全问题的 3.解决问题进一步优化加锁导致的执行效率优化预防内存可见性问题 4.解决指令重排序问题 1.单例模式 单例模式确保某…...

生信服务器 | 做生信为什么推荐使用Linux服务器?

原文链接&#xff1a;生信服务器 | 做生信为什么推荐使用Linux服务器&#xff1f; 一、 做生信为什么推荐使用服务器&#xff1f; 大家好&#xff0c;我是小杜。在做生信分析的同学&#xff0c;或是将接触学习生信分析的同学&#xff0c;<font style"color:rgb(53, 1…...