缓存夺命连环问

1. 为什么要用缓存?

用缓存,主要有两个用途:高性能高并发

高性能

  • 假设这么个场景,你有个操作,一个请求过来,吭哧吭哧你各种乱七八糟操作 MySQL,半天查出来一个结果,耗时 600ms。但是这个结果可能接下来几个小时都不会变了,或者变了也可以不用立即反馈给用户。那么此时咋办?
  • 缓存啊,折腾 600ms 查出来的结果,扔缓存里,一个 Key 对应一个 Value,下次再有人查,别走 MySQL 折腾 600ms 了,直接从缓存里,通过一个 Key 查出来一个 Value,2ms 搞定。性能提升 300 倍。
  • 就是说对于一些需要复杂操作耗时查出来的结果,且确定后面不怎么变化,但是有很多读请求,那么直接将查询出来的结果放在缓存中,后面直接读缓存就好

高并发

  • MySQL这么重的数据库,压根儿设计不是让你玩儿高并发的,虽然也可以玩儿,但是天然支持不好。MySQL 单机支撑到2000QPS(每秒查询率)也开始容易报警了
  • 所以要是你有个系统,高峰期一秒钟过来的请求有 1 万,那一个 mysql 单机绝对会死掉。你这个时候就只能上缓存,把很多数据放缓存,别放 mysql。缓存功能简单,说白了就是Key-Value式操作,单机支撑的并发量轻松一秒几万十几万,支撑高并发 so easy单机承载并发量是 MySQL单机的几十倍

缓存是走内存的,内存天然就支撑高并发。

2. 用了缓存之后会有什么不良后果?

常见的缓存问题有以下几个:

  • 缓存与数据库双写不一致
  • 缓存血崩、缓存穿透、缓存击穿
  • 缓存并发竞争 

缓存血崩、缓存穿透、缓存击穿知识铺垫: 

缓存雪崩(Cache Avalanche)

  • 对于系统 A,假设每天高峰期每秒 5000 个请求,本来缓存在高峰期可以扛住每秒 4000 个请求,但是缓存机器意外发生了全盘宕机。缓存挂了,此时 1 秒 5000 个请求全部落数据库,数据库必然扛不住,它会报一下警,然后就挂了。此时,如果没有采用什么特别的方案来处理这个故障,DBA 很着急,重启数据库,但是数据库立马又被新的流量给打死了。

这就是缓存雪崩。

缓存穿透(Cache Penetration)

  • 对于系统 A,假设一秒 5000 个请求,结果其中 4000 个请求是黑客发出的恶意攻击。
  • 黑客发出的那 4000 个攻击,缓存中查不到,每次你去数据库里查,也查不到。
  • 举个栗子。数据库 id 是从 1 开始的,结果黑客发过来的请求 id 全部都是负数。这样的话,缓存中不会有,请求每次都“视缓存于无物”,直接查询数据库。这种恶意攻击场景的缓存穿透就会直接把数据库给打死

 

缓存击穿(Hotspot Invalid)

  • 缓存击穿,就是说某个 key 非常热点,访问非常频繁,处于集中式高并发访问的情况,当这个 key 在失效的瞬间,大量的请求就击穿了缓存,直接请求数据库,就像是在一道屏障上凿开了一个洞。
  • 解决方式也很简单,可以将热点数据设置为永远不过期或者基于 redis or zookeeper 实现互斥锁,等待第一个请求构建完缓存之后,再释放锁,进而其它请求才能通过该 key 访问数据。

3. 为啥Redis单线程模型也能效率这么高?

  • 纯内存操作
  • 核心是基于非阻塞的IO多路复用机制
  • C语言实现,一般来说,C语言实现的程序"距离"操作系统更新,执行速度相对会更快
  • 单线程反而避免了多线程的频繁上下文切换的问题,预防了多线程可能产生的竞争问题。

