场景:Mysql的简略QPS测试(单机)

Mysql的简单QPS测试(单机)

MySQL官方网站下载:

1、MySQL-server-5.5.28-1.rhel4.i386.rpm

2、java驱动 mysql-connector-java-5.1.5-bin.jar

测试服务器为Dell  E5410 的Debian linux 2.6,配置为:

1、4核,2.33GHz

2、内存3G

3、SATA硬盘2T

web服务器:tomcat5.5

打压工具:Apache Bench

监控工具:mysqladmin

测试思路:

1、使用自定义数据库连接池,最大连接数500;

2、每个请求做1000次插入;

自定义连接池代码:DBConnectionManager

public class DBConnectionManager {

static private DBConnectionManager instance; // 唯一实例

static private int clients;

private Vector drivers = new Vector();

private PrintWriter log;

private Hashtable pools = new Hashtable();

/**

* 返回唯一实例.如果是第一次调用此方法,则创建实例

*

* @return DBConnectionManager 唯一实例

*/

static synchronized public DBConnectionManager getInstance() {

if (instance == null) {

instance = new DBConnectionManager();

}

clients++;

return instance;

}

/**

* 建构函数私有以防止其它对象创建本类实例

*/

private DBConnectionManager() {

init();

}

/**

* 将连接对象返回给由名字指定的连接池

*

* @param name

* 在属性文件中定义的连接池名字

* @param con

* 连接对象

*/

public void freeConnection(String name, Connection con) {

DBConnectionPool pool = (DBConnectionPool) pools.get(name);

if (pool != null) {

pool.freeConnection(con);

}

}

/**

* 获得一个可用的(空闲的)连接.如果没有可用连接,且已有连接数小于最大连接数 限制,则创建并返回新连接

*

* @param name

* 在属性文件中定义的连接池名字

* @return Connection 可用连接或null

*/

public Connection getConnection(String name) {

DBConnectionPool pool = (DBConnectionPool) pools.get(name);

if (pool != null) {

return pool.getConnection();

}

return null;

}

/**

* 关闭所有连接,撤销驱动程序的注册

*/

public synchronized void release() {

// 等待直到最后一个客户程序调用

if (--clients != 0) {

return;

}

Enumeration allPools = pools.elements();

while (allPools.hasMoreElements()) {

DBConnectionPool pool = (DBConnectionPool) allPools.nextElement();

pool.release();

}

Enumeration allDrivers = drivers.elements();

while (allDrivers.hasMoreElements()) {

Driver driver = (Driver) allDrivers.nextElement();

try {

DriverManager.deregisterDriver(driver);

log("撤销JDBC驱动程序 " + driver.getClass().getName() + "的注册");

} catch (SQLException e) {

log(e, "无法撤销下列JDBC驱动程序的注册: " + driver.getClass().getName());

}

}

}

/**

* 根据指定属性创建连接池实例.

*

* @param props

* 连接池属性

*/

private void createPools(Properties props) {

Enumeration propNames = props.propertyNames();

while (propNames.hasMoreElements()) {

String name = (String) propNames.nextElement();

if (name.endsWith(".url")) {

String poolName = name.substring(0, name.lastIndexOf("."));

String url = props.getProperty(poolName + ".url");

if (url == null) {

log("没有为连接池" + poolName + "指定URL");

continue;

}

String user = props.getProperty(poolName + ".user");

String password = props.getProperty(poolName + ".password");

String maxconn = props.getProperty(poolName + ".maxconn", "0");

int max;

try {

max = Integer.valueOf(maxconn).intValue();

} catch (Exception e) {

log("错误的最大连接数限制: " + maxconn + " .连接池: " + poolName);

max = 0;

}

DBConnectionPool pool = new DBConnectionPool(poolName, url,

user, password, max);

pools.put(poolName, pool);

log("成功创建连接池" + poolName);

}

}

}

/**

* 读取属性完成初始化

*/

private void init() {

InputStream is = getClass().getResourceAsStream("/db.properties");

Properties dbProps = new Properties();

try {

dbProps.load(is);

} catch (Exception e) {

System.err.println("不能读取属性文件. "

+ "请确保db.properties在CLASSPATH指定的路径中");

return;

}

String logFile = dbProps.getProperty("logfile",

"DBConnectionManager.log");

try {

log = new PrintWriter(new FileWriter(logFile, true), true);

} catch (IOException e) {

System.err.println("无法打开日志文件: " + logFile);

log = new PrintWriter(System.err);

}

loadDrivers(dbProps);

createPools(dbProps);

}

private void loadDrivers(Properties props) {

String driverClasses = props.getProperty("drivers");

StringTokenizer st = new StringTokenizer(driverClasses);

while (st.hasMoreElements()) {

String driverClassName = st.nextToken().trim();

try {

Driver driver = (Driver) Class.forName(driverClassName)

.newInstance();

DriverManager.registerDriver(driver);

drivers.addElement(driver);

log("成功注册JDBC驱动程序" + driverClassName);

} catch (Exception e) {

log("无法注册JDBC驱动程序: " + driverClassName + ", 错误: " + e);

}

}

}

/**

* 将文本信息写入日志文件

*/

private void log(String msg) {

log.println(new Date() + ": " + msg);

}

/**

* 将文本信息与异常写入日志文件

*/

private void log(Throwable e, String msg) {

log.println(new Date() + ": " + msg);

e.printStackTrace(log);

}

/**

* 此内部类定义了一个连接池.它能够根据要求创建新连接,直到预定的最 大连接数为止.在返回连接给客户程序之前,它能够验证连接的有效性.

*/

class DBConnectionPool {

private int checkedOut;

private Vector freeConnections = new Vector();

private int maxConn;

private String name;

private String password;

private String URL;

private String user;

public DBConnectionPool(String name, String URL, String user,

String password, int maxConn) {

this.name = name;

this.URL = URL;

this.user = user;

this.password = password;

this.maxConn = maxConn;

}

/**

* 将不再使用的连接返回给连接池

*

* @param con

* 客户程序释放的连接

*/

public synchronized void freeConnection(Connection con) {

// 将指定连接加入到向量末尾

freeConnections.addElement(con);

checkedOut--;

notifyAll();

}

/**

* 从连接池获得一个可用连接.如没有空闲的连接且当前连接数小于最大连接 数限制,则创建新连接.如原来登记为可用的连接不再有效,则从向量删除之,

* 然后递归调用自己以尝试新的可用连接.

*/

public synchronized Connection getConnection() {

Connection con = null;

if (freeConnections.size() > 0) {

// 获取向量中第一个可用连接

con = (Connection) freeConnections.firstElement();

freeConnections.removeElementAt(0);

try {

if (con.isClosed()) {

log("从连接池" + name + "删除一个无效连接");

// 递归调用自己,尝试再次获取可用连接

con = getConnection();

}

} catch (SQLException e) {

log("从连接池" + name + "删除一个无效连接");

// 递归调用自己,尝试再次获取可用连接

con = getConnection();

}

} else if (maxConn == 0 || checkedOut < maxConn) {

con = newConnection();

}

if (con != null) {

checkedOut++;

}

return con;

}

/**

* 关闭所有连接

*/

public synchronized void release() {

Enumeration allConnections = freeConnections.elements();

while (allConnections.hasMoreElements()) {

Connection con = (Connection) allConnections.nextElement();

try {

con.close();

log("关闭连接池" + name + "中的一个连接");

} catch (SQLException e) {

log(e, "无法关闭连接池" + name + "中的连接");

}

}

freeConnections.removeAllElements();

}

/**

* 创建新的连接

*/

private Connection newConnection() {

Connection con = null;

try {

if (user == null) {

con = DriverManager.getConnection(URL);

} else {

con = DriverManager.getConnection(URL, user, password);

}

log("连接池" + name + "创建一个新的连接");

} catch (SQLException e) {

log(e, "无法创建下列URL的连接: " + URL);

return null;

}

return con;

}

}

}

