命令记不住

登陆

3.Mycat 配置读写分离及高可用

3.Mycat配置读写分离及高可用

1.Mycat配置文件介绍

logs目录

wrapper.log       ---->mycat启动日志
mycat.log         ---->mycat详细工作日志

conf目录

schema.xml       ----->主配置文件(读写分离、高可用、分布式策略定制、节点控制)
server.xml		 ----->mycat软件本身相关的配置
rule.xml         ----->分片规则配置文件(分片规则列表、使用方法)

2.配置读写分离及高可用

2.1修改配置文件schema.xml

[root@db01 conf]# mv schema.xml schema.xml.rw
[root@db01 conf]# vim schema.xml

<?xml version="1.0"?>  
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">  
<mycat:schema xmlns:mycat="http://io.mycat/">
<schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100" dataNode="sh1"> 
</schema>  
	<dataNode name="sh1" dataHost="oldguo1" database= "world" />  
	<dataHost name="oldguo1" maxCon="1000" minCon="10" balance="1"  writeType="0" dbType="mysql"  dbDriver="native" switchType="1"> 
		<heartbeat>select user()</heartbeat>  
	<writeHost host="db1" url="10.0.0.51:3307" user="root" password="123"> 
			<readHost host="db2" url="10.0.0.51:3309" user="root" password="123" /> 
	</writeHost> 
    <writeHost host="db3" url="10.0.0.52:3307" user="root" password="123"> 
			<readHost host="db4" url="10.0.0.52:3309" user="root" password="123" /> 
	</writeHost>      
	</dataHost>  
</mycat:schema>

真正的 writehost:负责写操作的writehost
standby writeHost :和readhost一样,只提供读服务

当写节点宕机后,后面跟的readhost也不提供服务,这时候standby的writehost就提供写服务,
后面跟的readhost提供读服务

2.1测试:

mysql -uroot -p123456 -h 127.0.0.1 -P 8066
show variables like 'server_id';

读写分离测试

 mysql -uroot -p -h 127.0.0.1 -P8066
 show variables like 'server_id';
 show variables like 'server_id';
 show variables like 'server_id';
 
 begin;
 show variables like 'server_id';

对db01 3307节点进行关闭和启动,测试读写操作

2.3配置中的属性介绍:

balance属性:
负载均衡类型,目前的取值有3种:

  • 1.balance="0", 不开启读写分离机制,所有读操作都发送到当前可用的writeHost上。
  • 2.balance="1",全部的readHost与standby writeHost参与select语句的负载均衡,简单的说,
    当双主双从模式(M1->S1,M2->S2,并且M1与 M2互为主备),正常情况下,M2,S1,S2都参与select语句的负载均衡。
  • 3.balance="2",所有读操作都随机的在writeHost、readhost上分发。

writeType属性
负载均衡类型,目前的取值有2种:

  • 1.writeType="0", 所有写操作发送到配置的第一个writeHost,
    第一个挂了切到还生存的第二个writeHost,重新启动后已切换后的为主,切换记录在配置文件中:dnindex.properties .
  • 2.writeType=“1”,所有写操作都随机的发送到配置的writeHost,但不推荐使用

switchType属性

  • -1 表示不自动切换
  • 1 默认值,自动切换
  • 2 基于MySQL主从同步的状态决定是否切换 ,心跳语句为 show slave status

datahost其他配置:

<dataHost name="localhost1" maxCon="1000" minCon="10" balance="1"  writeType="0" dbType="mysql"  dbDriver="native" switchType="1"> 

maxCon="1000":最大的并发连接数
minCon="10" :mycat在启动之后,会在后端节点上自动开启的连接线程

tempReadHostAvailable="1"

这个一主一从时(1个writehost,1个readhost时),可以开启这个参数,如果2个writehost,2个readhost时
<heartbeat>select user()</heartbeat>  监测心跳

3.垂直分表

1.备份scgema.xml

mv schema.xml schema.xml.ha
2.MyCAT核心特性——分片(水平拆分)

分片:对一个"bigtable",比如说t3表

