Mycat对于导入和扩容迁移性能压测

1.      测试环境

1.1.    硬件环境

机器ip

OS

CPU

CPU Processors

内存

172.16.54.135

CentOS Linux release 7.1.1503

Intel(R) Xeon(R) CPU E5-2620 v2 @ 2.10GHz

24

64G

172.16.54.136

CentOS Linux release 7.1.1503

Intel(R) Xeon(R) CPU E5-2620 v2 @ 2.10GHz

24

64G

172.16.54.138

CentOS Linux release 7.1.1503

Intel(R) Xeon(R) CPU E5-2620 v2 @ 2.10GHz

24

64G

1.2.    软件环境

软件名称

版本

Jdk

1.8.0_45

Mycat

1.4.1

Mysql

5.6

PostgreSQL

9.2.14

2.      对于Mysql压测

2.1.    基本配置

  • wrapper.conf

# Java AdditionalParameters
#wrapper.java.additional.1=
wrapper.java.additional.1=-DMYCAT_HOME=.
wrapper.java.additional.2=-server
wrapper.java.additional.3=-XX:MaxPermSize=64M
wrapper.java.additional.4=-XX:+AggressiveOpts
wrapper.java.additional.5=-XX:MaxDirectMemorySize=5G
wrapper.java.additional.6=-Dcom.sun.management.jmxremote
wrapper.java.additional.7=-Dcom.sun.management.jmxremote.port=1984
wrapper.java.additional.8=-Dcom.sun.management.jmxremote.authenticate=false
wrapper.java.additional.9=-Dcom.sun.management.jmxremote.ssl=false
# Initial JavaHeap Size (in MB)
#wrapper.java.initmemory=3
wrapper.java.initmemory=3072
# Maximum JavaHeap Size (in MB)
#wrapper.java.maxmemory=64
wrapper.java.maxmemory=3072
  • schema.xml

<schemaname="testdb" checkSQLschema="false"sqlMaxLimit="100"><table name="user"dataNode="dn1,dn2" rule="mod-long"/></schema><dataNode name="dn1"dataHost="mycat" database="db1"/><dataNode name="dn2"dataHost="mycat2" database="db1"/><dataHost name="mycat"maxCon="1000" minCon="10" balance="0"writeType="0" dbType="mysql" dbDriver="native"switchType="1"><heartbeat>selectuser()</heartbeat><writeHosthost="host1" url="dev-2:3306" user="test"password="test"/></dataHost><dataHost name="mycat2"maxCon="1000" minCon="10" balance="0"writeType="0" dbType="mysql" dbDriver="native"switchType="1"><heartbeat>selectuser()</heartbeat><writeHosthost="host2" url="dev-3:3306" user="test"password="test"/></dataHost>
  • 数据库脚本

create databasedb1;
create tabledb1.user(id int, user_name varchar(20), email varchar(20), phone varchar(20));

2.2.    导入方案

由于Mycat支持Mysql协议,所以Mycat对于Mysql数据导入方案有三种:

  1. 用jdbc直接进行insert操作

根据官网测试结果:在16核上insert性能可以达到12w/s

本轮测试数据量200w,测试工具为testtool.tar.gz。结论:tps约8w

  1. 用mysqldump操作

mysqldump操作原理与insert相同,数据量100w,没有预热。结论tps:3w

  1. 用load data infile操作

官网说法:是insert性能的几十倍,如下

Load data功能在1.4版本+支持,经过测试发现,如果导入数据量比较大(大于10w),则会出现文件找不到情况,官网群中有人出现同样问题,原因待查。

根据其他人测试结果:loaddata local infile命令64M23万条数据用到500多M内存

2.3.  扩容迁移方案

从schema db1迁移扩容到db2。由于mycql不支持自动扩容,所以需要手动进行rehash。

目前方案有:

  1. 将数据导出本分,清空数据,通过上述导入方案的三种方式进行扩容迁移

