前段时间搞优化,最后瓶颈发现都在数据库单点上。 问DBA,给我的写入答案是在1W(机械硬盘)左右。
联想起前几天infoQ上一篇文章说他们最好的硬件写入速度在2W后也无法提高(SSD硬盘)
但这东西感觉从来没证实过,故一时兴起,弄台虚拟机压测起来。
想搞清下面的问题:
1,mysql支撑多少连接数?
2,写入瓶颈到底是多少?
3,求QPS
畅想:
足够的CPU, load>远小于核数*2
足够的内存, 基本只用到物理内存
瓶颈在硬盘,写入速度应该能到90-100M/S(机械硬盘,7200转)。 故:预计kB_wrtn/s在90M左右
准备阶段:
硬件:
压测机I5双核,8G内存, 开一个虚拟机+mysql,一个eclipse,一个jmeter
MYSQL准备
mysql基本命令
停止:
root@ubuntu:/home/hejinbin# /etc/init.d/mysql stop
Stopping mysql (via systemctl): mysql.service.
启动:
root@ubuntu:/home/hejinbin# /etc/init.d/mysql start
Starting mysql (via systemctl): mysql.service.
重启:
/etc/init.d/mysql restart 重启mysql
查看当前mysq端口的连接数
netstat -apn|grep "3306"
查看mysql基本状态
show processlist; 查看当前连接
show status; 查看当前数据库状态
show variables like 'max_connections' mysql当前最大连接数
set global max_connections=1000; 设置当前最大连接数为1000
这个设置会马上生效,但是当mysql重启时这个设置会失效,需要长期生效在my.ini 添加 max_connections=1000
jmeter准备:
1,测试空压测, 测试压测客户端能承受的线程数,
只开聚合报告,其它图形和结果树输出关闭。
经过测试,打开监视器图形结果和结果树输出,本机空压测也只能到1500附近,所以特别注意关闭这两个,只开聚合报告,我的机器100个线程空压测可以到压测到6W吞吐量(throughput/sec)
后面也用100个线程进行mysql的插入压测
JAVA测试类准备
用C3P0进行压测:
C3P0:
1, 在classpath下放入 c3p0-config.xml 配置如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
root
hejinbin
com.mysql.jdbc.Driver
jdbc:mysql://172.25.20.14:3306/Test?useUnicode=true
5
5
150
5
2,JAVA测试代码
1 package org.test;
2
3 import java.sql.Connection;
4 import java.sql.ResultSet;
5 import java.util.concurrent.atomic.AtomicLong;
6
7 import com.mchange.v2.c3p0.ComboPooledDataSource;
8 import com.mchange.v2.c3p0.impl.NewProxyPreparedStatement;
9
10 /**
11 * hejinbin , QQ 107966750, C3P0的测试用例 2016-10-13
12 */
13 public class C3P0Test {
14 public static AtomicLong id = new AtomicLong(1000000);
15 private static ComboPooledDataSource cpds = new ComboPooledDataSource();
16
17 public static Long queryTest() throws Exception {
18 Long aid = null;
19 Connection con = null;
20 try {
21 // 从C3P0获取连接
22 con = cpds.getConnection();
23 NewProxyPreparedStatement prepare = (NewProxyPreparedStatement) con
24 .prepareStatement("select * from tbl_account_info where account_id = ?");
25 prepare.setLong(1, 1001203);
26 ResultSet result = prepare.executeQuery();
27 if (result.next()) {
28 aid = (result.getLong("aid"));
29 }
30 } catch (Exception e) {
31 throw e;
32 } finally {
33 // 此处关闭已经被C3P0重写, 只是返还连接池
34 con.close();
35 }
36
37 return aid;
38 }
39
40 public static void insertTest() throws Exception {
41
42 Connection con = null;
43 try {
44 // 从C3P0获取连接
45 con = cpds.getConnection();
46 NewProxyPreparedStatement prepare = (NewProxyPreparedStatement) con.prepareStatement(
47 "INSERT INTO `tbl_account_info` VALUES (?, '1231232132', '何锦彬测试', '12312312', '15018711111', '[email protected]', '1', 'hjb_recharge', 'yyUid:12312312', '1', '', '', '', '1399882974', '1429785062', '183.60.177.229', '1464658277', '14.29.83.74', '0', '0', '1', '0', '2', '1', '0', '1', '1', '1', '1', '1', '1', '1', '', '', '2000', '0', '0', '0', '2000', '6', '0', '0', '1', '0', '1456308697', '658', null, '广东广州', '0', '0', '0', '0', '20', null, null, '1', null, '');");
48 prepare.setLong(1, id.incrementAndGet());
49 prepare.execute();
50 } catch (Exception e) {
51 throw e;
52 } finally {
53 // 此处关闭已经被C3P0重写, 只是返还连接池
54
55 con.close();
56 }
57
58 }
59
60 public static void main(String[] args) throws Exception {
61 for (int i = 0; i < 100000; i++)
62 insertTest();
63 }
64 }
3,jmeter压测相关代码
package org.test.bin;
import org.apache.jmeter.config.Arguments;
import org.apache.jmeter.protocol.java.sampler.AbstractJavaSamplerClient;
import org.apache.jmeter.protocol.java.sampler.JavaSamplerContext;
import org.apache.jmeter.samplers.SampleResult;
import org.test.C3P0Test;
import org.test.JDBCWthoutDBPoolTest;
/**
* hejinbin , QQ 107966750, C3P0的测试用例,放入jmeter中 2016-10-13
*/
public class JDBWithC3P0JmertRuning extends AbstractJavaSamplerClient {
// 填参数
public Arguments getDefaultParameters() {
Arguments params = new Arguments();
return params;
}
// 测试查询
// public SampleResult runTest(JavaSamplerContext arg0) {
// SampleResult sr = new SampleResult();
// try {
// sr.sampleStart();
// Long aid = C3P0Test.queryTest();
// // Long aid = 741l;
// // 逾期值
// if (aid == 741) {
// // 只有是预期值才判断查询成功
// sr.setSuccessful(true);
// } else {
// sr.setSuccessful(false);
// }
// } catch (Exception e) {
// sr.setSuccessful(false);
// e.printStackTrace();
// } finally {
// sr.sampleEnd();
// }
// return sr;
// }
public SampleResult runTest(JavaSamplerContext arg0) {
SampleResult sr = new SampleResult();
try {
sr.sampleStart();
C3P0Test.insertTest();
// 只有是预期值才判断查询成功
sr.setSuccessful(true);
} catch (Exception e) {
sr.setSuccessful(false);
e.printStackTrace();
} finally {
sr.sampleEnd();
}
return sr;
}
}
整个工程地址 https://github.com/bensonHe/Test4DBInsert
一切就绪, 开始死磕
第一次压测配置(虚拟机):
数据库服务器:1G内存+20G硬盘+1个CPU,单核
jmeter本地
压测结果
3100 左右
负载在6.77附近,判断是CPU问题,加4核
第二次压测配置(虚拟机):
1G内存+20G硬盘+1个CPU,4核
直接到了5700附近,
total used free shared buffers cached
Mem: 984 974 9 1 132 455
-/+ buffers/cache: 386 597
Swap: 2044 31 2013
只有9M剩余,预测增加物理内存可以继续提高
第三次发现物理内存使用
4G内存+20G硬盘+1个CPU,4核
直接压测到了 7500附近,IOWA% 在10附近,使用CPU 30%
此时服务器状态, 9的WA
top - 00:55:47 up 15 min, 1 user, load average: 7.63, 2.61, 1.09
Tasks: 175 total, 1 running, 174 sleeping, 0 stopped, 0 zombie
%Cpu(s): 15.1 us, 40.6 sy, 0.0 ni, 28.3 id, 9.0 wa, 0.0 hi, 7.0 si, 0.0 st
KiB Mem: 4038340 total, 1837716 used, 2200624 free, 151648 buffers
KiB Swap: 2094076 total, 0 used, 2094076 free. 1224640 cached Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
2345 mysql 20 0 2539240 274992 13540 S 279.5 6.8 4:48.13 mysqld
机器信息:
top - 01:02:07 up 21 min, 1 user, load average: 6.48, 6.91, 3.77
Tasks: 175 total, 1 running, 174 sleeping, 0 stopped, 0 zombie
%Cpu(s): 14.2 us, 33.2 sy, 0.0 ni, 35.0 id, 11.3 wa, 0.0 hi, 6.3 si, 0.0 st
KiB Mem: 4038340 total, 2605868 used, 1432472 free, 152740 buffers
KiB Swap: 2094076 total, 0 used, 2094076 free. 1965808 cached Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
2345 mysql 20 0 2540260 278508 13540 S 247.7 6.9 21:44.32 mysqld
CPU 4核, 负载 6.48, 没到瓶颈
内存, swap使用率是0, 也没压力
硬盘,
通过监控发现
Device: tps kB_read/s kB_wrtn/s kB_read kB_wrtn
sda 688.00 0.00 17356.00 0 17356
硬盘写入速度在 17M/s, 感觉还没到瓶颈, 7200转机械硬盘的是 90M
如何进一步优化,让写入速度达到瓶颈。 想到是配置mysql的参数了,下次继续尝试,有活要做了.
`不知道咋转图,