1).行数非常多,800w
2).访问非常频繁

分片的目的:
1).将大数据量进行分布存储
2).提供均衡的访问路由

分片策略:

范围 range  800w  1-400w 400w01-800w
取模 mod    取余数
枚举 
哈希 hash 
时间 流水

优化关联查询

全局表
ER分片

4.范围分片

4.1 t3表
(1)行数非常多,2000w(1-1000w:sh1 1000w01-2000w:sh2)
(2)访问非常频繁,用户访问较离散


<schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100" dataNode="dn1"> 
	<table name="t3" dataNode="dn1,dn2" rule="auto-sharding-long" />
</schema>  
	<dataNode name="dn1" dataHost="localhost1" database= "test" /> 
	<dataNode name="dn2" dataHost="localhost2" database= "test" />  

4.2配置schema.xml

mv schema.xml schema.xml.1

vim schema.xml

<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
<schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100" dataNode="sh1"> 
	<table name="t3" dataNode="sh1,sh2" rule="auto-sharding-long" />
</schema> 
        <dataNode name="sh1" dataHost="oldguo1" database= "world" />
        <dataNode name="sh2" dataHost="oldguo2" database= "world" />
        <dataHost name="oldguo1" maxCon="1000" minCon="10" balance="1"  writeType="0" dbType="mysql"  dbDriver="native" switchType
="1">
                <heartbeat>select user()</heartbeat>
        <writeHost host="db1" url="10.0.0.51:3307" user="root" password="123">
                        <readHost host="db2" url="10.0.0.51:3309" user="root" password="123" />
        </writeHost>
    <writeHost host="db3" url="10.0.0.52:3307" user="root" password="123">
                        <readHost host="db4" url="10.0.0.52:3309" user="root" password="123" />
        </writeHost>
        </dataHost>

        <dataHost name="oldguo2" maxCon="1000" minCon="10" balance="1"  writeType="0" dbType="mysql"  dbDriver="native" switchType
="1">
                <heartbeat>select user()</heartbeat>
        <writeHost host="db1" url="10.0.0.51:3308" user="root" password="123">
                        <readHost host="db2" url="10.0.0.51:3310" user="root" password="123" />
        </writeHost>
    <writeHost host="db3" url="10.0.0.52:3308" user="root" password="123">
                        <readHost host="db4" url="10.0.0.52:3310" user="root" password="123" />
        </writeHost>
        </dataHost>
</mycat:schema>

4.3配置rule.xml

vim rule.xml
<tableRule name="auto-sharding-long">
                <rule>
                        <columns>id</columns>
                        <algorithm>rang-long</algorithm>
                </rule>
			

<function name="rang-long"
    class="io.mycat.route.function.AutoPartitionByLong">
    <property name="mapFile">autopartition-long.txt</property>
</function>


----------


		
vim autopartition-long.txt
0-10=0
11-20=1

4.4创建测试表:

mysql -S /data/3307/mysql.sock 
use world
create table t3 (id int not null primary key auto_increment,name varchar(20) not null);

mysql -S /data/3308/mysql.sock 
use world
create table t3 (id int not null primary key auto_increment,name varchar(20) not null);

4.5测试:
重启mycat

mycat restart
ps -ef |grep mycat

mysql -uroot -p123456 -h 127.0.0.1 -P 8066

insert into t3(id,name) values(1,'a');
insert into t3(id,name) values(2,'b');
insert into t3(id,name) values(3,'c');
insert into t3(id,name) values(4,'d');

insert into t3(id,name) values(11,'aa');
insert into t3(id,name) values(12,'bb');
insert into t3(id,name) values(13,'cc');
insert into t3(id,name) values(14,'dd');

5.取模分片(mod-long)

5.1取余分片方式:分片键(一个列)与节点数量进行取余,得到余数,将数据写入对应节点
比如说: 现在节点数量是2

id / 2  ====> 0(dn1) ,1 ( dn2)


id / 4 ----> 0,1,2,3
1/4   1 
2/4   2 
3/4   3 
4/4   0 
5/4   1 