测试代码 InsertMysqlServlet:

public class InsertMysqlServlet extends HttpServlet {

public void doGet(HttpServletRequest req, HttpServletResponse resp)

throws ServletException, IOException {

Integer insertNum = Integer.valueOf(req.getParameter("insertNum")

.toString());

resp.setContentType("text/html;charset=UTF-8");

resp.setHeader("Cache-Control", "no-cache");

String INSERT_SQL = "INSERT INTO test (id,name) values(10000,'This is for Mysql insert.')";

PreparedStatement pstmt = null;

DBConnectionManager m = DBConnectionManager.getInstance();

Connection conn = null;

try {

conn = m.getConnection("devel");

System.out.println(conn);

pstmt = conn.prepareStatement(INSERT_SQL);

for (int i = 0; i < insertNum; i++) {

pstmt.addBatch();

}

pstmt.executeBatch();

pstmt.close();

resp.getWriter().write(conn + ": Insert Mysql successed!");

} catch (Exception e) {

e.printStackTrace();

} finally {

m.freeConnection("devel", conn);

}

}

public void doPost(HttpServletRequest req, HttpServletResponse resp)

throws ServletException, IOException {

}

}

开始压力测试,开400个线程并发,共插入100万条记录:

/usr/sbin/ab -n 1000 -c 400 http://192.168.175.130:8080/labWeb/insertMysql.do?insertNum=1000

监控: /usr/bin/mysqladmin -uroot -proot extended-status -r -i1|grep -i Com_insert

可以看到400个并发、4核2.33G、3G内存、SATA硬盘的情况下,插入100万记录的QPS在8400左右。

