这里主要对schema配置进行说明。
文件说明:
• MYCAT_HOME/conf/schema.xml 中定义逻辑库,表、分片节点等内容.
• MYCAT_HOME/conf/rule.xml 中定义分片规则.
• MYCAT_HOME/conf/server.xml 中定义用户以及系统相关变量,如端口等.
对于 MySQL 来说,标准的读写分离是主从模式,一个写节点 Master 后面跟着多个读节点(slave),读节点的数量取决于系统的压力。
schema配置说明:
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
<!--
schema 标签用于定义MyCat实例中的逻辑库,
可以有多个逻辑库,可以使用schema标签来划分这些不同的逻辑库。
-->
<!--
checkSQLschema 当该值设置为true时,如果我们执行语句:select * from TESTDB.travelrecord;
则MyCat会把语句修改为:select * from travelrecord;即把表示schema的字符去掉
-->
<!--
sqlMaxLimit 当该值设置为某个数值时,每条执行的SQL语句,如果没有加上limit语句,MyCat也会自动的加上所对应的值。
注:如果运行的schema为非拆分库的,那么该属性不会生效。
-->
<schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100">
<!-- table 标签定义了 MyCat 中的逻辑表。-->
<!--
name表名,唯一;
dataNode定义这个逻辑表所属的 dataNode(分片节点);
rule用于指定逻辑表要使用的规则名字,规则名字在rule.xml中定义根据,此处是id(long)自动分片
-->
<table name="travelrecord" dataNode="dn1,dn2,dn3" rule="auto-sharding-long" />
<!--
primaryKey,该逻辑表对应真实表的主键;
type定义了逻辑表的类型,目前逻辑表只有“全局表”和”普通表”两种类型,默认为普通表。
-->
<table name="company" primaryKey="ID" type="global" dataNode="dn1,dn2,dn3" />
<table name="goods" primaryKey="ID" type="global" dataNode="dn1,dn2" />
<!--
autoIncrement默认false,指定主键是否自增,配合全局序列,若使用uuid则不适用;
mod-long:随机分片
-->
<table name="hotnews" primaryKey="ID" autoIncrement="true" dataNode="dn1,dn2,dn3"
rule="mod-long" />
<table name="employee" primaryKey="ID" dataNode="dn1,dn2"
rule="sharding-by-intfile" />
<!--childTable 标签用于定义 E-R 分片的子表。通过标签上的属性与父表进行关联。-->
<table name="customer" primaryKey="ID" dataNode="dn1,dn2" rule="sharding-by-intfile">
<childTable name="orders" primaryKey="ID" joinKey="customer_id" parentKey="id">
<childTable name="order_items" joinKey="order_id" parentKey="id" />
</childTable>
<childTable name="customer_addr" primaryKey="ID" joinKey="customer_id" parentKey="id" />
</table>
</schema>
<!-- <dataNode name="dn1$0-743" dataHost="localhost1" database="db$0-743"/> -->
<!--
举下面第一行为例,意思为:使用名字为 localhost1 数据库实例上的 db1 物理数据库,
这就组成一个数据分片,最后,我们使用名字 dn1 标识(别名)这个分片。
-->
<dataNode name="dn1" dataHost="localhost1" database="db1" />
<dataNode name="dn2" dataHost="localhost1" database="db2" />
<dataNode name="dn3" dataHost="localhost1" database="db3" />
<!--<dataNode name="dn4" dataHost="sequoiadb1" database="SAMPLE" />
<dataNode name="jdbc_dn1" dataHost="jdbchost" database="db1" />
<dataNode name="jdbc_dn2" dataHost="jdbchost" database="db2" />
<dataNode name="jdbc_dn3" dataHost="jdbchost" database="db3" /> -->
<!--
name:唯一标识,供上层的标签使用。
maxCon:指定每个读写实例连接池的最大连接。
minCon:指定每个读写实例连接池的最小连接,初始化连接池的大小。
balance:负载均衡类型,目前的取值有 3 种..
1. balance="0", 不开启读写分离机制,所有读操作都发送到当前可用的 writeHost 上。
2. balance="1",当双主双从模式(M1->S1,M2->S2,并且M1与M2互为主备),正常情况下,M2,S1,S2都参与select语句的负载均衡。
3. balance="2",所有读操作都随机的在 writeHost、readhost 上分发。
4. balance="3",所有读请求随机的分发到wiriterHost对应的readhost执行,writerHost不负担读压力,
注意balance=3只在1.4及其以后版本有.
writeType:值为"0", 所有写操作发送到配置的第一个writeHost,第一个挂了切到还生存的第二个writeHost,
重新启动后已切换后的为准,切换记录在配置文件中:dnindex.properties
switchType:
1 默认值,自动切换;
2 基于 MySQL 主从同步的状态决定是否切换,心跳语句为 show slave status
3 基于 MySQL galary cluster 的切换机制(适合集群),心跳语句为 show status like ‘wsrep%’.
dbType:指定后端连接的数据库类型,目前支持二进制的mysq协议,
还有其他使用JDBC连接的数据库。例如:mongodb、oracle、spark 等。
dbDriver:指定连接后端数据库使用的Driver,目前可选的值有native和JDBC。
使用native的话,这个值执行的是二进制的mysql协议。
其他类型的数据库则需要使用JDBC驱动来支持。
-->
<dataHost name="localhost1" maxCon="1000" minCon="10" balance="0"
writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
<!--指明用于和后端数据库进行心跳检查的语句-->
<heartbeat>select user()</heartbeat>
<!--
writeHost和readHost:指定后端数据库的相关配置给mycat,用于实例化后端连接池。
唯一不同的是,writeHost指定写实例、readHost指定读实例。
可以指定多个,但如果writeHost指定的后端数据库宕机,那么这个writeHost绑定的所有readHost都将不可用。
host:用于标识不同实例,一般 writeHost 我们使用*M1,readHost 我们用*S1。
url:后端实例连接地址,如果是使用native的dbDriver,则一般为address:port这种形式。
用JDBC或其他的dbDriver,则需要特殊指定。
当使用JDBC时则可以这么写:jdbc:mysql://localhost:3306/。
user:后端存储实例需要的用户名字
password:后端存储实例需要的密码
-->
<writeHost host="hostM1" url="localhost:3306" user="root"
password="123456">
<readHost host="hostS2" url="192.168.1.200:3306" user="root" password="xxx" />
</writeHost>
<writeHost host="hostS1" url="localhost:3316" user="root"
password="123456" />
<!-- <writeHost host="hostM2" url="localhost:3316" user="root" password="123456"/> -->
</dataHost>
</mycat:schema>
log4j2.xml如下:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d [%-5p][%t] %m %throwable{full} (%C:%F:%L) %n"/>
</Console>
<RollingFile name="RollingFile" fileName="${sys:MYCAT_HOME}/logs/mycat.log"
filePattern="${sys:MYCAT_HOME}/logs/$${date:yyyy-MM}/mycat-%d{MM-dd}-%i.log.gz">
<PatternLayout>
<Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %5p [%t] (%l) - %m%n</Pattern>
</PatternLayout>
<Policies>
<OnStartupTriggeringPolicy/>
<SizeBasedTriggeringPolicy size="250 MB"/>
<TimeBasedTriggeringPolicy/>
</Policies>
</RollingFile>
</Appenders>
<Loggers>
<!--<AsyncLogger name="io.mycat" level="info" includeLocation="true" additivity="false">-->
<!--<AppenderRef ref="Console"/>-->
<!--<AppenderRef ref="RollingFile"/>-->
<!--</AsyncLogger>-->
<asyncRoot level="debug" includeLocation="true">
<!--<AppenderRef ref="Console" />-->
<AppenderRef ref="RollingFile"/>
</asyncRoot>
</Loggers>
</Configuration>
注:
<asyncRoot level="debug" includeLocation="true">为设置日志模式,如果要要看路由情况或错误可以设置debug,正常使用打开info。
<RollingFile name="RollingFile" fileName="${sys:MYCAT_HOME}/logs/mycat.log"...>为日志保存的路径,使用默认的即可。
server.xml如下:
<?xml version="1.0" encoding="UTF-8"?>
<!-- - - Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License. - You
may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0
- - Unless required by applicable law or agreed to in writing, software -
distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the
License for the specific language governing permissions and - limitations
under the License. -->
<!DOCTYPE mycat:server SYSTEM "server.dtd">
<mycat:server xmlns:mycat="http://io.mycat/">
<system>
<property name="nonePasswordLogin">0</property> <!-- 0为需要密码登陆、1为不需要密码登陆 ,默认为0,设置为1则需要指定默认账户-->
<property name="useHandshakeV10">1</property>
<property name="useSqlStat">0</property> <!-- 1为开启实时统计、0为关闭 -->
<property name="useGlobleTableCheck">0</property> <!-- 1为开启全加班一致性检测、0为关闭 -->
<property name="sequnceHandlerType">2</property>
<property name="subqueryRelationshipCheck">false</property> <!-- 子查询中存在关联查询的情况下,检查关联字段中是否有分片字段 .默认 false -->
<!-- <property name="useCompression">1</property>--> <!--1为开启mysql压缩协议-->
<!-- <property name="fakeMySQLVersion">5.6.20</property>--> <!--设置模拟的MySQL版本号-->
<!-- <property name="processorBufferChunk">40960</property> -->
<!--
<property name="processors">1</property>
<property name="processorExecutor">32</property>
-->
<!--默认为type 0: DirectByteBufferPool | type 1 ByteBufferArena | type 2 NettyBufferPool -->
<property name="processorBufferPoolType">0</property>
<!--默认是65535 64K 用于sql解析时最大文本长度 -->
<!--<property name="maxStringLiteralLength">65535</property>-->
<!--<property name="sequnceHandlerType">0</property>-->
<!--<property name="backSocketNoDelay">1</property>-->
<!--<property name="frontSocketNoDelay">1</property>-->
<!--<property name="processorExecutor">16</property>-->
<!--
<property name="serverPort">8066</property> <property name="managerPort">9066</property>
<property name="idleTimeout">300000</property> <property name="bindIp">0.0.0.0</property>
<property name="frontWriteQueueSize">4096</property> <property name="processors">32</property> -->
<!--分布式事务开关,0为不过滤分布式事务,1为过滤分布式事务(如果分布式事务内只涉及全局表,则不过滤),2为不过滤分布式事务,但是记录分布式事务日志-->
<property name="handleDistributedTransactions">0</property>
<!--
off heap for merge/order/group/limit 1开启 0关闭
-->
<property name="useOffHeapForMerge">1</property>
<!--
单位为m
-->
<property name="memoryPageSize">64k</property>
<!--
单位为k
-->
<property name="spillsFileBufferSize">1k</property>
<property name="useStreamOutput">0</property>
<!--
单位为m
-->
<property name="systemReserveMemorySize">384m</property>
<!--是否采用zookeeper协调切换 -->
<property name="useZKSwitch">false</property>
<!-- XA Recovery Log日志路径 -->
<!--<property name="XARecoveryLogBaseDir">./</property>-->
<!-- XA Recovery Log日志名称 -->
<!--<property name="XARecoveryLogBaseName">tmlog</property>-->
</system>
<!-- 全局SQL防火墙设置 -->
<!--白名单可以使用通配符%或着*-->
<!--例如<host host="127.0.0.*" user="root"/>-->
<!--例如<host host="127.0.*" user="root"/>-->
<!--例如<host host="127.*" user="root"/>-->
<!--例如<host host="1*7.*" user="root"/>-->
<!--这些配置情况下对于127.0.0.1都能以root账户登录-->
<!--
<firewall>
<whitehost>
<host host="1*7.0.0.*" user="root"/>
</whitehost>
<blacklist check="false">
</blacklist>
</firewall>
-->
<user name="root" defaultAccount="true">
<property name="password">123456</property>
<property name="schemas">TESTDB</property>
<!-- 表级 DML 权限设置 -->
<!--
<privileges check="false">
<schema name="TESTDB" dml="0110" >
<table name="tb01" dml="0000"></table>
<table name="tb02" dml="1111"></table>
</schema>
</privileges>
-->
</user>
<user name="user">
<property name="password">user</property>
<property name="schemas">TESTDB</property>
<property name="readOnly">true</property>
</user>
</mycat:server>
详细作用可以参考官方文档(国人的中间件,文档很好理解),这里提一下用户设置:
<user name="root" defaultAccount="true">
<property name="password">123456</property>
<property name="schemas">TESTDB</property>
</user>
这里的name和password就是项目内需要连接的逻辑库的用户名和密码,schemas是逻辑库的名字,对应schema.xml的schema标签的name。