5.2配置schema.xml

<?xml version="1.0"?>  
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">  
<mycat:schema xmlns:mycat="http://io.mycat/">
<schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100" dataNode="dn1"> 
	<table name="t4" dataNode="dn1,dn2" rule="mod-long" />
</schema>  
	<dataNode name="dn1" dataHost="localhost1" database= "test" /> 
	<dataNode name="dn2" dataHost="localhost2" database= "test" />  

	<dataHost name="localhost1" maxCon="1000" minCon="10" balance="1"  writeType="0" dbType="mysql"  dbDriver="native" switchType="1"> 
		<heartbeat>select user()</heartbeat>  
	<writeHost host="db1" url="10.0.0.51:3307" user="root" password="123"> 
			<readHost host="db2" url="10.0.0.51:3309" user="root" password="123" /> 
	</writeHost> 
    <writeHost host="db3" url="10.0.0.52:3307" user="root" password="123"> 
			<readHost host="db4" url="10.0.0.52:3309" user="root" password="123" /> 
	</writeHost>      
	</dataHost>  
   
	<dataHost name="localhost2" maxCon="1000" minCon="10" balance="1"  writeType="0" dbType="mysql"  dbDriver="native" switchType="1"> 
		<heartbeat>select user()</heartbeat>  
	<writeHost host="db1" url="10.0.0.51:3308" user="root" password="123"> 
			<readHost host="db2" url="10.0.0.51:3310" user="root" password="123" /> 
	</writeHost> 
    <writeHost host="db3" url="10.0.0.52:3308" user="root" password="123"> 
			<readHost host="db4" url="10.0.0.52:3310" user="root" password="123" /> 
	</writeHost>   
	</dataHost>  
</mycat:schema>

5.3配置rule.xml

vim rule.xml

107                 <property name="count">2</property>

5.4准备测试环境

1.创建测试表:

mysql -S /data/3307/mysql.sock 
use test
create table t4 (id int not null primary key auto_increment,name varchar(20) not null);

mysql -S /data/3308/mysql.sock 
use test
create table t4 (id int not null primary key auto_increment,name varchar(20) not null);

2.重启mycat

mycat restart
3.测试:

mysql -uroot -p123456 -h10.0.0.52 -P8066

use TESTDB
insert into t4(id,name) values(1,'a');
insert into t4(id,name) values(2,'b');
insert into t4(id,name) values(3,'c');
insert into t4(id,name) values(4,'d');

分别登录后端节点查询数据

mysql -S /data/3307/mysql.sock 
use test
select * from t4;

mysql -S /data/3308/mysql.sock 
use test
select * from t4;

6.枚举分片

t4 表

id name telnum
1	bj   1212
2	sh   22222
3	bj   3333
4	sh   44444
5	bj   5555

sharding-by-intfile

vim schema.xml
<?xml version="1.0"?>  
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">  
<mycat:schema xmlns:mycat="http://io.mycat/">
<schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100" dataNode="dn1"> 
	<table name="t5" dataNode="dn1,dn2" rule="sharding-by-intfile" />
</schema>  
	<dataNode name="dn1" dataHost="localhost1" database= "test" /> 
	<dataNode name="dn2" dataHost="localhost2" database= "test" />  

	<dataHost name="localhost1" maxCon="1000" minCon="10" balance="1"  writeType="0" dbType="mysql"  dbDriver="native" switchType="1"> 
		<heartbeat>select user()</heartbeat>  
	<writeHost host="db1" url="10.0.0.51:3307" user="root" password="123"> 
			<readHost host="db2" url="10.0.0.51:3309" user="root" password="123" /> 
	</writeHost> 
    <writeHost host="db3" url="10.0.0.52:3307" user="root" password="123"> 
			<readHost host="db4" url="10.0.0.52:3309" user="root" password="123" /> 
	</writeHost>      
	</dataHost>  
   
	<dataHost name="localhost2" maxCon="1000" minCon="10" balance="1"  writeType="0" dbType="mysql"  dbDriver="native" switchType="1"> 
		<heartbeat>select user()</heartbeat>  
	<writeHost host="db1" url="10.0.0.51:3308" user="root" password="123"> 
			<readHost host="db2" url="10.0.0.51:3310" user="root" password="123" /> 
	</writeHost> 
    <writeHost host="db3" url="10.0.0.52:3308" user="root" password="123"> 
			<readHost host="db4" url="10.0.0.52:3310" user="root" password="123" /> 
	</writeHost>   
	</dataHost>  