性能结果如上测试

  1. 手动迁移(注意:此方案只适合单节点迁移):

  2. 1)        使用mycat的RehashLauncher重新进行hash算法,得出rehash的id列表

  3. 2)        在mysql上使用mysqldump根据rehash的id列表,导出数据

  4. 3)        在mycat上mysqldump,导入数据

  5. 4)        在mysql上删除迁移的数据

对于1)步骤,有2个bug:

  • 取得id值时错误

此bug已经提交到mycate1.4和mycat master分支,并已合并

  • hash后的host比较错误

此bug已经提交到1.4分支,并已合并

对于2),3),4)步骤可以采用shell脚本自动运行,官网脚本如下:

# arg1=start, arg2=end, format: %s.%N
function getTiming() {start=$1end=$2start_s=$(echo$start | cut -d '.' -f 1)start_ns=$(echo$start | cut -d '.' -f 2)end_s=$(echo $end |cut -d '.' -f 1)end_ns=$(echo $end |cut -d '.' -f 2)time=$(( ( 10#$end_s- 10#$start_s ) * 1000 + ( 10#$end_ns / 1000000 - 10#$start_ns / 1000000 ) ))echo "$timems"
}#rehash节点
rehashNode=$1
#mycat节点
expanNode=$2
#迁移数据
order_fn="$3"#迁移数据库
rehash_db=db1
#迁移表
rehash_table=user#mysql配置
mysql_port=3306
mysql_user=test
mysql_pwd=test#mycat配置
mycat_port=8066
mycat_user=mysql
mycat_pwd=123456
mycat_db=testdbstart=$(date +%s.%N)if [ "$#" = "0" ]; then
echo "Please input parameter, for example:"
echo "ReRouter.sh 192.168.84.13 192.168.84.14/home/mycat/T_CMS_ORDER"
echo " "
exit
fi;
echo "需要进行迁移的主机总量为:$#, 主机 IP 列表如下:"
for i in "$@"
do
echo "$i"
done
echo " "
#取出 rehash 需要的 SerNum(已经用 in 拼接好)
for n in `cat $order_fn`
do
condOrder=$n
doneecho "************* 导出 *************"
date
# 1) 首先调用 mysqldump 进行数据导出
echo "开始导出主机:$ 表:T_CMS_ORDER."
mysqldump -h$rehashNode -P$mysql_port -u$mysql_user-p$mysql_pwd $rehash_db $rehash_table --default-characterset=utf8 --extende
d-insert=false --no-create-info --add-locks=false--completeinsert --where=" id in $condOrder " >./T_CMS_ORDER_temp.sql
echo "导出结束."
echo " "echo "************* 导入 *************"
date
# 2) 调用 mycat 接口进行数据导入
echo "开始导入 T_CMS_ORDER 表数据"
mysql -h$expanNode -P$mycat_port -u$mycat_user -p$mycat_pwd$mycat_db --default-character-set=utf8 < ./T_CMS_ORDER_temp.sql
echo "导入结束."
echo " "echo "************* 删除数据 *************"
date
# 3) 当前两步都无误的情况下,删除最初的导出数据.
echo "开始删除已导出的数据表:."
mysql -h$rehashNode -Pmycat_port -u$mysql_user-p$mysql_pwd  -e "use $rehash_db;DELETE FROM $rehash_table
WHERE id in $condOrder ; commit; "
echo "删除结束."
echo " "
echo "************* 清空临时文件 *************"
date
# 4) 清空临时文件
rm ./T_CMS_ORDER_temp.sql
echo "清空临时文件"
echo "#####################主机:$rehashNode 处理完成#####################"
date
echo " "echo "ReHash 运行完毕."end=$(date +%s.%N)
getTiming $start $end

此脚本运行1)执行的文件,会报如下错误:

这是由于1)会一次性根据id列表,采用in语句查询出所有数据,当数据量过大时,报错。本轮测试采用优化方案:

  • 1)步骤每1w为一行

RehashLauncher代码如下:

