热点数据更新导致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的思路也是如此

总结

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

相关推荐
javachen__1 分钟前
SpringBoot整合P6Spy实现全链路SQL监控
spring boot·后端·sql
PAK向日葵4 小时前
【算法导论】PDD 0817笔试题题解
算法·面试
uzong5 小时前
技术故障复盘模版
后端
GetcharZp6 小时前
基于 Dify + 通义千问的多模态大模型 搭建发票识别 Agent
后端·llm·agent
桦说编程6 小时前
Java 中如何创建不可变类型
java·后端·函数式编程
lifallen6 小时前
Java Stream sort算子实现:SortedOps
java·开发语言
IT毕设实战小研6 小时前
基于Spring Boot 4s店车辆管理系统 租车管理系统 停车位管理系统 智慧车辆管理系统
java·开发语言·spring boot·后端·spring·毕业设计·课程设计
wyiyiyi7 小时前
【Web后端】Django、flask及其场景——以构建系统原型为例
前端·数据库·后端·python·django·flask
没有bug.的程序员7 小时前
JVM 总览与运行原理:深入Java虚拟机的核心引擎
java·jvm·python·虚拟机
甄超锋7 小时前
Java ArrayList的介绍及用法
java·windows·spring boot·python·spring·spring cloud·tomcat