环境

  • 操作系统:CentOS 7
  • Mysql版本:Mysql8
  • Mycat版本:Mycat1.6.7.6

前提

前提Mysql服务已经搭建好主从复制,Mysql搭建主从复制可参考:Mysql8实现主从复制

配置文件

涉及到需要修改的配置文件 - server.xml:定义用户以及系统相关变量,如端口等 - schema.xml:定义逻辑库,表、分片节点等内容 1. 修改配置文件server.xml

<user name="mycat" defaultAccount="true">       <!-- mycat登陆用户名 -->
<property name="password">123456</property> <!-- mycat登陆密码 -->
<property name="schemas">TESTDB</property> <!-- mycat连接逻辑库 -->
<property name="defaultSchema">TESTDB</property> <!-- mycat连接逻辑库 -->
</user>

配置解释 - user name=”mycat”:通过Mycat服务连接Mysql服务的用户名,可随意修改 - name=”schemas”:Mycat的逻辑库TESTDB,可随意修改 2. 修改配置文件 schema.xml 删除schema标签间的表信息,dataNode标签只留一个,dataHost标签只留一个,writeHost、readHost只留一对

读写分离完整配置文件(一主一从)

这里的配置是一主一从,如果服务器数量条件允许建议搭建双主双从

<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">

<schema name="TESTDB" checkSQLschema="true" sqlMaxLimit="100" randomDataNode="dn1" dataNode="dn1">

</schema>
<dataNode name="dn1" dataHost="host1" database="testdb" />

<dataHost name="host1" maxCon="1000" minCon="10" balance="2"
writeType="0" dbType="mysql" dbDriver="jdbc" switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<!-- can have multi write hosts -->
<writeHost host="hostM1" url="jdbc:mysql://127.0.0.1:3306" user="root"
password="123456">
<readHost host="hostS1" url="jdbc:mysql://127.0.0.2:3306" user="root"
password="123456" />
</writeHost>
</dataHost>
</mycat:schema>

标签解释

schema

  • name:对应Server.xml中配置的逻辑库名TESTDB
  • checkSQLschema:当该值设置为true时,如果我们执行语句select * from TESTDB.travelrecord;则MyCat会把语句修改为select * from travelrecord;即把表示schema的字符去掉,避免发送到后端数据库执行时报(ERROR 1146 (42S02): Table ‘testdb.travelrecord’ doesn’t exist)。不过,即使设置该值为 true ,如果语句所带的是并非是schema指定的名字,例如:select * from db1.travelrecord; 那么MyCat并不会删除db1这个字段,如果没有定义该库的话则会报错,所以在提供SQL语句的最好是不带这个字段。
  • sqlMaxLimit:当该值设置为某个数值时。每条执行的SQL语句,如果没有加上limit语句,MyCat也会自动的加上所对应的值。例如设置值为100,执行select * from TESTDB.travelrecord;的效果为和执行select * from TESTDB.travelrecord limit 100;相同设置该值的话,MyCat默认会把查询到的信息全部都展示出来,造成过多的输出。所以,在正常使用中,还是建议加上一个值,用于减少过多的数据返回。当然SQL语句中也显式的指定limit的大小,不受该属性的约束。需要注意的是,如果运行的schema为非拆分库的,那么该属性不会生效。需要手动添加limit语句。
  • randomDataNode和dataNode:同时存在,指定默认存储节点,比如建表默认会创建到该节点下

dataNode

  • name:节点名称,可随意填写
  • dataHost:对应dataHost标签中name属性值
  • database:真实Mysql服务中创建的数据库名称

