您的位置:首页 > 数据库

一次服务器性能瓶颈查找和优化经历。

2016-12-20 11:20 639 查看
10月份 公司服务器频繁出现问题,整个优化过程如下

最开始能所做的工作,为了应急只能频繁重启,频繁重启的原因只有一个,因为重启无效只能暂时恢复,立马又会因为服务器内存爆掉而瘫痪,解决问题的方式只有频繁重启。高峰时期的请求数和数据库处理能力不在一个平衡点。大量重启之后,服务器恢复正常。整个过程常常伴随着阿里云数据库的主备切换。

公司业务架构比较古老,一台windows(存在的原因是因为被部分终端指定了ip)+两台linux(其中一台装了nginx。通过域名访问 到nginx 再分发到两台linux)+memcached缓存session 没了,外加一个sql server数据库实例。服务器和数据库均挂靠在阿里云上。

首先从公司的整个服务器架构分析出问题的点有两个

1. 服务器内存爆掉,导致服务器响应不了新的请求,特征同步变得非常缓慢,再慢慢到同步不了

2. 数据库死锁异常严重。性能极差

观察到

数据库的各项指标

优化过程前的iops,以及 cpu 情况,数据库连接数情况 分别取了17号到21号的数据

cpu






iops





数据库连接数





总结:iops 经常达到1W2的水平,之前一直在6K。公司对服务器进行了硬件升级,6k–>12k 之后iops 又重原来的6k 直接冲到了现在允许的12k. 服务器依然经常奔溃,说明应用确实存在非常大的问题。通过简单的硬件升级 只能稍微提升些数据库的性能。但是根本问题并没有得到解决

cpu 在可以接受的范围内。

连接数异常 非常不稳定。

脱离掉指标

多天观察服务器运行状态。

对比服务器正常运行时期,分析jvm 中各个类的占用情况。

正常情况下:



当服务器瘫痪时 表现 [B 失控一直增长到撑爆 指定的jvm 4G内存大小。 [B 是bytes数据

服务器正常运行时期并不会一直增长 大概在200多MB左右。高峰时期会在400~500Mb波动。由此可以基本排除是我们应用的启动参数设置问题。正常运行的项目 连1.5g内存都没有用到。

关于连接数

在一次服务器瘫痪前夕,通过观察日志 看到连接池内连接数 被占用完了,其他请求得不到相应的连接。检查项目的连接池,发现服务器正在运行的项目,五个项目,两台linux上分别有两个,windows有一个。关于连接池的初始连接数,最大连接数不一样。甚至有

开发环境的参数在正式上跑。我根据公司的业务分析,更改了所有项目最大连接数,初始连接数,之后数据库连接数基本稳定在800 左右。•

拿到服务器崩溃时候的dump.文件

分析拿到的byte[] 数据的内容大部分都是终端 post过来的数据。结合数据库死锁的情况。可以得出这样的结论 并不是代码导致的内存泄漏引发的服务器oom, 而是数据库性能

差,远远跟不上终端post过来的数据,数据大量堆积在服务器正在处理,没有返回导致GC 没有办法回收。内存越来越高,服务器爆了。

之后10-24 的服务器崩溃拿到相应的dump,又追踪到了一些公司内部报表的功能。生成本来是应当凌晨五点执行,但是却在白天执行。当晚我立即把更新报表功能去掉(接口依然存在)留着凌晨定时任务生成,并优化了下语句。

11 -3 web商家端和云店出现短暂故障,分析dump得到再次由此更新报表功能引起。晚上我直接把接口去掉了。反复确认正常使用不可能有调更新功能的接口,这次直接把更新接口下了。

关于阿里云主备切换

因为服务器崩溃往往伴随这阿里云数据库发生主备切换。因为先后顺序无法确定

无法判定是否是因为阿里云导致。后来知道了因为我们应用的慢sql 在数据库中发生了死锁

导致数据内存也飙高 ,后来的请求也处理不完阻塞服务器。就算重启服务器,数据库死锁依然存在,数据库跟服务器的处理速度完全不在一个点上。数据库死锁依然存在,才是导致服务器重启短暂有效的主要原因,还有一个原因服务器重启之后会被大量重复请求和正常请求阻塞。

所以目前的主要问题都是由于sql效率低,数据库性能差,以及一些不合适的报表功能导致。最终决定采取数据库优化的方案,下面是对数据库的整体优化。由yydba大神陈畅亮主导,我个人配合实施ude数据库优化方案一期,二期。方案的确定是陈畅亮在结合我对项目,以及业务的了解下做出的决策。一期效果不明显。二期做完,截至到目前2016-12-20为止再未发生过服务器宕机,可见二期效果非常明显。

一期优化工作。

对我们现有业务的大表查询sql语句中 rowlock 用nolock 进行替换,并且略微调整语句结构,现阶段业务暂时还没有牵涉到支付,并且还没要到这么严格的级别。所以并不需要rowlock 。特别业务可以特别调整。

分析阿里云 所给出的慢sql 统计。包括业务sql,索引。

分析整个库的各个表的各类指标。

确定二期执行方案

二期优化工作

对数据库中最大的的八个表进行结构变更。

优化原理:

1. 数据库表增加一列主键ID 并全部重新生成表的存储结构和索引结构,(减少整个库的数据所占空间大小,原理所有的索引页都有物理主键信息,而主键字段类型变更带来占用空间变少从而间接减少了对内存的压力以及 iops等一系列影响)

2. 提高关于一页8kb 的利用率(原有Kid是非顺序存储,而id是顺序存储)

注 kid即为uuid

可能引发的问题

1. 数据重整导致数据库变更表记录时间戳大批量数据需要下载(公司业务机制,sql server timestamp字
aff6
段为终端下载数据的判断条件)

2. 数据迁移过程可能 会发生未知错误。

3. 整个表结构变更之后大部分索引需要重新调整,否则部分功能查询会受到影响

实施可能性

1.项目大量原生sql 只有少量orm代码。使得不修改代码就可以完成优化。当然会有语句需要特别调整除外。

2.整个过程具有可逆性。发现未知情况可以回滚回来。

最后决定按业务分批

第一批 订单模块

第二批 商品模块

用了一个周末两天时间在测试库上完成所有变更,并且在测试环境上跑了一个星期,并没有明显问题。最后开始实施到正式库。

整个迁移过程脚本之前和成果。 已经另外整理脚本所以不在此重复下去。表结构变更以及索引调整给正式库了大约 节约了250G 存储空间,iops也下降明显。

在第一批优化之后服务器由于索引结构变更,已经我们修改的索引未覆盖到所有的功能,出现了一些锁表现象引发服务器宕机的情况,在接下来的每天 我都抓出了一些慢查询语句进行优化。服务器也渐渐变稳定。

第二次优化之后服务器 由于准备时间充分,所以这次索引调整覆盖了大部分查询。再未发生过宕机。一直稳定运行。

以下是二次优化 数据库Iops,cpu,数据库连接数的情况

分别取了 11-7 到11-9 三天的数据

cpu




iops





连接数





数据库优化结果。

iops 下降效果尤为明显。大概平均在2k~3k左右。

归于以上工作,还有许多细节,脾气不好的服务器终于稳定下来,并且从大部分客户反馈 各种操作都相比之前快了许多。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息