【高并发】热点数据更新导致CPU100%的解决方案

news/2024/10/23 9:27:02/

文章目录

  • 前言
  • 为什么会导致CPU飙升
  • 解决方案- 分而治之
  • 流量分摊思路
  • 总结

前言

在平常的工作中,更新数据是再正常不过的一个需求了,我们只需要执行一个update语句即可,如果有必要我们还可以加上事务来保证数据的可靠性。

但是如果这是一个热点数据,就比如说直播下单,如果这个商品很火爆,价格又很低,那么就会有很多人下单,这种下单不像秒杀,秒杀是有限制数量,但是这种直播下单是不限量的,可以同时有很多人在下单,这时候用户来下单,那么首先就要判断库存是否足够,如果有库存,那么就更新库存。

这时候,这个库存就成了热点数据,因为如果有几万人同时下单,那么就会导致同时有几万个线程来更新这个库存数据。这时候我们的CPU就会瞬间达到100%。就有可能出现一些异常情况,导致用户下单业务受到影响。

我们可以使用本地数据库,加上jmeter来进行压测,因为之前一次压测,我把公司测试数据库都搞崩了,所以这里没有展示cpu信息了。大家可以自己进行压测,然后使用top命令来查看cpu的信息。

为什么会导致CPU飙升

这时候就要谈到MySql的行锁了。在我们执行一条update语句的时候,这时候MySql会开启一个事务,并且对这条记录进行加锁。在这个线程没有释放资源以前,其它线程进来要更新就只能等待。但是这并不是导致CPU飙升的原因。

我们知道MySql是有一个死锁检测的机制,也就是说,当一个线程去更新记录的时候,首先要判断是否会发生死锁,如果发生死锁,就会主动回滚某一个事务,让其释放资源,让其它事务得以继续运行。

所以这时候问题就来了,如果这时候有1000个线程,那么每个线程都要去判断是否会发生死锁,也就是要每一个线程都要跟其它线程进行一个死锁的判断。那么这个时间复杂度就是O(n2), 也就是有1000 * 1000 = 1000000,100万次的死锁判断,就是因为有了这个死锁检测,所以才导致CPU飙升。

那么有什么办法去解决嘛?当然是有的

解决方案- 分而治之

我们可以采用分而治之的思想去解决这个问题。比如我们现在有1万个库存,那么我们可以搞10台服务器,也就是10台MySql服务器。每台服务器上都只放1000个库存,这样我们就可以将压力分摊在这10台服务器。

这时候很多人会问,即使分摊给多台服务器,那么MySql的压力还是很大呀。

是的,所以在高并发的写场景下,我们不建议使用MySql,而是使用缓存数据库,比如Redis这时候我们将所有的库存都放在一个redis中,为了保证数据的可靠性,我们还是用了主从备份,甚至是redis集群等。但是用户下单的都是同一个商品,也就是说所有用户来访问都只会是访问同一个redis节点。

即使你使用了redis这种缓存数据库,当并发量上来,redis还是会扛不住的。

所以我们需要使用redis的分片技术,也就是将库存分摊到多个redis节点。跟MySql一样,也搞10台redis服务。这样就可以将压力分摊到10个redis节点上。

流量分摊思路

假设我们现在就有10台MySql服务器。那么如何将用户流量分摊到这10台服务器呢?

我们知道,用户下单那么订单里面肯定会有一个用户ID,所以我们可以对用户ID进行取模,这样就可以将用户流量分摊到每台服务器上但是这时候又会有一个问题,如果这时候第一台MySql的库存很快就没有了,其它MySql上还有库存这时候如果这个用户到MySql-1上发现没有库存了,这时候我们可以让他到MySql-2服务器上,以此类推,直到有库存返回即可当然使用redis的思路也是如此。

总结

在平常工作中,如果碰到大数据量,或者大流量的时候,分而治之是一个很好的解决思路,将数据或者流量分摊,以此来减轻每台服务器的压力。


http://www.ppmy.cn/news/1000467.html

相关文章

微信小程序如何调用微信支付接口?

开发前准备 小程序appid,商户id,商户密钥(key),付款用户的(openid) 调用微信支付接口 (流程:首先调用微信统一下单接口,之后在调用wx.requestPayment(OBJECT)发起微信支付) 获取openid wx.login({succ…

2023 7.31~8.6 周报 (多尺度的DL-FWI + 自然图像的风格迁移速度模型)

->目录<- 0 上周回顾1 本周论文背景简述2 模型架构3 风格化速度模型4 训练与实际数据的测试5 存在的一些问题6 总结和下一步工作 0 上周回顾 上周完成了VelocityGAN的重现和学习. 认识到了利用判别器网络对于常规网络进行约束是很一种很高效的设计思路. 1 本周论文背景…

QT-QLabel显示图片,按QLabel控件的大小自动缩放

要按照 QLabel 控件的大小调整并显示图片&#xff0c;你可以使用 scaled() 函数将 QPixmap 对象进行缩放&#xff0c;然后将缩放后的图片设置到 QLabel 上。下面是一个示例代码&#xff1a; #include <QApplication> #include <QLabel> #include <QPixmap>i…

Grafana+Alter+webhook发预警给钉钉

上文写了如何FlinkMetric发送监控消息最后在grafana展现。现在要把grafana的消息发给钉钉群 首先复制出来钉钉群的钉钉机器人的access_token grafana的告警 1.架构简介&#xff1a;alert rules、contact points 、notification policies。 alert rules主要设置触发警告的规则&…

23.8.2总结(博客项目)

这几天还是在写项目&#xff0c;把个人中心的功能完善了一些&#xff0c;但是还有没有弄好的&#xff1a; 在个人中心添加新建专栏和收藏夹 在个人中心按照时间&#xff0c;标签&#xff0c;专栏分&#xff0c;还有搜索该用户的文章内容 然后开始写评论&#xff0c; 还要需要完…

Qt项目---简单的计算器

在这篇技术博客中&#xff0c;我们将介绍如何使用Qt框架实现一个简单的计算器应用。我们将使用C编程语言和Qt的图形用户界面库来开发这个应用&#xff0c;并展示如何实现基本的算术操作。 项目设置 首先&#xff0c;我们需要在Qt Creator中创建一个新的Qt Widgets应用程序项目…

Debian 系列 Linux 的静态 DNS 、gateway 、IP 设置和网络重启

文章目录 DNS 设置DNS 配置文件DNS 配置文件内容 gateway、IP 设置网络适配器配置文件网络适配器配置文件内容 网络重启 各个 Linux 发行版的网络设置有很大不同。根据最近对 Debian 系列&#xff08;含 Debian 12、基于 Debian 12 的Proxmox 8.0-2 以及基于Debian 11 的 openm…

python-爬虫作业

# -*- coding:utf-8 -*-Author: 董咚咚 contact: 2648633809qq.com Time: 2023/7/31 17:02 version: 1.0import requests import reimport xlwt from bs4 import BeautifulSoupurl "https://www.dygod.net/html/gndy/dyzz/" hd {user-Agent:Mozilla/4.0 (Windows N…