聊聊八卦,当年的顶流明星事件是如何把公司的缓存架构“击垮”的?

news2024/12/25 1:38:54
V-xin:ruyuan0330 获得600+页原创精品文章汇总PDF

目录

  • 一、为什么要用缓存集群
  • 二、20万用户同时访问一个热点缓存的问题
  • 三、基于流式计算技术的缓存热点自动发现
  • 四、动加载为JVM本地缓存
  • 五、限流熔断保护
  • 六、总结

一、为什么要用缓存集群

这篇文章,咱们来聊聊热点缓存的架构优化问题。

其实使用缓存集群的时候,最怕的就是热key、大value这两种情况,那啥叫热key大value呢?

简单来说,热key,就是你的缓存集群中的某个key瞬间被数万甚至十万的并发请求打爆。

大value,就是你的某个key对应的value可能有GB级的大小,导致查询value的时候导致网络相关的故障问题。

这篇文章,我们就来聊聊热key问题。先来看看下面的一幅图。

简单来说,假设你手头有个系统,他本身是集群部署的,然后后面有一套缓存集群,这个集群不管你用redis cluster,还是memcached,或者是公司自研缓存集群,都可以。

在这里插入图片描述

那么,这套系统用缓存集群干什么呢?

很简单了,在缓存里放一些平时不怎么变动的数据,然后用户在查询大量的平时不怎么变动的数据的时候,不就可以直接从缓存里走了吗?

缓存集群的并发能力是很强的,而且读缓存的性能是很高的。

举个例子,假设你每秒有2万请求,但是其中90%都是读请求,那么每秒1.8万请求都是在读一些不太变化的数据,而不是写数据。

那此时你把数据都放在数据库里,然后每秒发送2万请求到数据库上读写数据,你觉得合适吗?

当然不太合适了,如果你要用数据库承载每秒2万请求的话,那么不好意思,你很可能就得搞分库分表 + 读写分离。


比如你得分3个主库,承载每秒2000的写入请求,然后每个主库挂3个从库,一共9个从库承载每秒1.8万的读请求。

这样的话,你可能就需要一共是12台高配置的数据库服务器,这是很耗费钱的,成本非常高,而且很不合适。

大家看看下面的图,来体会下这种情况。

在这里插入图片描述

所以,此时你完全就可以把平时不太变化的数据放在缓存集群里,缓存集群可以采用2主2从,主节点用来写入缓存,从节点用来读缓存。

以缓存集群的性能,2个从节点完全可以用来承载每秒1.8万的大量读了,然后3个数据库主库就是承载每秒2000的写请求和少量其他读请求就可以了。

大家看看下面的图,你耗费的机器瞬间变成了4台缓存机器 + 3台数据库机器 = 7台机器,是不是比之前的12台机器减少了很大的资源开销?

没错,缓存其实在系统架构里是非常重要的组成部分。很多时候,对于那些很少变化但是大量高并发读的数据,通过缓存集群来抗高并发读,是非常合适的。

在这里插入图片描述

这里所有的机器数量、并发请求量都是一个示例,大家主要是体会一下这个意思就好,其目的主要是给一些不太熟悉缓存相关技术的同学一点背景性的阐述,让这些同学能够理解在系统里用缓存集群承载读请求是什么意思。


二、20万用户同时访问一个热点缓存的问题

好了,背景是已经给大家解释清楚了,那么现在就可以给大家说说今天重点要讨论的问题:热点缓存

我们来做一个假设,你现在有10个缓存节点来抗大量的读请求。正常情况下,读请求应该是均匀的落在10个缓存节点上的,对吧!

这10个缓存节点,每秒承载1万请求是差不多的。

然后我们再做一个假设,你一个节点承载2万请求是极限,所以一般你就限制一个节点正常承载1万请求就ok了,稍微留一点buffer出来。


好,所谓的热点缓存问题是什么意思呢

很简单,就是突然因为莫名的原因,出现大量的用户访问同一条缓存数据。

举个例子,某个明星突然宣布跟某某结婚,这个时候是不是会引发可能短时间内每秒都是数十万的用户去查看这个明星跟某某结婚的那条新闻?

那么假设那条新闻就是一个缓存,然后对应就是一个缓存key,就存在一台缓存机器上,此时瞬时假设有20万请求奔向那一台机器上的一个key。

此时会如何?我们看看下面的图,来体会一下这种绝望的感受。

