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

总结

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

相关推荐
Q_19284999066 分钟前
基于Spring Boot的摄影器材租赁回收系统
java·spring boot·后端
Code_流苏9 分钟前
VSCode搭建Java开发环境 2024保姆级安装教程(Java环境搭建+VSCode安装+运行测试+背景图设置)
java·ide·vscode·搭建·java开发环境
良许Linux11 分钟前
0.96寸OLED显示屏详解
linux·服务器·后端·互联网
ThisIsClark15 分钟前
【后端面试总结】MySQL主从复制逻辑的技术介绍
mysql·面试·职场和发展
求知若饥23 分钟前
NestJS 项目实战-权限管理系统开发(六)
后端·node.js·nestjs
禁默1 小时前
深入浅出:AWT的基本组件及其应用
java·开发语言·界面编程
Cachel wood1 小时前
python round四舍五入和decimal库精确四舍五入
java·linux·前端·数据库·vue.js·python·前端框架
Code哈哈笑1 小时前
【Java 学习】深度剖析Java多态:从向上转型到向下转型,解锁动态绑定的奥秘,让代码更优雅灵活
java·开发语言·学习
gb42152871 小时前
springboot中Jackson库和jsonpath库的区别和联系。
java·spring boot·后端
程序猿进阶1 小时前
深入解析 Spring WebFlux:原理与应用
java·开发语言·后端·spring·面试·架构·springboot