</mycat:schema>

rule.xml

vim rule.xml

<tableRule name="sharding-by-intfile"> 
<rule> <columns>name</columns> 
<algorithm>hash-int</algorithm> 
</rule> 
</tableRule> 


<function name="hash-int" class="org.opencloudb.route.function.PartitionByFileMap"> 
<property name="mapFile">partition-hash-int.txt</property> 
  <property name="type">1</property>
                <property name="defaultNode">0</property>

</function> 

配置partition-hash-int.txt

partition-hash-int.txt 配置: 
10000=0 
10010=1
DEFAULT_NODE=1 

columns 标识将要分片的表字段,algorithm 分片函数, 其中分片函数配置中,mapFile标识配置文件名称

5.1枚举分片准备测试环境

5.2创建测试表:

mysql -S /data/3307/mysql.sock 
use test
create table t5 (id int not null primary key auto_increment,name varchar(20) not null);

mysql -S /data/3308/mysql.sock 
use test
create table t5 (id int not null primary key auto_increment,name varchar(20) not null);

5.3重启mycat

mycat restart

mysql -uroot -p123456 -h10.0.0.52 -P8066

use TESTDB
insert into t5(id,name) values(1,'bj');
insert into t5(id,name) values(2,'sh');
insert into t5(id,name) values(3,'bj');
insert into t5(id,name) values(4,'sh');
insert into t5(id,name) values(5,'tj');

6.Mycat全局表

a   b   c  d   

join 

t 



select  t1.name   ,t.x  from  t1 
join t 

select  t2.name   ,t.x  from  t2 
join t 

select  t3.name   ,t.x  from  t3 
join t 

使用场景:
如果你的业务中有些数据类似于数据字典,比如配置文件的配置,
常用业务的配置或者数据量不大很少变动的表,这些表往往不是特别大,
而且大部分的业务场景都会用到,那么这种表适合于Mycat全局表,无须对数据进行切分,
要在所有的分片上保存一份数据即可,Mycat 在Join操作中,业务表与全局表进行Join聚合会优先选择相同分片内的全局表join,
避免跨库Join,在进行数据插入操作时,mycat将把数据分发到全局表对应的所有分片执行,在进行数据读取时候将会随机获取一个节点读取数据。

vim schema.xml 

<table name="t_area" primaryKey="id" type="global" dataNode="dn1,dn2" /> 

后端数据准备

mysql -S /data/3307/mysql.sock 
use test
create table t_area (id int not null primary key auto_increment,name varchar(20) not null);

mysql -S /data/3308/mysql.sock 
use test
create table t_area  (id int not null primary key auto_increment,name varchar(20) not null);

重启mycat

mycat restart
ps -ef | grep mycat
测试:

mysql -uroot -p123456 -h10.0.0.52 -P8066

use TESTDB
insert into t_area(id,name) values(1,'a');
insert into t_area(id,name) values(2,'b');
insert into t_area(id,name) values(3,'c');
insert into t_area(id,name) values(4,'d');

7.E-R分片

A 
join 
B  

为了防止跨分片join,可以使用E-R模式

A   join   B
on  a.xx=b.yy
join C
on A.id=C.id

<table name="A" dataNode="dn1,dn2" rule="mod-long"> 
       <childTable name="B" joinKey="yy" parentKey="xx" /> 
</table> 
select ci.name,co.name,ci.countrycode,ci.population  from city_new as ci join country_new as co on ci.countrycode=co.code where ci.population<100

重启mycat

mycat restart
ps -ef | grep mycat

推荐阅读