在这里插入图片描述

这个时候很明显了,我们刚才假设的是一个缓存Slave节点最多每秒就是2万的请求,当然实际缓存单机承载5万~10万读请求也是可能的,我们这里就是一个假设。

结果此时,每秒突然奔过来20万请求到这台机器上,会怎么样?

很简单,上面图里那台被20万请求指向的缓存机器会过度操劳而宕机的。

那么如果缓存集群开始出现机器的宕机,此时会如何?

接着,读请求发现读不到数据,会从数据库里提取原始数据,然后放入剩余的其他缓存机器里去。但是接踵而来的每秒20万请求,会再次压垮其他的缓存机器。

以此类推,最终导致缓存集群全盘崩溃,引发系统整体宕机。

咱们看看下面的图,再感受一下这个恐怖的现场。

在这里插入图片描述

三、基于流式计算技术的缓存热点自动发现

其实这里关键的一点,就是对于这种热点缓存,你的系统需要能够在热点缓存突然发生的时候,直接发现他,然后瞬间立马实现毫秒级的自动负载均衡。

那么我们就先来说说,你如何自动发现热点缓存问题

首先你要知道,一般出现缓存热点的时候,你的每秒并发肯定是很高的,可能每秒都几十万甚至上百万的请求量过来,这都是有可能的。


所以,此时完全可以基于大数据领域的流式计算技术来进行实时数据访问次数的统计,比如storm、spark streaming、flink,这些技术都是可以的。

然后一旦在实时数据访问次数统计的过程中,比如发现一秒之内,某条数据突然访问次数超过了1000,就直接立马把这条数据判定为是热点数据,可以将这个发现出来的热点数据写入比如zookeeper中。

当然,你的系统如何判定热点数据,可以根据自己的业务还有经验值来就可以了。

大家看看下面这张图,看看整个流程是如何进行的。

在这里插入图片描述

当然肯定有人会问,那你的流式计算系统在进行数据访问次数统计的时候,会不会也存在说单台机器被请求每秒几十万次的问题呢?

答案是,因为流式计算技术,尤其是storm这种系统,他可以做到同一条数据的请求过来,先分散在很多机器里进行本地计算,最后再汇总局部计算结果到一台机器进行全局汇总。

所以几十万请求可以先分散在比如100台机器上,每台机器统计了这条数据的几千次请求。

然后100条局部计算好的结果汇总到一台机器做全局计算即可,所以基于流式计算技术来进行统计是不会有热点问题的。

在这里插入图片描述

四、动加载为JVM本地缓存

我们自己的系统可以对zookeeper指定的热点缓存对应的znode进行监听,如果有变化他立马就可以感知到了。

此时系统层就可以立马把相关的缓存数据从数据库加载出来,然后直接放在自己系统内部的本地缓存里即可。

这个本地缓存,你用ehcache、hashmap,其实都可以,一切都看自己的业务需求,主要说的就是将缓存集群里的集中式缓存,直接变成每个系统自己本地实现缓存即可,每个系统自己本地是无法缓存过多数据的。

因为一般这种普通系统单实例部署机器可能就一个4核8G的机器,留给本地缓存的空间是很少的,所以用来放这种热点数据的本地缓存是最合适的,刚刚好。


假设你的系统层集群部署了100台机器,那么好了,此时你100台机器瞬间在本地都会有一份热点缓存的副本。

然后接下来对热点缓存的读操作,直接系统本地缓存读出来就给返回了,不用再走缓存集群了。

这样的话,也不可能允许每秒20万的读请求到达缓存机器的一台机器上读一个热点缓存了,而是变成100台机器每台机器承载数千请求,那么那数千请求就直接从机器本地缓存返回数据了,这是没有问题的。

我们再来画一幅图,一起来看看这个过程:

在这里插入图片描述

五、限流熔断保护

除此之外,在每个系统内部,其实还应该专门加一个对热点数据访问的限流熔断保护措施。

每个系统实例内部,都可以加一个熔断保护机制,假设缓存集群最多每秒承载4万读请求,那么你一共有100个系统实例。

你自己就该限制好,每个系统实例每秒最多请求缓存集群读操作不超过400次,一超过就可以熔断掉,不让请求缓存集群,直接返回一个空白信息,然后用户稍后会自行再次重新刷新页面之类的。