public class RehashLauncher {private final class RehashRunner implements Runnable {private final File   output;private final String table;private RehashRunner(File output, String table) {this.output = output;this.table = table;}public void run(){int pageSize=500;int page=0;List<Map<String, Object>> list=null;int total=0;int rehashed=0;String hostWithDatabase=args.getHostWithDatabase();PrintStream ps=null;try {ps=new PrintStream(output);StringBuilder rehashData = new StringBuilder();list = JdbcUtils.executeQuery(dataSource, "select "+ args.getShardingField() + " from " + table + " limit ?,?", page++ * pageSize,pageSize);while (!CollectionUtil.isEmpty(list)) {for(int i=0,l=list.size();i<l;i++){Map<String, Object> sf=list.get(i);Integer hash=alg.calculate(sf.get(args.getShardingField()).toString());String host=rehashHosts[hash];total++;if(!host.equals(hostWithDatabase)){rehashed++;rehashData.append(sf.get(args.getShardingField())).append(",");if(rehashed % 10000 == 0){ps.println("(" + rehashData.substring(0, rehashData.length() - 1) + ")");rehashData.delete(0, rehashData.length());}}
//                        ps.println(sf+"=>"+host);}list = JdbcUtils.executeQuery(dataSource, "select "+ args.getShardingField() + " from " + table + " limit ?,?", page++ * pageSize,pageSize);}if(rehashData.length() >= 1){ps.println("(" + rehashData.deleteCharAt(rehashData.length() - 1) + ")");}
//                ps.println("rehashed ratio:"+(((double)rehashed)/total));} catch (Exception e) {throw new RehashException(e);}finally{if(ps!=null){ps.close();}latch.countDown();}}}

program argument:

-jdbcDriver=com.mysql.jdbc.Driver -jdbcUrl=jdbc:mysql://172.16.54.136:3306/db1 -host=172.16.54.136:3306 -user=test -database=db1 -password=test -tablesFile=F:/certusnetSVN/books/mycat/rehash\tables.txt -shardingField=id -rehashHostsFile=F:/certusnetSVN/books/mycat/rehash/hosts.txt -hashType=mod -rehashNodeDir=F:/certusnetSVN/books/mycat/rehash/tmp

hosts.txt配置:

172.16.54.136:3306/db1
172.16.54.138:3306/db1
172.16.54.136:3306/db2
172.16.54.138:3306/db2

tables.txt配置:

user
  • 2),3),4)脚本改为shell多线程,每次处理一行的方案

脚本如下:

# arg1=start, arg2=end, format: %s.%N
function getTiming() {start=$1end=$2start_s=$(echo $start | cut -d '.' -f 1)start_ns=$(echo $start | cut -d '.' -f 2)end_s=$(echo $end | cut -d '.' -f 1)end_ns=$(echo $end | cut -d '.' -f 2)time=$(( ( 10#$end_s - 10#$start_s ) * 1000 + ( 10#$end_ns / 1000000 - 10#$start_ns / 1000000 ) ))echo "$time ms"
}#rehash节点
rehashNode=$1
#mycat节点
expanNode=$2
#迁移数据
order_fn="$3"#迁移数据库
rehash_db=db1
#迁移表
rehash_table=user#mysql配置
mysql_port=3306
mysql_user=test
mysql_pwd=test#mycat配置
mycat_port=8066
mycat_user=mysql
mycat_pwd=123456
mycat_db=testdbtotal_start=$(date +%s.%N)if [ "$#" = "0" ]; then
echo "Please input parameter, for example:"
echo "ReRouter.sh 192.168.84.13 192.168.84.14 /home/mycat/T_CMS_ORDER"
echo " "
exit
fi;
echo "需要进行迁移的主机总量为:$#, 主机 IP 列表如下:"
for i in "$@"
do
echo "$i"
done
echo " "
#取出 rehash 需要的 SerNum(已经用 in 拼接好)
while read condOrder
do
{
file_id=${condOrder:3:10}
echo "************* 导出 *************"
date
# 1) 首先调用 mysqldump 进行数据导出
echo "开始导出主机:$ 表:T_CMS_ORDER."
mysqldump -h$rehashNode -P$mysql_port -u$mysql_user -p$mysql_pwd $rehash_db $rehash_table --no-create-info --skip-add-locks -c
--where=" id in $condOrder " > ./T_CMS_ORDER_$file_id.sql
echo "导出结束."
echo " "echo "************* 导入 *************"
date
# 2) 调用 mycat 接口进行数据导入
echo "开始导入 T_CMS_ORDER 表数据"
mysql -h$expanNode -P$mycat_port -u$mycat_user -p$mycat_pwd -D$mycat_db < ./T_CMS_ORDER_$file_id.sql
echo "导入结束."
echo " "echo "************* 删除数据 *************"
date
# 3) 当前两步都无误的情况下,删除最初的导出数据.
echo "开始删除已导出的数据表:."
mysql -h$rehashNode -Pmycat_port -u$mysql_user -p$mysql_pwd  -e "use $rehash_db; DELETE FROM $rehash_table
WHERE id in $condOrder ; commit; "
echo "删除结束."
echo " "
echo "************* 清空临时文件 *************"
date
# 4) 清空临时文件
rm ./T_CMS_ORDER_$file_id.sql
echo "清空临时文件"
echo "#####################主机:$rehashNode 处理完成#####################"
date
echo " "echo "ReHash 运行完毕."
}&
done < $order_fn
waitecho "操作总消耗时长:"
total_end=$(date +%s.%N)
getTiming $total_start $total_end

执行结果100w迁移,耗时约:20s

3.      对于postgresql压测

3.1.  基本配置

  • schema.xml

<schemaname="testdb" checkSQLschema="false"sqlMaxLimit="100"><tablename="user_test" dataNode="dn1,dn2"rule="mod-long"/></schema><dataNode name="dn1"dataHost="mycat" database="db1"/><dataNode name="dn2"dataHost="mycat2" database="db1"/><dataHost name="mycat"maxCon="1000" minCon="10" balance="0"writeType="0" dbType="postgresql" dbDriver="jdbc"switchType="1"><heartbeat>select1</heartbeat><writeHosthost="host1" url="jdbc:postgresql://dev-2:5432/db1"user="postgres" password="123456"/></dataHost><dataHost name="mycat2"maxCon="1000" minCon="10" balance="0"writeType="0" dbType="postgresql" dbDriver="jdbc"switchType="1"><heartbeat>select1</heartbeat><writeHosthost="host2" url="jdbc:postgresql://dev-3:5432/db1"user="postgres" password="123456"/></dataHost>
  • postgresql.conf

shared_buffers = 128MB
max_connections = 1000
fsync = off
wal_buffers = -1
commit_delay = 10000
commit_siblings = 500
  • 数据库脚本

create databasedb1;
create table user_test(idint, user_name varchar(20), email varchar(20), phone varchar(20));

3.2.  导入方案

Mycat对于postgresql的导入方案只有一种,采用jdbc的insert方式。

本轮测试数据量100w,测试工具为testtool.tar.gz。结论:tps约6w

3.3.  扩容迁移方案

对于postgresql迁移,也只能采用编程程序的方式进行,方案可以参考mysql迁移方案,此轮不再测试。

转载于:https://blog.51cto.com/eric100/1723079

Mycat对于导入和扩容迁移性能压测相关推荐

  1. 高性能分布式缓存redis(持久化原理 安全策略 过期删除内存淘汰策略 性能压测 高可用 Redis Cluster)

    redis redis(持久化原理 安全策略 过期删除&内存淘汰策略 性能压测 高可用 Redis Cluster) 1. 持久化原理 1.1 持久化流程(落盘) 1.2 RDB详解 1.2. ...

  2. 性能压测工具选型对比

    本文是<Performance Test Together>(简称PTT)系列专题分享的第二期,该专题将从性能压测的设计.实现.执行.监控.问题定位和分析.应用场景等多个纬度对性能压测的全 ...

  3. 如何做好性能压测(一)丨压测环境设计和搭建

    简介:如何做好性能压测(一)丨压测环境设计和搭建 一般来说,保证执行性能压测的环境和生产环境高度一致是执行一次有效性能压测的首要原则.有时候,即便是压测环境和生产环境有很细微的差别,都有可能导致整个压 ...

  4. oralce load的时候使用触发器会导致load慢吗_你真的了解性能压测中的SLA吗?

    作者简介:襄玲(花名),阿里巴巴技术专家,PTS 研发,近期主导整理和推动云时代性能压测的思想和标准,云计算性能测试国标项目组成员,内部稳定性保障系统之预热系统负责人. 本文是<Performa ...

  5. 如何做好性能压测丨压测环境设计和搭建

    简介:一般来说,保证执行性能压测的环境和生产环境高度一致是执行一次有效性能压测的首要原则.有时候,即便是压测环境和生产环境有很细微的差别,都有可能导致整个压测活动评测出来的结果不准确. 一般来说,保证 ...

  6. 如何做好性能压测(一) | 压测环境的设计和搭建

    性能压测,是保障服务可用性和稳定性过程中,不可或缺的一环,但是有关性能压测的体系化分享并不多.如何做好性能压测的系列专题分享,将从性能压测的设计.实现.执行.监控.问题定位和分析.应用场景等多个纬度对 ...

  7. 如何做好性能压测:压测环境的设计和搭建

    01 性能环境要考虑的要素 性能压测,是保障服务可用性和稳定性过程中,不可或缺的一环.我们将从性能压测的设计.实现.执行.监控.问题定位和分析.应用场景等多个纬度对性能压测的全过程进行拆解,以帮助大家 ...

  8. 如何做好性能压测(一):压测环境的设计和搭建

    01 性能环境要考虑的要素 系统逻辑架构,即组成系统的组件.应用之间的结构.交互关系的抽象.最简单最基本的就是这三层架构. 三层逻辑结构图 客户层:用户请求端. Web层:处理客户端所有的业务请求逻辑 ...

  9. 谷粒商城项目篇8_分布式高级篇_商城首页、性能压测、优化(Nginx动静分离)

    目录 商城首页 整合thymeleaf springmvc的WebMvcAutoConfiguration 首页三级分类渲染 Nginx代理 Nginx代理会丢掉host信息 压力测试 性能检测 性能 ...

最新文章

  1. 运营谈恋爱,真的太太太太太太会撩了
  2. PS2019历史记录画笔工具、历史记录艺术画笔工具
  3. oracle12之 多租户容器数据库架构
  4. HDUOJ1864最大报销额(01背包)
  5. 浅谈对离散型随机变量期望的理解
  6. python程序设计基础电子版_Python 程序设计基础(董付国 著)完整版PDF[6MB]
  7. Tomcat下载步骤
  8. 【数据库】一个 rm -rf 把公司整个数据库删没了
  9. istio入门(01)istio的优势在哪里?
  10. 模拟京东商城登陆HttpRequest
  11. Redis高级项目实战,2021最新Java大厂面试真题大全
  12. 张小龙的话与微信的玄机
  13. Scrum板与Kanban如何抉择?kdliihoap板与按照xhvrcr
  14. 使用malloc函数分配空间
  15. TamperMonkey脚本开发_无限制视频提取
  16. katka-container搭建
  17. VScode实现分屏显示浏览器(一边写前端代码一边可以实时查看结果)
  18. 我拿到了北京户口!却是跌落的开始....
  19. unite 开发_在Unite Nordic振兴您的游戏开发
  20. 迅为3399开发板Linux固件编译

热门文章

  1. 利用rpm包搭建lamp环境及论坛的创建
  2. 如何看待 Apache Log4j 2 远程代码执行漏洞?
  3. Nginx的http块自定义服务日志
  4. 怎么使用config?
  5. Dubbo对于REST协议的支持
  6. 委派模式与策略模式综合应用
  7. Spring七中传播行为详解
  8. 配置jvm堆最大内存eden区与s0或者s1区域比例
  9. 加密与安全 - Java加密与安全
  10. ThreadLocal - Java多线程编程