以下来分享一个关于MySQL数据库慢查询和FGC频繁的性能案例。

一、系统架构

  

  

  一个简单的dubbo服务,服务提供者提供接口,并且提供接口的实现,提供方注册服务到Zookeeper注册中心,然后消费者要用其某个服务的时候,就去zookeeper上订阅该服务。这样,我们只需要使用接口,然后通过spring getbean,就可以让这个接口实例化,拿来使用,通过传参去Mysql数据库查询数据。

同时因为消费者只能得到接口,而无法看到接口的实现,也保证了服务者的安全。

服务注册与调用

脚本实现接口调用

关于如何编写dubbo服务脚本可参考上篇文章: https://www.cnblogs.com/zhang-zhi/p/9929447.html

二、现象及问题

  上图为10用户并发时,系统的整体性能表现,包括TPS与平均响应时间指标。

从上图可以看出,该系统主要存在以下方面几个问题:

1、其中一个事务响应时间过长,超过1秒;

2、部分接口响应时间波动较大;

3、系统业务处理能力:即TPS,存在波动且起伏加大。

三、分析思路及解决方法

主要分析思路可以从以下几个方面考虑:

1、业务问题,系统代码本身业务逻辑问题,如:事务失败率;

2、系统服务器资源出现瓶颈导致,如:CPU、内存、I/O等;

3、数据库层面问题,如:慢查询;

4、java应用的堆内存相关;

5、受第三方系统的问题影响;

6、其它方面等等。

问题排查及解决

1、首先,controller中系统没有出现业务失败,查看日志,没有发现有错误日志,所以可以初步排查代码逻辑处理失败;

2、其次,先解决比较明显的问题,那个响应时间过长的接口,通常我们先想到的就是可能存在慢查询问题;

打开慢查询:

 mysql> show variables like "slow_query_log%";
+-----------------------------------+---------------------------------+
| Variable_name | Value |
+-----------------------------------+---------------------------------+
| slow_query_log | ON |
| slow_query_log_always_write_time | 10.000000 |
| slow_query_log_file | /disk1/mysql5.7.21/tmp/slow.log |//慢查询日志存放路径
| slow_query_log_use_global_control | |
+-----------------------------------+---------------------------------+
4 rows in set (0.00 sec)
//设置慢查询开关,0代表关闭慢查询,1代表打开慢查询。
mysql> set global slow_query_log = 1;
Query OK, 0 rows affected (0.00 sec)
//查看慢查询时间
mysql> show variables like "long_query%";
+-----------------+----------+
| Variable_name | Value |
+-----------------+----------+
| long_query_time | 2.000000 |
+-----------------+----------+
1 row in set (0.00 sec)
//设置慢查询为1秒
mysql> set long_query_time=1;
Query OK, 0 rows affected (0.00 sec) mysql>

通过查看慢查询日志,找到慢查询sql,如下:

  ①接下来,对找到的sql进行分析,查看sql执行计划:

如何查看执行计划:

 mysql> explain select * from test;
+----+-------------+-------+------------+-------+---------------+---------+---------+------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+-------+---------------+---------+---------+------+------+----------+-------------+
| 1 | SIMPLE | test | NULL | index | NULL | PRIMARY | 4 | NULL | 6 | 100.00 | Using index |
+----+-------------+-------+------------+-------+---------------+---------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec) mysql>

以下是本次发现慢查询sql的执行计划:

其中最重要的字段为:id、type、key、rows、Extra

1、id:select查询中的序列号,包含一组数字,表示查询中执行select字句或操作表的顺序;

2、type:访问类型,sql查询优化一个很重要的指标,结果值从好到坏依次是:

System>const>eq_ref>ref>fulltext>ref_or_null>index_merge>uniqe_subquery>index_subquery>range>index>ALL,一般来说,好的sql查询至少能达到range级,做好为ref。

3、Key:实际使用的索引,如果未NULL,则没有使用索引;

4、rows:根据表统计信息及索引选取情况,大致估算出找到所需的记录所需要的行数,一般该值越小越好;

5、Extra:不适合在其它字段中显示,但是十分重要的额外信息。

  从sql的执行计划明显可以看出,sql缺少相应的索引导致出现慢查询问题,与开发确认后,添加索引后,该接口的响应时间明显变快,以下为添加索引后的sql执行计划。

  ②也可以打开profile功能,对sql进行分析,看时间具体消耗在哪里

 mysql> show variables like "%profiling%";