通过系统层自己直接加限流熔断保护措施,可以很好的保护后面的缓存集群、数据库集群之类的不要被打死,我们来看看下面的图。

在这里插入图片描述

六、本文总结

具体要不要在系统里实现这种复杂的缓存热点优化架构呢?这个还要看你们自己的系统有没有这种场景了。

如果你的系统有热点缓存问题,那么就要实现类似本文的复杂热点缓存支撑架构。

但是如果没有的话,那么也别过度设计,其实你的系统可能根本不需要这么复杂的架构。

如果是后者,那么大伙儿就权当看看本文,来了解一下对应的架构思想好了_

V-xin:ruyuan0330 获得600+页原创精品文章汇总PDF

另外推荐儒猿课堂的1元系列课程给您,欢迎加入一起学习~

互联网Java工程师面试突击课(1元专享)

SpringCloudAlibaba零基础入门到项目实战(1元专享)

亿级流量下的电商详情页系统实战项目(1元专享)

Kafka消息中间件内核源码精讲(1元专享)

12个实战案例带你玩转Java并发编程(1元专享)

Elasticsearch零基础入门到精通(1元专享)

基于Java手写分布式中间件系统实战(1元专享)

基于ShardingSphere的分库分表实战课(1元专享)

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

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

相关文章

数值优化之基本概念

本文ppt来自深蓝学院《机器人中的数值优化》 目录 1 推荐书单 2 优化问题的基本范式 3 数值优化在机器人领域的应用 1 推荐书单 对于英语阅读有困难的同学可以看第一本书,对于最优化的介绍也是比较详细的。 这是第一本书的ppt链接最优化:建模、算法…

【LDF】线性判别函数(三)

松弛方法 学习准则 在感知函数准则中, 目标函数中采用了 −aTy-\mathbf{a}^T \mathbf{y}−aTy 的形式。实际上有很多其它准则也可以用于感知函数的学习。线性准则 Jp(a)∑y∈Y(−aTy)J_p(\mathbf{a})\sum_{\mathbf{y} \in Y}\left(-\mathbf{a}^T \mathbf{y}\right) Jp​(a)y∈…

MP中定义全局常量用于xml的判断

