标签:后台 变量 list rom cms 数据 实践 lib lease
工具目前从mycat1.6开始支持。
一、准备工作
1、mycat所在环境安装mysql客户端程序
2、mycat的lib目录下添加mysql的jdbc驱动包
3、对扩容缩容的表所有节点数据进行备份,以便迁移失败后的数据恢复
二、扩容缩容步骤
1、复制schema.xml、rule.xml并重命名为newSchema.xml、newRule.xml放于conf目录下
2、修改newSchema.xml和newRule.xml配置文件为扩容缩容后的mycat配置参数(表的节点数、数据源、路由规则)
3、修改conf目录下的migrateTables.properties配置文件,告诉工具哪些表需要进行扩容或缩容,没有出现在此配置文件的schema表不会进行数据迁移,格式:
4、修改bin目录下的dataMigrate.sh脚本文件,参数如下:
tempFileDir 临时文件路径,目录不存在将自动创建
isAwaysUseMaster默认true:不论是否发生主备切换,都使用主数据源数据,false:使用当前数据源
mysqlBin:mysql bin路径
cmdLength mysqldump命令行长度限制 默认110k 110*1024。在LINUX操作系统有限制单条命令行的长度是128KB,也就是131072字节,这个值可能不同操作系统不同内核都不一样,如果执行迁移时报Cannot run program "sh": error=7, Argument list too long 说明这个值设置大了,需要调小此值。
charset导入导出数据所用字符集 默认utf8
deleteTempFileDir完成扩容缩容后是否删除临时文件 默认为true
threadCount并行线程数(涉及生成中间文件和导入导出数据)默认为迁移程序所在主机环境的cpu核数*2
delThreadCount每个数据库主机上清理冗余数据的并发线程数,默认为当前脚本程序所在主机cpu核数/2
queryPageSize 读取迁移节点全部数据时一次加载的数据量 默认10w条
5、停止mycat服务(如果可以确保扩容缩容过程中不会有写操作,也可以不停止mycat服务)
6、通过crt等工具进入mycat根目录,执行bin/ dataMigrate.sh脚本,开始扩容/缩容过程:
7、扩容缩容成功后,将newSchema.xml和newRule.xml重命名为schema.xml和rule.xml并替换掉原文件,重启mycat服务,整个扩容缩容过程完成。
三、注意事项:
1) 保证拆分表迁移数据前后路由规则一致
2) 保证拆分表迁移数据前后拆分字段一致
3) 全局表将被忽略
4) 不要将非拆分表配置到migrateTables.properties文件中
5) 暂时只支持拆分表使用mysql作为数据源的扩容缩容
四、优化
dataMigrate.sh脚本中影响数据迁移速度的有4个参数,正式迁移数据前可以先进行一次测试,通过调整以下参数进行优化获得一个最快的参数组合
threadCount脚本执行所在主机的并行线程数(涉及生成中间文件和导入导出数据)默认为迁移程序所在主机环境的cpu核数*2
delThreadCount每个数据库主机上清理冗余数据的并发线程数,默认为当前脚本程序所在主机cpu核数/2,同一主机上并发删除数据操作线程数过多可能会导致性能严重下降,可以逐步提高并发数,获取执行最快的线程个数。
queryPageSize 读取迁移节点全部数据时一次加载的数据量 默认10w条
cmdLength mysqldump命令行长度限制 默认110k 110*1024。尽量让这个值跟操作系统命令长度最大值一致,可以通过以下过程确定操作系统命令行最大长度限制:
逐步减少100000,直到不再报错
/bin/sh -c "/bin/true $(seq 1 100000)"
获取不报错的值,通过wc –c统计字节数,结果即操作系统命令行最大长度限制(可能稍微小一些)
当使用一致性Hash进行路由分片时,假设存在节点宕机/新增节点这种情况,那么相对于使用其他分片算法(如mod),就能够尽可能小的改变已存在key映射关系,尽可能的减少数据迁移操作。当然一致性hash也有一个明显的不足,假设当前存在三个节点A,B,C,且是使用一致性hash进行分片,如果你想对当前的B节点进行扩容,扩容后节点为A,B,C,D,那么扩容完成后数据分布就会变得不均匀。A,C节点的数据量是大于B,D节点的。
据测试,分布最均匀的是mod,一致性哈希只是大致均匀。数据迁移也是,迁移量最小的做法是mod,每次扩容后节点数都是2的N次方,这样的迁移量最小。但是mod需要对每个节点都进行迁移,这也是mod的不足之处。总之,还得酌情使用,根据业务选择最适合自己系统的方案。
2.1 配置使用
rule.xml:定义分片规则
<tableRule name="sharding-by-murmur">
<rule>
<columns>SERIAL_NUMBER</columns> <algorithm>murmur</algorithm>
</rule> </tableRule>
<function name="murmur" class="org.opencloudb.route.function.PartitionByMurmurHash">
<property name="seed">0</property>
<property name="count">2</property>
<property name="virtualBucketTimes">160</property>
</function>
tableRule定义分片规则
function定义一致性Hash的参数
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://org.opencloudb/">
<schema name="mycat" checkSQLschema="false" sqlMaxLimit="100">
<table name="T_CMS_ORDER" primaryKey="ORDER_ID" dataNode="dn202_3316"
rule="sharding-by-murmur" />
</schema>
<dataNode name="dn202_3316" dataHost="lh202_1" database="poc" />
<dataHost name="lh202_1" maxCon="2000" minCon="10" balance="0"
writeType="0" dbType="mysql" dbDriver="native">
<heartbeat>select user()</heartbeat>
<writeHost host="master_host-m1" url="10.21.17.202:3316"
user="usr" password="pwd"></writeHost>
<writeHost host="savle_host-m1" url="10.21.17.201:3317"
user="usr" password="pwd"></writeHost>
</dataHost>
</mycat:schema>
server.xml:定义用户以及系统相关变量,如端口等。没有太高要求的可以只修改数据库部分。
<user name="mycat"> <property name="password">usr</property> <property name="schemas">pwd</property> </user>
经过以上配置就可以使用一致性hash了。
2.2 一致性Hash的数据迁移
开始迁移
进行一致性hash进行迁移的时候,假设你新增加一个节点,需要修改以下两个配置文件:
rule.xml
<function name="murmur" class="org.opencloudb.route.function.PartitionByMurmurHash"> <property name="seed">0</property>
<property name="count">3</property> <property name="virtualBucketTimes">160</property> <!-- <property name="weightMapFile">weightMapFile</property> <property name="bucketMapPath">/home/usr/mycat/bucketMapPath</property> --> </function>
需要把节点的数量从2个节点扩为3个节点。
schema.xml
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://org.opencloudb/">
<schema name="mycat" checkSQLschema="false" sqlMaxLimit="100">
<table name="T_CMS_ORDER" primaryKey="ORDER_ID" dataNode="dn202_3316,dn201_3316"
rule="sharding-by-murmur" />
</schema>
<dataNode name="dn202_3316" dataHost="lh202_1" database="poc" />
<dataNode name="dn201_3316" dataHost="lh201_1" database="poc" />
<dataHost name="lh202_1" maxCon="2000" minCon="10" balance="0"
writeType="0" dbType="mysql" dbDriver="native">
<heartbeat>select user()</heartbeat>
<writeHost host="master_host-m1" url="10.21.17.202:3316"
user="usr" password="pwd"></writeHost>
<writeHost host="savle_host-m1" url="10.21.17.201:3317"
user="usr" password="pwd"></writeHost>
</dataHost>
<dataHost name="lh201_1" maxCon="2000" minCon="10" balance="0"
writeType="0" dbType="mysql" dbDriver="native">
<heartbeat>select user()</heartbeat>
<writeHost host="master_host-m1" url="10.21.17.201:3316"
user="usr" password="pwd"></writeHost>
<writeHost host="savle_host-m1" url="10.21.17.202:3317"
user="usr" password="pwd"></writeHost>
</dataHost>
</mycat:schema>
需要添加新节点的dataNode和dataHost信息,以及在schema中的table标签下把新增节点的dataNode的name增加到dataNode的值中。
2.3 开始迁移
使用org.opencloudb.util.rehasher.RehashLauncher类进行数据迁移。参数以命令行的形式进行载入。如
-jdbcDriver=xxxxx -jdbcUrl=.... -host=192.168.1.1:3316 -user=xxxx -password=xxxx -database=xxxx
rehashNode=$1
expanNode=$2
order_fn="$3"
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
done echo "************* 导出 *************"
date
# 1) 首先调用mysqldump进行数据导出
echo "开始导出主机:$ 表:T_CMS_ORDER."
mysqldump -h$rehashNode -P3316 -upoc -ppoc123 poc T_CMS_ORDER --default-character-set=utf8 --extended-insert=false --no-create-info --add-locks=false --complete-insert --where=" SERIAL_NUMBER in $condOrder " > ./T_CMS_ORDER_temp.sql
echo "导出结束."
echo " "
echo "************* 导入 *************" date
# 2) 调用mycat接口进行数据导入
echo "开始导入T_CMS_ORDER表数据"
mysql -h$expanNode -P8066 -upoc -ppoc123 poc --default-character-set=utf8 < ./T_CMS_ORDER_temp.sql echo "导入结束."
echo " "
echo "************* 删除数据 *************" date
# 3) 当前两步都无误的情况下,删除最初的导出数据.
echo "开始删除已导出的数据表:."
mysql -h$rehashNode -P3316 -upoc -ppoc123 -e "use poc; DELETE FROM T_CMS_ORDER WHERE SERIAL_NUMBER in $condOrder ; commit; "
echo "删除结束."
echo " "
echo "************* 清空临时文件 *************" date
# 4) 清空临时文件 rm ./t_cms_order_temp.sql
echo "清空临时文件"
echo "#####################主机:$rehashNode 处理完成#####################"
date
echo " " echo "ReHash运行完毕."
假设文件名是:ReHashRouter.sh
在使用范围分片算法进行路由分片时,配置非常简单。如下:
3.1 配置使用
rule.xml:定义分片规则
<tableRule name="auto-sharding-long">
<rule>
<columns>user_id</columns>
<algorithm>rang-long</algorithm>
</rule>
</tableRule>
<function name="rang-long"
class="org.opencloudb.route.function.AutoPartitionByLong">
<property name="mapFile">autopartition-long.txt</property>
</function>
tableRule定义分片规则
function定义范围分片的参数
可以看到根据范围自动分片的配置文件非常简单,只有一个mapFile(要赋予读的权限),此mapFile文件定义了每个节点中user_id的范围,如果user_id的值超过了这个范围,那么则使用默认节点。当前版本代码中默认节点的值是-1,表示不配置默认节点,超过当前范围就会报错。当然你也可以在property中增加defaultNode的默认值,如:
<property name="defaultNode">0</property>
mapFile节点配置文件
当前版本提供了一个mapFile配置文件供大家参考和使用,如下
# range start-end ,data node index
# K=1000,M=10000. 0-500M=0 500M-1000M=1
所有的节点配置都是从0开始,及0代表节点1,此配置非常简单,即预先制定可能的id范围到某个分片。
(tips:K和M的定义是在org.opencloudb.route.function.NumberParseUtil中定义的,如果感兴趣的同学可以自己定义其他字母。)
扩容
如果业务需要或者数据超过当前定义的范围,需要新增节点,则可以在文件中追加 1000M-1500M=2 即可。当然新增的节点需要在schema.xml中进行定义。
# range start-end ,data node index
# K=1000,M=10000. 0-500M=0
500M-1000M=1 1000M-1500M=2
4.1 迁移时间的确定
在进行迁移之前,我们得先确定迁移操作发生的时间。停机操作需要尽可能的让用户感知不到,你可以观察每段时间系统的吞吐量,以此作为依据。一般来说,我们选择在凌晨进行升级操作。
4.2 数据迁移前的测试
需要做一些相关的性能测试,在条件允许的情况下在类似的环境中完全模拟,得到一些性能数据,然后不断的改进,看能够否有大的提升。
我们在做数据迁移的时候,就是在备份库中克隆的一套环境,然后在上面做的性能测试,在生产上的步骤方式都一样,之后在正式升级的时候就能够做到心中有数。什么时候需要注意什么,什么时候需要做哪些相关的检查。
4.3 数据备份
热备甚至冷备,在数据迁移之前进行完整的备份,一定要是全量的。甚至在允许的情况下做冷备都可以。数据的备份越充分,出现问题时就有了可靠的保证。
lob数据类型的备份,做表级的备份(create table nologging….),对于lob的数据类型,在使用imp,impdp的过程中,瓶颈都在lob数据类型上了,哪怕表里的lob数据类型是空的,还是影响很大。自己在做测试的时候,使用Imp基本是一秒钟一千条的数据速度,impdp速度有所提升,但是parallle没有起作用,速度大概是1秒钟1万条的样子。
如果在数据的导入过程中出了问题,如果有完整快速的备份,自己也有了一定的数据保证,要知道出问题之后再从备份库中导入导出,基本上都是很耗费时间的。
4.4 数据升级前的系统级检查
load data infile语句可以从一个文本文件中以很高的速度读入一个表中。性能大概是insert语句的几十倍。通常用来批量数据导入。目前只支持mysql数据库且dbDriver必须为native。Mycat支持load data自动路由到对应的分片。Load data和压缩协议mycat从1.4开始支持。
5.1 语法和注意事项
标准示例:
load DATA local INFILE ‘d:\88\qq.txt‘ IGNORE INTO TABLE test CHARACTER SET ‘gbk‘ FIELDS TERMINATED BY ‘,‘ OPTIONALLY ENCLOSED BY ‘"‘ LINES TERMINATED BY ‘\n‘(id,sid,asf) ;
注意:如果数据中可能包含一些特殊字符,比如分割符转义符等,建议用引号扩起来,通过OPTIONALLY ENCLOSED BY ‘”’指定。如果这样还不行,可以把字段值中的引号替换成\”。
如果指定local关键词,则表明从客户端主机读文件。如果local没指定,文件必须位于mycat所在的服务器上。
可以通过fields terminated by指定字符之间的分割符号,默认值为\t
通过lines terminated by可以指定行之间的换行符。默认为\n,这里注意有些windows上的文本文件的换行符可能为\r\n,由于是不可见字符,所以请小心检查。
character set 指定文件的编码,建议跟mysql的编码一致,否则可能乱码。其中字符集编码必须用引号扩起来,否则会解析出错。
还可以通过replace | ignore指定遇到重复记录是替换还是忽略。
目前列名必须指定,且必须包括分片字段,否则没办法确定路由。
其他参数参考mysql的load data infile官方文档说明。
注意其他参数的先后顺序不能乱,比如列名比较在最后的,顺序参考官方说明。
标准load data语句: LOAD DATA语句,同样被记录到binlog,不过是内部的机制.
例子: 导出:
select * from tblog_article into outfile ‘/test.txt‘ FIELDS TERMINATED BY ‘\t‘ OPTIONALLY ENCLOSED BY ‘‘ ESCAPED BY ‘\\‘ LINES TERMINATED BY ‘\n‘;
导入:
load data local infile ‘/var/lib/mysql/blog/test.txt‘ INTO TABLE tblog_article FIELDS TERMINATED BY ‘\t‘ OPTIONALLY ENCLOSED BY ‘‘ ESCAPED BY ‘\\‘ LINES TERMINATED BY ‘\n‘ (id,title,level,create_time,create_user,create_user,article_type_id,article_content,istop,status,read_count );
5.2 客户端配置
如果是mysql命令行连接的mycat,则需要加上参数–local-infile=1。Jdbc则无需设置。
Load data测试性能
在一台win8下 ,jvm 1.7 参数默认,jdbc连接mycat。
测试结果load data local导入1百万数据到5个分片耗时10秒,1千万数据到5个分片耗时145秒。
mysqldump是mysql自带的命令行工具。可以用它完成全库迁移(从一个mysql库完整迁移到mycat),也可以迁移某几个表,还可以迁移某个表的部分数据。
6.1 全库迁移
迁移前准备
迁移前确保mysql库和mycat库中的表名一样(mycat库中只需要有表名配置在schema.xml文件中即可)
从mysql导出
从mysql库上全库导出 mysqldump -c -–skip-add-locks databaseName> /root/databaseName.sql
注意:(上面的语句没有-uroot -ppassword参数,是因为mysql服务器设置了本机免密码等。
如果设置了密码:通过以下命名导出(用户名为root,密码为123456): mysqldump -uroot -p123456 -c -–skip-add-locks databaseName> /root/databaseName.sql
)
说明:两个参数不可少,如下:
-c参数不可少,-c, 全称为–complete-insert 表示使用完整的insert语句(用列名字)。
-–skip-add-locks表示导数据时不加锁,如果加锁涉及多分片时容易导致死锁。
导入到mycat
将databaseName.sql拷贝到mycat集群中的一台mysql服务器上/root目录下。
连接mycat:
mysql -uusername -ppassword -h172.17.xxx.xxx -P8066
切换到指定的数据库: use databaseName;
导入脚本: source /root/databaseName.sql;
6.2 迁移一个库中的某几个表
只是导出命令不同,其他与全库迁移一样
mysqldump -c -–skip-add-locks databaseName table1 table2> /root/someTables.sql
迁移一个表中的部分数据,加参数–where实现。
命令如下:
mysqldump -c -–skip-add-locks databaseName tableName --where=" id > 900 " > /root/onetableDataWithCondition.sql
标签:后台 变量 list rom cms 数据 实践 lib lease
原文地址:http://blog.csdn.net/wangshuang1631/article/details/69055958