MySQL的CPU达到100%情况复盘解析
一、业务场景及问题描述
网站总注册用户大约6W,平时日活比较低,但是在活动的时候,高并发问题相继出现,当前,有一次活动,主要是给固定的6位idol进行投票应援,高并发问题也随之而来。
最直接的问题就是,在用户投票的时候突然不能投票,中间mysql大约宕机了8min左右。
二、网站服务背景描述
- web服务:两台web服务器,均是8核16G
- 一台mysql5.6服务器,4核8G,mysql最大连接数1500
- 一台memcache和一台redis2.8
三、问题描述分析
- mysql的cpu瞬间打满到100%(平时最高不超过40%),mysql的qps瞬间达到1w(平时不超过500),磁盘使用和占用空间变小,慢查询次数极大增加
- web服务器的负载瞬间增大到5.7,平时不到1
- nginx报错:出现大量的time out和too many open files错误
19743#0: accept4() failed (24: Too many open files)
分析:
(1)nginx出现time out,说明nginx连接后端服务器比如php的时候,后端处理时间太长,导致出现超时
(2)出现超时问题,有两种通常的解决方式:一种就是分析后端为什么处理时间太长,一般是mysql慢查询问题,一种就是直接更改nginx超时时间,设置更长的超时时间。
(3)出现too many files ,文件数打开太多,一方面是网站流量太大,一方面可以查看服务器的max open files,可以通过ulimit -a命令查看最大打开文件数是10w。
(4)出现too many files,可以重新设置最大打开文件数,具体可以参考:https://learnku.com/articles/...
- 项目报错:出现大量的mysql连接错误
Next yiidbException: SQLSTATE[HY000] [2002] 连接超时 in /srv/www/vendor/yiisoft/yii2/db/Connection.php:624 Stack trace: #0 /srv/www/vendor/yiisoft/yii2/db/Connection.php(996): yiidbConnection->open() #1 /srv/www/vendor/yiisoft/yii2/db/Connection.php(983): yiidbConnection->getMasterPdo() #2 /srv/www/vendor/yiisoft/yii2/db/Command.php(253): yiidbConnection->getSlavePdo() #3 /srv/www/vendor/yiisoft/yii2/db/Command.php(1143): yiidbCommand->prepare(true) #4 /srv/www/vendor/yiisoft/yii2/db/Command.php(425): yiidbCommand->queryInternal('fetchColumn', 0) #5 /srv/www/vendor/yiisoft/yii2/db/Query.php(463): yiidbCommand->queryScalar() #6 /srv/www/vendor/yiisoft/yii2/db/ActiveQuery.php(340): yiidbQuery->queryScalar('COUNT(*)', Object(yiidbConnection))
分析:
(1)由此可以看到,整个服务的根源在于mysql出现了问题,一般可能就是瞬间的高并发,慢查询sql增多,导致mysql直接宕机,整个服务崩溃
(2)可以看到,mysql的qps瞬间增大,cpu直接打满,mysql慢查询次数增加
(3)解决方式,主要是优化慢查询sql,具体可以参考:https://my.oschina.net/sundas...
四、优化
- 对有慢查询sql进行索引等优化,这是最主要的,一般出现cpu打满都是这个原因
- 在业务逻辑上进行优化,尽量避免复杂sql,拆分成查询率更高的短sql
- 慢查询逻辑中,能用redis的,尽量使用redis
- show processlist查看当前正在执行的sql,看到有几条有异常的sql语句,发现从表中查询的数据过大,赶紧kill掉这些正在运行的语句
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。