dataHost

  • name:主机名称,可随意填写
  • maxCon:指定每个读写实例连接池的最大连接。也就是说,标签内嵌套的writeHost、readHost标签都会使用这个属性的值来实例化出连接池的最大连接数。
  • minCon:指定每个读写实例连接池的最小连接,初始化连接池的大小。
  • balance:负载均衡类型,目前的取值有3种: balance=”0”, 不开启读写分离机制,所有读操作都发送到当前可用的writeHost上。 balance=”1”,全部的readHost与stand by writeHost参与select语句的负载均衡,简单的说,当双主双从模式(M1->S1,M2->S2,并且M1与 M2互为主备),正常情况下,M2,S1,S2都参与select语句的负载均衡。balance=”2”,所有读操作都随机的在writeHost、readhost上分发。balance=”3”,所有读请求随机的分发到wiriterHost对应的readhost执行,writerHost不负担读压力,注意balance=3只在1.4及其以后版本有,1.3没有。
  • writeType:负载均衡类型,目前的取值有3种:writeType=”0”, 所有写操作发送到配置的第一个writeHost,第一个挂了切到还生存的第二个writeHost,重新启动后已切换后的为准,切换记录在配置文件中:dnindex.properties,writeType=”1”,所有写操作都随机的发送到配置的writeHost,1.5以后废弃不推荐。switchType属性 1 表示不自动切换。 1 默认值,自动切换。 2 基于MySQL主从同步的状态决定是否切换。
  • dbType:指定后端连接的数据库类型,目前支持二进制的mysql协议,还有其他使用JDBC连接的数据库。例如:mongodb、oracle、spark等。
  • dbDriver:指定连接后端数据库使用的Driver,目前可选的值有native和JDBC。使用native的话,因为这个值执行的是二进制的mysql协议,所以可以使用mysql和maridb。其他类型的数据库则需要使用JDBC驱动来支持。从1.6版本开始支持postgresql的native原始协议。 如果使用JDBC的话需要将符合JDBC 4标准的驱动JAR包放到MYCAT\lib目录下,并检查驱动JAR包中包括如下目录结构的文件:META-INF\services\java.sql.Driver。在这个文件内写上具体的Driver类名,例如:com.mysql.jdbc.Driver。
  • switchType: -1 表示不自动切换 1 默认值,自动切换 2 基于MySQL主从同步的状态决定是否切换 心跳语句为 show slave status 3 基于MySQL galary cluster的切换机制(适合集群)(1.4.1) 心跳语句为 show status like ‘wsrep%’

heartbeat

这个标签内指明用于和后端数据库进行心跳检查的语句。例如,MYSQL可以使用select user(),Oracle可以使用select 1 from dual等。 这个标签还有一个connectionInitSql属性,主要是当使用Oracla数据库时,需要执行的初始化SQL语句就这个放到这里面来。例如:alter session set nls_date_format=’yyyy-mm-dd hh24:mi:ss’(把这里的中文冒号改为英文冒号),1.4主从切换的语句必须是:show slave status

writeHost(写主机)、readHost(读主机)

这两个标签都指定后端数据库的相关配置给mycat,用于实例化后端连接池。唯一不同的是,writeHost指定写实例、readHost指定读实例,组着这些读写实例来满足系统的要求。 在一个dataHost内可以定义多个writeHost和readHost。但是,如果writeHost指定的后端数据库宕机,那么这个writeHost绑定的所有readHost都将不可用。另一方面,由于这个writeHost宕机系统会自动的检测到,并切换到备用的writeHost上去。

最后重启Mycat服务即可

mycat启动相关命令,要先cd 到mycat\bin\路径下 linux 环境为:

./mycat start 启动
./mycat stop 停止
./mycat console 前台运行
./mycat restart 重启服务
./mycat pause 暂停
./mycat status 查看启动状态

window 启动为: 直接双击运行 startup_nowrap.bat ,如果闪退用 cmd 模式运行查看日志

验证

在写主机插入:insert into mytbl values (1,@@hostname); 这里只是举例,测试的时候可以找到一个varchar类型的新增数据时插入:@@hostname @@hostname:不同主机上的名字会显示不一样,再测试查询这个插入的字段对比是哪台机器的即可,注意查询是要通过登陆Mycat服务查询

关于操作

开发者只需要通过操作Mycat服务去操作数据,不需要关心数据在哪个服务器哪个库中,比如你的后端你是Java,只需要将配置数据库的地方改为mycat的服务即可,CRUD和正常操作Mysql一样即可 比如

jdbc:mysql://127.0.0.1:8066/TESTDB...后面省略
  • 8066:Mycat服务默认端口
  • TESTDB:Mycat配置文件server.xml中配置的逻辑库名

注意事项

如果使用Mycat1.x版本进行分库操作,需要注意跨库目前不支持JOIN操作,分表不分库Mycat1.6.7.6亲测默认支持JOIN操作,无须配置ER表关系