注:本篇文章的操作均在centos7.5下。
mycat是mysql的中间件,它可以做mysql数据库的读写分离、分库分表。
安装:
1)安装java
因Mycat是用java开发的,所以需要在实验环境下安装java,官方建议jdk1.7及以上版本
Java Oracle官方下载地址为:
http://www.oracle.com/technetwork/java/javase/archive-139210.html
在环境变量中加入下载的jdk:
sudo vim /etc/profile
export JAVA_HOME=/usr/local/jdk1.8.0_191
export CLASSPATH=.:$JAVA_HOME/jre/lib/rt.jar:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
export PATH=$PATH:$JAVA_HOME/bin
:wq
source /etc/profile
如果配置完成后出现以下报错:
这时需要安装一个:yum -y install glibc.i686。
2)安装mycat:
去mycat官网下载一个软件包,什么系统下载什么样的软件包!!!
Mycat官网:http://www.mycat.io/
可以了解下Mycat的背景和应用情况,这样使用起来比较有信心。
Mycat下载地址:http://dl.mycat.io/
官网有个文档,属于详细的介绍,初次入门,看起来比较花时间。
tar -xvf Mycat-server-1.6-RELEASE-20161028204710-linux.tar.gz -C /usr/local/
cd /usr/local/mycat
配置:
这时就已经安装完了,启动还需要修改4个文件:rule.xml、server.xml、schema.xml、wrapper.conf
修改rule.xml (这个文件中写的都是mycat分库分表的算法):
默认是不需要修改的。
修改server.xml(这个文件里面定义了用于配置系统参数和给逻辑表分配权限等):
druidparser
1
1
1000
8066
9066
123456
TESTDB
user
TESTDB
true
里面配置了mycat的管理端口9066和服务端口8066,登陆的地址,逻辑表分配权限。
参数 | 说明 |
---|---|
user | 用户配置节点 |
--name | 登录的用户名,也就是连接Mycat的用户名 |
--password | 登录的密码,也就是连接Mycat的密码 |
--schemas | 数据库名,这里会和schema.xml中的配置关联,多个用逗号分开,例如需要这个用户需要管理两个数据库db1,db2,则配置db1,dbs |
--privileges | 配置用户针对表的增删改查的权限,具体见文档吧 |
里面有几个参数要注意:
idleTimeout:指定连接的空闲超时时间,默认是30分钟,所以在配置数据源的时候,数据源的超时时间要小于mycat的空闲超时时间。
charset:连接的初始化字符集,默认是utf8
txlsolation:前端连接的初始化事务隔离级别,默认是和mysql的repeated_read可重复读隔离级别一致
sqlExecuteTimeout:sql执行超时时间,默认是300秒。
重点!!!修改schema.xml文件:
select 1
select 1
这里对连接的mysql做了读写分离和分库分表
参数 | 说明 |
---|---|
schema | 数据库设置,此数据库为逻辑数据库,name与server.xml中schema对应 |
dataNode | 分片信息,也就是分库相关配置 |
dataHost | 物理数据库,真正存储数据的数据库 |
schema:
schema标签用来定义mycat实例中的逻辑库,mycat可以有多个逻辑库,每个逻辑库都有自己的相关配置。可以使用schema标签来划分这些不同的逻辑库。
如果不配置schema标签,所有表的配置会属于同一个默认的逻辑库。
逻辑库的概念和MySql的database的概念一样,我们在查询两个不同逻辑库中的表的时候,需要切换到该逻辑库下进行查询
注意:进行查询的时候需要在server.xml配置相关用户权限信息
属性 | 说明 |
---|---|
name | 逻辑数据库名,与server.xml中的schema对应 |
checkSQLschema | 数据库前缀相关设置,建议看文档,这里暂时设为folse |
sqlMaxLimit | select 时默认的limit,避免查询全表 |
table:
属性 | 说明 |
---|---|
name | 表名,物理数据库中表名 |
dataNode | 表存储到哪些节点,多个节点用逗号分隔。节点为下文dataNode设置的name |
primaryKey | 主键字段名,自动生成主键时需要设置 |
autoIncrement | 是否自增 |
rule | 分片规则名,具体规则下文rule详细介绍 |
基于MyCat1.6正式版的源码修改的,支持subTables的按月分表正则配置 subTables=“ tableName_$201701-?” subTableWay="BYMONTH" 表示从201701月份开始进行分表处理,?表示当前日期的月份,是动态的。只需配置开始日期即可,首先要确定的一点就是子表要在mysql里面真实存在,可以进行动态创建表达到子表的自动增长。subTableWay是表示按月,也可以按照日期,及subTableWay="BYDATE"
dataNode(标签定义了mycat中的数据节点,也就是我们所说的数据分片。一个datanode标签就是一个独立的数据分片。)
属性 | 说明 |
---|---|
name | 节点名,与table中dataNode对应 |
datahost | 物理数据库名,与datahost中name对应 |
database | 物理数据库中数据库名 |
dataHost
属性 | 说明 |
---|---|
name | 物理数据库名,与dataNode中dataHost对应 |
balance | 均衡负载的方式 |
writeType | 写入方式 |
dbType | 数据库类型 |
heartbeat | 心跳检测语句,注意语句结尾的分号要加。 |
maxCon
指定每个读写实例连接池的最大连接。
minCon
指定每个读写实例连接池的最小连接,初始化连接池的大小
balance
负载均称类型
0:不开启读写分离机制,所有读操作都发送到当前可用的writeHost上
1:全部的readHost与stand by writeHost参与select语句的负载均衡,简单的说,当双主双从模式(M1-S1,M2-S2 并且M1 M2互为主备),正常情况下,M2,S1,S2都参与select语句的负载均衡。
2:所有读操作都随机的在writeHost、readHost上分发
3:所有读请求随机的分发到writeHst对应的readHost执行,writeHost不负担读写压力。(1.4之后版本有)
writeType属性
负载均衡类型。
0:所有的写操作发送到配置的第一个writeHost,第一个挂了切换到第二个。切换记录在文件dnindex.properties
1:所有的鞋操作都随机的发送到配置的writeHost,1.5以后版本废弃不推荐。
switchType属性
-1不自动切换
1 默认值 自动切换
2 基于MySql主从同步的状态决定是否切换
心跳语句为 show slave status
3 基于mysql galary cluster 的切换机制(适合集群)1.4.1
心跳语句为 show status like 'wsrep%'
dbType
指定后端链接的数据库类型目前支持二进制的mysql协议,还有其他使用jdbc链接的数据库
dbDriver属性
指定连接后段数据库使用的driver,目前可选的值有native和JDBC。使用native的话,因为这个值执行的是二进制的mysql协议,所以可以使用mysql和maridb,其他类型的则需要使用JDBC驱动来支持。
如果使用JDBC的话需要符合JDBC4标准的驱动jar 放到mycat\lib目录下,并检查驱动jar包中包括如下目录结构文件 META-INF\services\java.sql.Driver。 在这个文件写上具体的driver类名,例如com.mysql.jdbc.Driver
writeHost readHost
指定后端数据库的相关配置给mycat,用于实例化后端连接池
slaveThreshold="100"
Mycat心跳检查语句配置为 show slave status ,dataHost 上定义两个新属性: switchType=“2” 与slaveThreshold=“100”,此时意味着开启MySQL主从复制状态绑定的读写分离与切换机制。Mycat心跳机制通过检测 show slave status 中的 “Seconds_Behind_Master”, “Slave_IO_Running”,“Slave_SQL_Running” 三个字段来确定当前主从同步的状态以及Seconds_Behind_Master主从复制时延。
Mycat的启动也很简单,启动命令在Bin目录:
##启动
mycat start
##停止
mycat stop
##重启
mycat restart
如果在启动时发现异常,在logs目录中查看日志。
连接:
mysql -h127.0.0.1 -P8066 -uroot -p123456
Mycat还有一个管理的连接,端口号是9906.
mysql -h127.0.0.1 -P9066 -uroot -p123456
连接后可以根据管理命令查看Mycat的运行情况,当然,喜欢UI管理方式的人,可以安装一个Mycat-Web来进行管理,有兴趣自行搜索。
Mycat是不是配置以后,就能完全解决分表分库和读写分离问题?
Mycat配合数据库本身的复制功能,可以解决读写分离的问题,但是针对分表分库的问题,不是完美的解决。或者说,至今为止,业界没有完美的解决方案。
分表分库写入能完美解决,但是,不能完美解决主要是联表查询的问题,Mycat支持两个表联表的查询,多余两个表的查询不支持。 其实,很多数据库中间件关于分表分库后查询的问题,都是需要自己实现的,而且节本都不支持联表查询
Mycat支持哪些数据库,其他平台如 .net、PHP能用吗?
官方说了,支持的数据库包括MySQL、SQL Server、Oracle、DB2、PostgreSQL 等主流数据库,很赞。
尽量用Mysql,我试过SQL Server,会有些小问题,因为部分语法有点差异。
Mycat 非JAVA平台如 .net、PHP能用吗?
可以用。这一点MyCat做的也很棒。
1)启动mycat时报错信息如下:
[root@mycat ]# /usr/local/mycat/bin/mycat console start
Running Mycat-server...
wrapper | --> Wrapper Started as Console
wrapper | Launching a JVM...
jvm 1 | Java HotSpot(TM) 64-Bit Server VM warning: ignoring option MaxPermSize=64M; support was removed in 8.0
jvm 1 | Wrapper (Version 3.2.3) http://wrapper.tanukisoftware.org
jvm 1 | Copyright 1999-2006 Tanuki Software, Inc. All Rights Reserved.
jvm 1 |
jvm 1 |
jvm 1 | WrapperSimpleApp: Encountered an error running main: java.lang.ExceptionInInitializerError
jvm 1 | java.lang.ExceptionInInitializerError
jvm 1 | at org.opencloudb.MycatStartup.main(MycatStartup.java:50)
jvm 1 | at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
jvm 1 | at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
jvm 1 | at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
jvm 1 | at java.lang.reflect.Method.invoke(Method.java:498)
jvm 1 | at org.tanukisoftware.wrapper.WrapperSimpleApp.run(WrapperSimpleApp.java:240)
jvm 1 | at java.lang.Thread.run(Thread.java:748)
jvm 1 | Caused by: org.opencloudb.config.util.ConfigException: dataNode node_db01 reference dataHost:mycat not exists!
jvm 1 | at org.opencloudb.config.loader.xml.XMLSchemaLoader.createDataNode(XMLSchemaLoader.java:545)
jvm 1 | at org.opencloudb.config.loader.xml.XMLSchemaLoader.loadDataNodes(XMLSchemaLoader.java:516)
jvm 1 | at org.opencloudb.config.loader.xml.XMLSchemaLoader.load(XMLSchemaLoader.java:106)
jvm 1 | at org.opencloudb.config.loader.xml.XMLSchemaLoader.
jvm 1 | at org.opencloudb.config.loader.xml.XMLSchemaLoader.
jvm 1 | at org.opencloudb.ConfigInitializer.
jvm 1 | at org.opencloudb.MycatConfig.
jvm 1 | at org.opencloudb.MycatServer.
jvm 1 | at org.opencloudb.MycatServer.
jvm 1 | ... 7 more
wrapper | <-- Wrapper Stopped
2、解决方法:
修改schema.xml
password="123456">
2)url直接写成域名报错!
报错信息如下:
WrapperSimpleApp: Encountered an error running main: java.lang.ExceptionInInitializerError
INFO | jvm 1 | 2018/11/16 11:26:15 | java.lang.ExceptionInInitializerError
INFO | jvm 1 | 2018/11/16 11:26:15 | at io.mycat.MycatStartup.main(MycatStartup.java:53)
INFO | jvm 1 | 2018/11/16 11:26:15 | at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
INFO | jvm 1 | 2018/11/16 11:26:15 | at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
INFO | jvm 1 | 2018/11/16 11:26:15 | at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
INFO | jvm 1 | 2018/11/16 11:26:15 | at java.lang.reflect.Method.invoke(Method.java:606)
INFO | jvm 1 | 2018/11/16 11:26:15 | at org.tanukisoftware.wrapper.WrapperSimpleApp.run(WrapperSimpleApp.java:240)
INFO | jvm 1 | 2018/11/16 11:26:15 | at java.lang.Thread.run(Thread.java:745)
INFO | jvm 1 | 2018/11/16 11:26:15 | Caused by: io.mycat.config.util.ConfigException: java.lang.StringIndexOutOfBoundsException: String index out of range: -1
INFO | jvm 1 | 2018/11/16 11:26:15 | at io.mycat.config.loader.xml.XMLSchemaLoader.load(XMLSchemaLoader.java:126)
INFO | jvm 1 | 2018/11/16 11:26:15 | at io.mycat.config.loader.xml.XMLSchemaLoader.
INFO | jvm 1 | 2018/11/16 11:26:15 | at io.mycat.config.loader.xml.XMLSchemaLoader.
INFO | jvm 1 | 2018/11/16 11:26:15 | at io.mycat.config.ConfigInitializer.
INFO | jvm 1 | 2018/11/16 11:26:15 | at io.mycat.config.MycatConfig.
INFO | jvm 1 | 2018/11/16 11:26:15 | at io.mycat.MycatServer.
INFO | jvm 1 | 2018/11/16 11:26:15 | at io.mycat.MycatServer.
INFO | jvm 1 | 2018/11/16 11:26:15 | ... 7 more
INFO | jvm 1 | 2018/11/16 11:26:15 | Caused by: java.lang.StringIndexOutOfBoundsException: String index out of range: -1
INFO | jvm 1 | 2018/11/16 11:26:15 | at java.lang.String.substring(String.java:1911)
INFO | jvm 1 | 2018/11/16 11:26:15 | at io.mycat.config.loader.xml.XMLSchemaLoader.createDBHostConf(XMLSchemaLoader.java:687)
INFO | jvm 1 | 2018/11/16 11:26:15 | at io.mycat.config.loader.xml.XMLSchemaLoader.loadDataHosts(XMLSchemaLoader.java:776)
INFO | jvm 1 | 2018/11/16 11:26:15 | at io.mycat.config.loader.xml.XMLSchemaLoader.load(XMLSchemaLoader.java:118)
INFO | jvm 1 | 2018/11/16 11:26:15 | ... 13 more
STATUS | wrapper | 2018/11/16 11:26:17 | <-- Wrapper Stopped
STATUS | wrapper | 2018/11/16 11:32:57 | --> Wrapper Started as Daemon
解决方法:需要修改dbDriver为jdbc,url需要加前缀jdbc:mysql://
dbType="mysql" dbDriver="jdbc" switchType="1" slaveThreshold="100">
3)还有1个报错会在启动时直接在屏幕上输出找不到二进制文件的错误
输出这个错误是由于wrapper.conf文件java的配置有问题,
错误的:wrapper.java.command=/data/mycat/jdk1.7.0_80/(只写java的home路径会报错)
正确的:wrapper.java.command=/data/mycat/jdk1.7.0_80/bin/java(需要写上java命令的路径)