4. redis 的并发竞争问题是什么?如何解决这个问题?了解 redis 事务的 CAS 方案吗? 

  • 某个时刻,多个系统实例都去更新某个 key
  • 可以基于 zookeeper 实现分布式锁。每个系统通过 zookeeper 获取分布式锁,确保同一时间,只能有一个系统实例在操作某个 key,别人都不允许读和写。
  • 你要写入缓存的数据,都是从 mysql 里查出来的,都得写入 mysql 中,写入 mysql 中的时候必须保存一个时间戳,从 mysql 查出来的时候,时间戳也查出来。

  • 每次要写之前,先判断一下当前这个 value 的时间戳是否比缓存里的 value 的时间戳要新。如果是的话,那么可以写,否则,就不能用旧的数据覆盖新的数据。

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

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

相关文章

昇腾Ascend TIK自定义算子开发教程(概念版)

一、参考资料 【2023 CANN训练营第一季】Ascend C算子开发入门(中) 二、重要说明 TIK2编程范式把算子核内的处理程序,分成多个流水任务,任务之间通过队列(Queue)进行通信和同步,并通过统一的…

目标检测笔记(十三): 使用YOLOv5-7.0版本对图像进行目标检测完整版(从自定义数据集到测试验证的完整流程))

文章目录 一、目标检测介绍二、YOLOv5介绍2.1 和以往版本的区别 三、代码获取3.1 视频代码介绍 四、环境搭建五、数据集准备5.1 数据集转换5.2 数据集验证 六、模型训练七、模型验证八、模型测试九、评价指标 一、目标检测介绍 目标检测(Object Detection&#xff…

2023国赛高教社杯数学建模C题思路分析

1 赛题 在生鲜商超中,一般蔬菜类商品的保鲜期都比较短,且品相随销售时间的增加而变差, 大部分品种如当日未售出,隔日就无法再售。因此, 商超通常会根据各商品的历史销售和需 求情况每天进行补货。 由于商超销售的蔬菜…

Ubuntu 20.04上docker安装Redis

要在Ubuntu 20.04上使用Docker安装Redis,您可以按照以下步骤进行操作: 1.更新系统包列表:sudo apt update2.安装Docker:sudo apt install docker.io3.启动Docker服务并设置其开机自启动:sudo systemctl start docker …

链表指定区间反转

题目:反转从位置 m 到 n 的链表。请使用一趟扫描完成反转。 说明: 1 ≤ m ≤ n ≤ 链表长度。 输入:1->2->3->4->5->NULL, m 2, n 4 输出:1->4->3->2->5->NULL 头插法 Java实现 public static ListNode rev…

【AWS】如何用SSH连接aws上的EC2实例(虚拟机)?

目录 0.环境 1.连接结果示例 2.SSH连接思路 3.具体步骤 1)安装并运行ssh服务 2)启动ssh服务 3)在AWS上找到正在运行的EC2实例,并且根据提供的ssh连接语句进行连接 0.环境 windows 11 64位 前提: 有aws账户&…

学生信息系统(python实现)

#codingutf-8 import os.path filenamestudent.txtdef menm():#菜单界面print(学生管理系统)print(-----------------------------功能菜单-----------------------------)print(\t\t\t\t\t\t1.录入学生信息)print(\t\t\t\t\t\t2.查找学生信息)print(\t\t\t\t\t\t3.删除学生信息…

list【2】模拟实现(含迭代器实现超详解哦)

模拟实现list 引言(实现概述)list迭代器实现默认成员函数operator* 与 operator->operator 与 operator--operator 与 operator!迭代器实现概览 list主要接口实现默认成员函数构造函数析构函数赋值重载 迭代器容量元素访问数据修改inserterasepush_ba…

堆排序详解

堆:是一种特殊的完全二叉树,一般通过顺序表存储,分为大堆和小堆两类。 大堆:父节点的值恒大于子节点的值。 小堆:父节点的值恒小于子节点的值。 创建堆,可以使得根节点成为整个堆中保存最大或最小的值的…

基于jeecg-boot的flowable流程历史记录显示修改

更多nbcio-boot功能请看演示系统 gitee源代码地址 后端代码: https://gitee.com/nbacheng/nbcio-boot 前端代码:https://gitee.com/nbacheng/nbcio-vue.git 在线演示(包括H5) : http://122.227.135.243:9888 历…