+------------------------+-------+
| Variable_name | Value |
+------------------------+-------+
| have_profiling | YES |
| profiling | OFF |
| profiling_history_size | 15 |
+------------------------+-------+
3 rows in set (0.00 sec)
//设置profiling开关,1代表打开,0代表关闭
mysql> set profiling=1;
Query OK, 0 rows affected, 1 warning (0.00 sec)
//执行sql语句
mysql> select * from test;
+----+
| id |
+----+
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
| 6 |
| 10 |
+----+
7 rows in set (0.00 sec)
//查看profiles文件
mysql> show profiles;
+----------+------------+--------------------+
| Query_ID | Duration | Query |
+----------+------------+--------------------+
| 1 | 0.00037925 | select * from test |
+----------+------------+--------------------+
1 row in set, 1 warning (0.00 sec)
//查看profile文件中,第一个查询的profile情况,查看时间消耗在哪里
mysql> show profile for query 1;
+----------------------+----------+
| Status | Duration |
+----------------------+----------+
| starting | 0.000065 |//开始
| checking permissions | 0.000009 |//检查权限
| Opening tables | 0.000043 |//打开表
| init | 0.000027 |//初始化
| System lock | 0.000014 |//系统锁
| optimizing | 0.000004 |//优化
| statistics | 0.000016 |//统计
| preparing | 0.000011 |//准备
| executing | 0.000002 |//执行
| Sending data | 0.000113 |//发送数据
| end | 0.000004 |//结束
| query end | 0.000008 |//查询结束
| closing tables | 0.000008 |//关闭表/删除TEMP表
| freeing items | 0.000022 |//释放items
| cleaning up | 0.000037 |//清理
+----------------------+----------+
15 rows in set, 1 warning (0.00 sec)

  慢查询sql的profiling结果为:

优化后的sql  profiling结果:

优化后,单笔查询响应时间大大缩短,约为2毫秒

3、系统业务处理能力弱且TPS波动较大问题,可以先查看系统应用服务器或其它一些组件的CPU资源使用率及线程栈信息,看是否存在线程阻塞或死锁问题。

nmon查看CPU资源使用情况

vmstat -Sm 1--查看系统内存、cpu等资源使用情况

  CPU、内存资源消耗可以看出,一切都很很正常,通过jstack命令查看线程栈信息,也不存在线程阻塞及死锁问题,所以可以排除这方面的原因。

  因为系统TPS波动很大,我们可以看一下系统的GC情况。

  jstat -gcutil pid 1000

  

  发现FGC频繁,大约2秒一次,找到问题所在,接着看一下JVM的对内存分配情况

  jmap -heap pid

  

  解决方法:

  将JVM的启动参数设置为:-Xms4096M -Xmx4096M,重启系统,在同样的压力下,进行测试,得到优化后的测试结果为:

  TPS截图:

  

  RT截图:

  

  

  优化后,系统性能表现明显提升,TPS可以达到3000笔/秒,系统响应时间约为100毫秒,完成满足系统上线要求。