1.普通方式 mybatis-plus.configuration.variables.secretFilterSwitch0 yml的方式 mybatis: mapper-locations: classpath:mapper/*.xml type-aliases-package: com.demo configuration: variables: userId: 456132465 userName: 李四 配置完成后在代码…

NLP论文RoFormer(含源码)中文解读:具有旋转式位置嵌入的增强型transformer模型(一场相对革命)

目录 1、论文与源码2、摘要介绍3、展开解读3.1、匹配或超过了目前可用于将位置信息注入变换器的所有其他方法3.2、模型思想3.3、公式推导3.4、源码解释GPT-NeoX(PyTorch)网状变压器 JAX (JAX)4、 对比实验参考文献1、论文与源码 RoFormer匹配或超过了目前可用于将位置信息注…

分享76个PHP源码,总有一款适合您

链接:https://pan.baidu.com/s/1dC6_-CLs_qSyNnKEmno0Pg?pwd6666 提取码:6666 下面是文件的名字,我放了一些图片,文章里不是所有的图主要是放不下...,大家下载后可以看到。 UTForum社区论坛 v2.5 响应式健身房信息展…

小波分析—— 3. 实现一个简单的Haar小波

由于小波在应用形式上与卷积很相似,所以如果你有需要,可以查看我以前写过的内容: 信号采样基本概念 —— 冲激函数卷积计算——1. 关于卷积的基本概念卷积计算——2. 一些常用于图像的卷积核与应用 另外常见的信号处理工具,傅里…

Unity脚本(三)

视频教程:https://www.bilibili.com/video/BV12s411g7gU?p128 目录 Time Prefab Animation Time Time.time:自应用程序启动以来,每帧的开始时间(只读) Time.deltaTime:每帧间隔,或说完…

SpringData

文档:D:\springdata SpringData是一个用来简化dao层开发的框架.在保证了各个底层存储特性同时,提供了一套统一的数据访问API.它可以很好的支持常用的关系型数据库和非关系型数据库. 使用SpringData做为dao层开发技术,将大大简化代码,而且其API比各个技…

【力扣周赛#326】6279.数组乘积中的不同质因数数目+6196.将字符串分割成值不超过K的子字符串+6280.范围内最接近的两个质数

目录 6278.统计能整除数字的位数 - 简单ac 6279.数组乘积中的不同质因数数目 - 质因数 6196.将字符串分割成值不超过K的子字符串 - 贪心 6280.范围内最接近的两个质数 - 质数筛 贪心 6278.统计能整除数字的位数 - 简单ac 6278. 统计能整除数字的位数 class Solution {pu…

aws codebuild 配置codecommit更新触发和squid正向代理

本文主要讨论如何通过监听codecommit仓库自动触发codebuild的构建,以及为codebuild配置正向代理 通过codecommit更新触发codebuild codecommit触发器相关 每个codecommit最多配置10个触发器 sns触发器 为sns创建lambda函数订阅,在lambda日志中查看s…

一个例题,了解包装类

下列代码输出什么,为什么? public class Test3 {public static void main(String[] args) {Integer a1 100;Integer a2 Integer.valueOf(100);Integer a3 new Integer(100);System.out.println(a1 a2);System.out.println(a1 a3);System.out.println(a1.equals(a3));Sys…

分离编译、类型萃取、变参模板

分离编译 一个程序由若干个源文件共同实现,每个源文件单独编译生成目标文件,最后将所有的目标文件链接起来形成单一可执行文件的过程称之为分离编译模式。模板不支持分离编译 编译器报的这种错误属于链接性错误,也就是当程序预处理、编译、汇…

Sutherland–Hodgman 算法介绍(简单易懂)

目录 一、算法介绍 二、算法描述 三、计算细节补充 四、算法总结 一、算法介绍 我们使用Sutherland–Hodgman算法来裁剪多边形的边,一般是给你一个多边形顶点序列(P1,P2,P3,P4,…Pn)让你裁剪,最终裁剪掉裁剪多边形的外部部分(下图黑框就是裁剪多边形…

大中型政企机构网络安全建设发展趋势研究报告

声明 本文是学习大中型政企机构网络安全建设发展趋势研究报告. 下载地址而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我们 研究背景 大中型政企机构是网络安全保护的重中之重,也是国内网络安全建设投入最大,应用新技术、新产品最…

Proteus8仿真:51单片机25AA020A(SPI接口EEPROM)的使用

51单片机25AA020A实验内容25AA020A引脚功能SPI信号模拟8位写8位读EEPROM读写函数EEPROM写使能EEPROM写一个Byte实验程序例程main.c工程文件Microchip的25AA020A是一个2Kbit串行电可擦除可编程只读存储器(EEPROM)。内存可以通过一个简单的串行外围接口&am…

第三十讲:神州路由器路由重分发配置

RIP和OSPF协议是目前应用最广泛的路由协议,两种协议交接的场合也很多见,两种协议的重分布是比较常见的配置。主校区原来所采用的网络协议为OSPF,而分校区采用的路由协议是RIP,采用RIP和OSPF重分发技术可以解决此问题。 实验拓扑图…

HDLBits练习汇总-14-时序逻辑设计测试--状态机(二)

水箱问题(Exams/ece241 2013 q4) 一个大水库的水为几个用户服务。为了保持足够高的水位,三个传感器以5英寸的间隔垂直放置。当水位高于最高传感器S3时,输入流量应为零。当液位低于最低传感器(Si)时,流量应处于最大(公…

【技术分享】戴尔工作站安装Win10+Ubuntu20.04双系统避坑指南

文章目录引言1.安装前的几个注意事项(避坑指南)1.1.有多块硬盘,该如何分配给Win10和Ubuntu系统?1.2.Ubuntu分区应该怎么分?2.系统安装步骤2.1.下载系统镜像2.2.制作U盘启动盘2.3.进入Win10系统分配系统空间2.4.BIOS设置…

82.【LibraryManger】

图书管理系统(一)、搭建环境1.数据库语句2.导入需要的依赖(二)、配置文件3.创建MyBatis的xml文件 mybais-config.xml4.创建dao层接口以及dao层的 mapper.xml5.创建数据库的资源 database.properties6.创建spring的配置文件 spring-dao.xml【】7.创建service层的接口以及servcie…

查找

章节目录:一、线性查找1.1 概述1.2 代码示例二、二分查找2.1 概述2.2 代码示例三、插值查找3.1 概述3.2 代码示例四、斐波那契查找4.1 概述4.2 代码示例五、结束语一、线性查找 1.1 概述 线性查找又称顺序查找,是一种最简单的查找方法,它的…