MySQL和Oracle数据库引擎

MYSQL数据库: 在mysql数据库中,常用到的引擎主要就是2个:Innodb和MyIASM。 Innodb:它提供了对数据库ACID事务的支持,并且还提供行级锁和外键的约束。它被设计的目的就是处理大数据容器的数据库系统,它本身…

一文搞定接口幂等性架构设计方案

幂等性介绍 现如今很多系统都会基于分布式或微服务思想完成对系统的架构设计。那么在这一个系统中,就会存在若干个微服务,而且服务间也会产生相互通信调用。那么既然产生了服务调用,就必然会存在服务调用延迟或失败的问题。当出现这种问题&a…

系列四、Nginx的常用命令和配置文件

一、常用命令 1.1、查看nginx的版本号 ./nginx -v 1.2、启动nginx cd /usr/local/nginx/sbin./nginx 1.3、停止nginx cd /usr/local/nginx/sbin./nginx -s stop 1.4、重新加载nginx 说明:该命令用于修改配置文件后,在不重启nginx的情况下使配置文…

ClickHouse的WITH-ALIAS是如何实现的

ClickHouse的WITH-ALIAS是如何实现的 WITH-ALIAS包含相似但不同的两个特性&#xff1a; WITH <表达式> as <别名>WITH <别名> as <子查询> WITH <表达式> as <别名> 特性 以下SQL展示了 WITH <表达式> as <别名> 特性的用…

FPGA通信—千兆网(UDP)软件设计

一、PHY引脚功能描述 引脚功能描述1CLK25 CLK125:内部PLL生成的125MHz参考时钟&#xff0c;如MAC未使用125MHe时钟&#xff0c;则此引脚应保持浮动&#xff0c; 2 4 63 GND 接地3REG OUT开关压器&#xff0c;1.05V输出 5 6 8 9 11 12 14 15 MDI[0] MDI[0]- MDI[1] MDI[1…

学习笔记-BNF、EBNF、ABNF语法格式描述规范

目标是确认一些c/cpp的语法细节&#xff0c;需要看cpp语法定义文件。 考虑从c的语法定义文件开始确认。 考虑实现一个简化的语言定义和编译器&#xff0c;为后续的实际需求做自定义扩展。 参考网页&#xff1a; https://en.wikipedia.org/wiki/Extended_Backus%E2%80%93Naur_f…

高可用Kuberbetes部署Prometheus + Grafana

概述 阅读官方文档部署部署Prometheus Grafana GitHub - prometheus-operator/kube-prometheus at release-0.10 环境 步骤 下周官方github仓库 git clone https://github.com/prometheus-operator/kube-prometheus.git git checkout release-0.10 进入工作目录 cd kube…

【linux命令讲解大全】100. Linux常用文件传输命令详解

文章目录 cd概要主要用途参数选项返回值例子关于切换到上一个工作目录的说明关于 CDPATH关于 cdable_vars注意 从零学 python cd 切换用户当前工作目录。 概要 cd [-L|[-P [-e]]] [dir] 主要用途 切换工作目录至 dir。其中 dir 的表示法可以是绝对路径或相对路径。若参数 …

二、[mysql]之Explain讲解与实战

目录 一、了解Explain1.Explain介绍 二、Explain相关字段1.partitions2.filtered3.SHOW WARNINGS命令 三、Explain比较重要字段1.id2.select_type3.table4.type5.possible_keys6.key7.key_len8.ref9.rows10.Extra 四、索引优化实战&#xff08;遵循原则&#xff09;1.全值匹配2…

Linux 系统中查看和停止删除定时任务

文章目录 linux系统定时任务之crontab什么是crontabcrond 在 Linux 系统中查看当前配置的定时任务停止和删除定时任务的方法cron定时任务控制防火墙恢复 linux系统定时任务之crontab 什么是crontab 在Linux或类Unix系统中&#xff0c;通常使用crontab命令在指定的时间执行一个…