【性能调优】一次关于慢查询及FGC频繁的调优经历的更多相关文章

  1. SQL Server调优系列进阶篇(查询语句运行几个指标值监测)

    前言 上一篇我们分析了查询优化器的工作方式,其中包括:查询优化器的详细运行步骤.筛选条件分析.索引项优化等信息. 本篇我们分析在我们运行的过程中几个关键指标值的检测. 通过这些指标值来分析语句的运行问 ...

  2. SQL Server调优系列基础篇 - 子查询运算总结

    前言 前面我们的几篇文章介绍了一系列关于运算符的介绍,以及各个运算符的优化方式和技巧.其中涵盖:查看执行计划的方式.几种数据集常用的连接方式.联合运算符方式.并行运算符等一系列的我们常见的运算符.有兴 ...

  3. SQL Server 调优系列基础篇 - 子查询运算总结

    前言 前面我们的几篇文章介绍了一系列关于运算符的介绍,以及各个运算符的优化方式和技巧.其中涵盖:查看执行计划的方式.几种数据集常用的连接方式.联合运算符方式.并行运算符等一系列的我们常见的运算符.有兴 ...

  4. cassandra mongodb选择——cassandra:分布式扩展好,写性能强,以及可以预料的查询;mongodb:非事务,支持复杂查询,但是不适合报表

    Of course, like any technology MongoDB has its strengths and weaknesses. MongoDB is designed for OLT ...

  5. MYSQL数据库性能调优之四:解决慢查询--索引

    为什么索引能够提高查询速度?没有索引 检索数据的方式是从头到尾一条一条挨着匹配,这是慢的根本原因:索引类型BTREE:二叉树类型,原理图如下:对表创建一个二叉树,记录中间数据的物理磁盘地址,二叉树检索 ...

  6. sql server 性能调优之 SQL语句阻塞查询

    在生产环境下,有时公司客服反映网页半天打不到,除了在浏览器按F12的Network响应来排查,确定web服务器无故障后.就需要检查数据库是否有出现阻塞 当时数据库的生产环境中主表数据量超过2000w, ...

  7. MYSQL数据库性能调优之五:解决慢查询--存储引擎与数据类型

    3.数据类型的影响 4.存储引擎的影响 看你的mysql现在已提供什么存储引擎:mysql> show engines; 看你的mysql当前默认的存储引擎:mysql> show var ...

  8. MySQL调优三步曲(慢查询、explain profile)

    在做性能测试中经常会遇到一些sql的问题,其实做性能测试这几年遇到问题最多还是数据库这块,要么就是IO高要么就是cpu高,所以对数据的优化在性能测试过程中占据着很重要的地方,下面我就介绍一些msyql ...

  9. JVM调优(一)——参数查询和问题排查

    JVM的参数类型 标准参数 -help -server -client -version -showversion -cp -classpath X参数 -Xint: 解释执行 -Xcomp:第一次使 ...

随机推荐

  1. 【洛谷P2216】[HAOI2007]理想的正方形

    理想的正方形 [题目描述] 一个a*b的矩阵,从中取一个n*n的子矩阵,使所选矩阵中的最大数与最小数的差最小. 思路: 二维的滑动窗口 对于每行:用一个单调队列维护,算出每个长度为n的区间的最大值和最 ...

  2. POJ 3666 Making the Grade(数列变成非降序/非升序数组的最小代价,dp)

    传送门: http://poj.org/problem?id=3666 Making the Grade Time Limit: 1000MS   Memory Limit: 65536K Total ...

  3. input按钮选择功能

    <p> <input type="checkbox" class="ischecked" id="is_pinkage" ...

  4. 将某页面中ajax中获取到的信息放置到sessionStorage中保存,并在其他页面调用这些数据。

    A页面代码: var obj = data.data; var infostr = JSON.stringify(obj);//转换json sessionStorage.obj = infostr; ...

  5. springboot jar 部署到linux之后 获取类资源文件问题-- 仅限linux 下 情况比较特殊 需要获取打到jar内的 讲台资源 只能通过流获取,根据路径获取不到指定文件 nullpointExption

    https://blog.csdn.net/qq_27000425/article/details/72897282 ClassPathResource类,如果没有指定相对的类名,该类将从类的根路径开 ...

  6. Oracle客户端与Toad、plsql developer安装

    (一)oracle client与oracle instant client比较 当我们要使用Toad.plsql developer等工具连接数据库时,首先需要在自己的电脑上安装oracle cli ...

  7. 开发一个c#的数据库连接池

    c#操作数据库是一个经典,用习惯了以后真感觉不错,很简单的.现在很多关系数据库都支持c#.c#的ADO.NET规范都遵守. 对于一般的设置,ADO.NET都放在数据库连接字符串上.比如池化,连接超时等 ...

  8. 修改zabbix字体格式

    环境: centos7 zabbix3.2 1.获取喜欢的字体格式文件(喜欢别的字体也可以去网上下载) 通常都是ttf格式,可直接在windows下获取C:\Windows\Fonts 2.配置zab ...

  9. oracle的事务隔离级别和读一致性

    oracle提供了三个隔离级别: 1.读提交 ,简而言之只能读取语句开始执行前提交的数据 2.串行,这个好理解,就是事务串行运行,避免经典的三个场景-脏读.不可重复读.幻读. 3.只读,oracle已 ...

  10. Python基本图形绘制

    turtle的一个画布空间最小单位是像素 turtle的绘制窗体:turtle.stup(width,heigth,startx,starty) 四个参数中后两个可选 turtle空间坐标体系:tur ...