这里主要对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。