MyCat - 测试篇
2016-03-06 15:16
288 查看
数据库路由中间件MyCat - 测试篇
测试背景
为了检测MyCat性能表现以及架构扩展性,设计测试。首先需要编写压力测试代码,程序基于Jmeter,并且封装了JDBC,模拟涅槃项目实际应用的连接方式。测试程序生成基于当前系统时间的随机数,并且保证这个随机数一秒内重复概率为百万分之一。
程序请求必须保证每个分片的请求量是一样的.
测试脚本举例:
package com.sf.hash.drm; 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 java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.sql.Statement; import java.util.concurrent.ThreadLocalRandom; public class DRMTest2 extends AbstractJavaSamplerClient{ private String JDBC_DRIVER; private String DB_URL; private String USER; private String PASSWORD; private static ThreadLocal <Connection> conn = new ThreadLocal<Connection>(); private static ThreadLocal<Statement> stmt = new ThreadLocal<Statement>(); private String testStr; private int aa=0; private int count=0; //初始化方法,实际运行时每个线程仅执行一次,在测试方法运行前执行,类似于LoadRunner中的init方法 public void setupTest(JavaSamplerContext arg0) { JDBC_DRIVER = arg0.getParameter("JDBC_DRIVER", ""); USER = arg0.getParameter("USER", ""); PASSWORD = arg0.getParameter("PASSWORD", ""); DB_URL = arg0.getParameter("DB_URL",""); aa = Integer.parseInt(arg0.getParameter("ID","")); try { Class.forName(JDBC_DRIVER); conn.set(DriverManager.getConnection(arg0.getParameter("DB_URL",""), arg0.getParameter("USER", ""), arg0.getParameter("PASSWORD", ""))); stmt.set(conn.get().createStatement()); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } System.out.println(Thread.currentThread()+" start!"); } //设置传入的参数,可以设置多个,已设置的参数会显示到Jmeter的参数列表中 public Arguments getDefaultParameters() { Arguments params = new Arguments(); params.addArgument("JDBC_DRIVER", "com.mysql.jdbc.Driver"); //定义一个参数,显示到Jmeter的参数列表中,第一个参数为参数默认的显示名称,第二个参数为默认值 params.addArgument("DB_URL", "jdbc:mysql://10.202.44.205:8666/test"); params.addArgument("USER", "test"); params.addArgument("PASSWORD", "test"); params.addArgument("ID", "0"); return params; } //测试执行的循环体,根据线程数和循环次数的不同可执行多次,类似于LoadRunner中的Action方法 public SampleResult runTest(JavaSamplerContext arg0) { SampleResult results = new SampleResult(); long currentTime = System.nanoTime(); int key = ThreadLocalRandom.current().nextInt(0,100000000); long id = currentTime*4 + key*4 + (aa); String sql = "INSERT INTO proxyha(id,name,age) VALUES (" + (id) + ", '"+aa+"', 18)"; // String sql2 = "UPDATE proxyha set age ='" + // (id) + // "'where name ='"+Thread.currentThread()+aa+"'"; int a = 0; try { results.sampleStart(); a = stmt.get().executeUpdate(sql); // a = stmt.get().executeUpdate(sql2); results.sampleEnd(); } catch (SQLException e) { e.printStackTrace(); int count = 0; //重试 while(!reconnect(arg0)) { count++; if(count>100) { System.out.print(0); break; } } } if(a <= 0){ results.setSuccessful(false); //用于设置运行结果的成功或失败,如果是"false"则表示结果失败,否则则表示成功 }else results.setSuccessful(true); return results; } private boolean reconnect(JavaSamplerContext arg0){ try { stmt.get().close(); conn.get().close(); conn.set(DriverManager.getConnection(arg0.getParameter("DB_URL",""), arg0.getParameter("USER", ""), arg0.getParameter("PASSWORD", ""))); stmt.set(conn.get().createStatement()); aa++; } catch (SQLException e) { return false; } return true; } //结束方法,实际运行时每个线程仅执行一次,在测试方法运行结束后执行,类似于LoadRunner中的end方法 public void teardownTest(JavaSamplerContext arg0) { System.out.println(Thread.currentThread()+" end!"); } }
测试场景
- 数据库能力测试,用压测程序直接压测每一个库,为了看数据库能力是否一致。
- 压测程序能力测试,用n个压测程序压测m个数据库,为了看压测程序是否存在性能瓶颈。
- MyCat能力测试,用n个压测程序压测o个MyCat实例后台连接着同样的m个数据库节点。
- MyCat故障边界测试:
单节点缓慢 - 单节点down机(对于全局表的dml都会失效)
- 分片表单节点锁定
- 分片表索引摘除测试update影响
测试环境
测试结果
1. 数据库能力测试
排除db1m-db4m(因为性能差太多)的问题,之后db1m-db4m与其他12个数据库的性能差不多了。
2. 压测程序能力测试
3. MyCat能力测试
测试证明,MyCat的TPS可以随着测试脚本与实例数量还有DB节点的数量增加而增加
4. MyCat故障边界测试
4.1 单节点缓慢
使用cpulimit命令限制某个DB节点的cpu使用率,原本不限制可以用到1500%, 分别限制到1000%,500%,100%;
4.2 单节点宕机
让MyCat的16个节点其中一个节点在运行脚本过程中宕机
4.3 分片表单节点锁定
运行脚本,让MyCat的16个节点其中一个节点在运行脚本过程中做在线的ddl
运行脚本,让MyCat的16个节点其中一个节点在运行脚本过程中全表锁定
4.3 分片表索引摘除测试update影响
修改脚本(从insert改成以主键查找update)。运行脚本,让MyCat的16个节点其中一个节点在运行脚本过程中删除主键索引(表是以主键作为分片id)
修改脚本(从insert改成以非主键(unique字段)查找update)。运行脚本,让MyCat的16个节点其中一个节点在运行脚本过程中删除非主键(unique)索引(表是以主键作为分片id)
测试结论
根据上面测试结果,在物理环境正常的情况下,TPS是可以随着MyCat实例个数与后台db个数增加而增加的。
以下故障边界都有个前提条件:请求是均匀分布在每个后台db节点上的。
- MyCat性能不受限于最慢的分片主机,分片主机缓慢只是单点影响,不会影响全局
- 单节点宕机不会影响只发到其他节点的命令,但是只要涉及到这个节点的命令(比如select * from table range(0,1000))都不能正常执行
- 分片表单节点锁定对于MyCat性能影响不大。
- 分片表分片字段索引丢失如果按照分片字段查找更新的话,影响不大。但是如果非分片字段索引丢失如果按照那个字段查找更新的话,由于请求会发到每个节点,那么每个请求都会全量搜索,对于性能影响很大。
相关文章推荐
- mycat E-R关系分片策略测试
- MyCat - 测试篇
- 测试国内开源数据库中间件Mycat和Atlas体会
- MyCat - 测试篇
- 数据库中间件mycat测试之一
- Mycat对MongoDB分表后Navicat访问测试问题
- mycat实战之性能测试
- Mycat安装以及使用测试
- mycat学习-3-测试jdbc连接下,mysql和mycat的吞吐性能
- SQL92标准语句Mycat支持测试 (基于Oracle和MySQL数据库)与下载地址
- mycat 1.6 配置【仅学习测试配置使用】
- 基于Docker搭建MySQL(MariaDB)+ mycat读写分离测试环境
- mysql+mycat压力测试一例【转】
- mysql+mycat压力测试一例
- Jmeter测试mysql数据库中间件mycat
- Mycat源码修改分表规则的CRUD操作测试与改进
- Mycat的简易安装及测试
- mycat部署测试
- mycat分片表全局自增主键测试
- MyCAT-1.4-RC性能测试(初步施工)