热点数据更新导致CPU100%的解决方案

大家好,我是小趴菜。在平常的工作中,更新数据是再正常不过的一个需求了,我们只需要执行一个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的思路也是如此

总结

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

相关推荐
captain3763 分钟前
MyBatis操作数据库(入门2)
java·数据库·spring boot·后端·spring·mybatis
心中有你021424 分钟前
Java实现Dijkstra最短路径算法(邻接表 + 优先队列)
java·数据库·算法
步行cgn1 小时前
Spring MVC + Thymeleaf 模板解析失败:从 500 错误到页面正常显示
java·spring·mvc
IT_陈寒1 小时前
Java序列化踩坑记:对象循环引用让我加班两小时
前端·人工智能·后端
每天进步一点点km1 小时前
自用-牛客网-华为机试编程模拟题1-python
华为od·华为·面试
lgcgkCQ2 小时前
【AI 转型实战 1】SpringAI 入门:搭建基础大模型对话能力
java·ai·agent·rag·spring ai·mcp·langchain4j
泡海椒2 小时前
05-雷达图多维画像-信用评级多维画像
后端
王中阳Go2 小时前
5.27 分钟干完后端和全部测试:一场三小时笔试的五个失分点,四个不在代码上
大数据·数据库·人工智能·后端·大语言模型
大哥43092 小时前
Modbus 的"字序":一个配错就变成天文数字,或者干脆变成 0
后端
Wang's Blog2 小时前
Java 项目实战:交友项目 - 用户体系集成总结
java·开发语言·交友