mysql单机qps能到多少,mysql 单机 qps相关推荐

  1. 6、单机运行环境搭建之 --CentOS-6.4安装MySQL 5.6.10并修改MySQL的root用户密码

    Mysql 5.5以后使用了CMake进行安装,参考与以前的区别请参考: http://www.blogjava.net/kelly859/archive/2012/09/04/387005.html ...

  2. 单机运行环境搭建之 --CentOS-6.4安装MySQL 5.6.10并修改MySQL的root用户密码

    来源:http://www.cnblogs.com/littlehb/archive/2013/04/02/2995007.html Mysql 5.5以后使用了CMake进行安装,参考与以前的区别请 ...

  3. mysql 单机双实列_{ mysql } MySQL单机多实例及主从复制

    没有过多的,直接上码 my.cnf [mysql_multi] mysqld = /usr/bin/mysqld_safe mysqladmin = /usr/bin/mysqladmin user ...

  4. linux下mysql单机主从配置,Linux下MySQL互为主从配置

    Linux系统环境:CentOS 6.5 master1:192.168.100.204 master2:192.168.100.205 mysql版本:mysql-5.6.19 注:mysql的5. ...

  5. mysql qps如何查看_mysql状态查看 QPS/TPS/缓存命中率查看

    运行中的mysql状态查看 对正在运行的mysql进行监控,其中一个方式就是查看mysql运行状态. (1)QPS(每秒Query量) QPS = Questions(or Queries) / up ...

  6. MYSQL专题-使用Binlog日志恢复MySQL数据

    大家有没有碰到过由于误操作把测试数据库的一张表给删除了,导致测试的数据都被删除了,然后手足无措,测试把你一定数落,顿时感觉自己要死了?今天就教你即使误删了也可以将删除的数据恢复,以后误删再也不用惊吓了 ...

  7. mysql运维机制_《MySQL运维内参》节选 | InnoDB日志管理机制(一)

    引 子 InnoDB 存储引擎是支持事务ACID特性的,它是以二十多年前IBM的一篇著名文章<ARIES:A Transaction Recovery Method Supporting Fin ...

  8. mysql安装原理_全面解读MySQL主从复制,从原理到安装配置

    为什么需要主从复制? 1.在业务复杂的系统中,有这么一个情景,有一句sql语句需要锁表,导致暂时不能使用读的服务,那么就很影响运行中的业务,使用主从复制,让主库负责写,从库负责读,这样,即使主库出现了 ...

  9. mysql status questions_运行中的mysql状态查看

    运行中的mysql状态查看 对正在运行的mysql进行监控,其中一个方式就是查看mysql运行状态. (1)QPS(每秒Query量) QPS = Questions(or Queries) / se ...

  10. mysql数据库不小于_小于mysql

    mysql启用hugepage 1 hugepage在linux 2.6以后的内核才支持,mysql中只有innodb引擎才支持,hugepage作用: 1.减少内存置换 2.减少TLB miss次数 ...

最新文章

  1. Go 分布式学习利器(5)-- 数组和切片
  2. 聊聊flink JobManager的heap大小设置
  3. sqlserver 分页_四类数据库分页实现方案总结之PG分页实现
  4. objective-c 编写规范_Objective-c成员变量的定义方式?如何写才规范?
  5. 推荐一个在线创作流程图、思维导图软件—ProcessOn
  6. Uim的情人节礼物·其之弐(洛谷-P2524)
  7. 【转载】Python线程、进程和协程详解
  8. linux下静态链接库和动态链接库
  9. Oracle下的用户创建角色、授权、建立表空间
  10. python turtle画阴阳_Python turtle绘制阴阳太极图代码解析
  11. docker 学习之使用dockerfile 创建镜像遇到的坑
  12. 2019FME博客大赛——基于FME的武汉市航班数据获取及城市联系度分析
  13. 【金猿案例展】某新型股份制商业银行——客服智能质检系统建设
  14. 八段数码管数字显示实验c语言,实验报告__实验七_八段数码管显示实验
  15. Java中boolean类型占几个字节,你知道吗?
  16. html的li标签结合layui实现滚动列表
  17. 王阳明《心学》小总结
  18. [osg]OSG中的颜色数组,法向数组
  19. c语言数星星结构体,1469: 数星星(结构体专题)
  20. linux下使用命令行辅助定位内存泄漏问题

热门文章

  1. 标准通用个人简历表-Word简历可编辑下载
  2. Mock框架的三次迭代,让你的单元测试更高效
  3. 3.5 毫米耳机插座插头的结构和接线方式
  4. 13、Swin Transformer: Hierarchical Vision Transformer using Shifted Windows
  5. 英语简明语法系列之---代词(-)
  6. linpus linux 换win7,联想 lenovoIdeaPad可以装windows7系统吗_联想 lenovoIdeaPad怎么安装win7系统-win7之家...
  7. (程序员情感三部曲之三)程序员与女朋友相处之道
  8. capped collection
  9. 只为记录生活和工作的点滴
  10. 1.itoa()函数