上线mycat

注:本篇文章的操作均在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(这个文件里面定义了用于配置系统参数和给逻辑表分配权限等):

<!DOCTYPE mycat:server SYSTEM "server.dtd">
<mycat:server xmlns:mycat="http://io.mycat/">
        <system>
                                <property name="defaultSqlParser">druidparser</property>
                                <property name="mutiNodeLimitType">1</property>
                                <property name="useSqlStat">1</property>  <!-- 1为开启实时统计、0为关闭 -->
                                <property name="mutiNodePatchSize">1000</property>
                                <property name="serverPort">8066</property>
                                <property name="managerPort">9066</property>
        </system>

        <!-- 全局SQL防火墙设置 -->
        <!--
        <firewall>
           <whitehost>
              <host host="127.0.0.1" user="mycat"/>
              <host host="127.0.0.2" user="mycat"/>
           </whitehost>
       <blacklist check="false">
       </blacklist>
        </firewall>
        -->

        <user name="root">
                <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>

里面配置了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文件:

<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
    <schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100">
                <table name="user_freeze" primaryKey="id" subTables="user_freeze_2018$10-11,user_freeze" rule="sharding-by-month" dataNode="exchange" />
                <table name="rate" primaryKey="id"  dataNode="exchange" />
                <table name="user_order" primaryKey="id"  dataNode="exchange" />
                <table name="user_identity" primaryKey="id"  dataNode="exchange" />
                <table name="user_account" primaryKey="id"  dataNode="exchange" />
                <table name="user_info" primaryKey="id"  dataNode="exchange" />
                <table name="user_withdraw" primaryKey="id"  dataNode="exchange" />
                <table name="user_recharge" primaryKey="id"  dataNode="exchange" />
                <table name="user_running" primaryKey="id"  dataNode="exchange" />
                <table name="user_exchange_log" primaryKey="id"  dataNode="exchange" />
                <table name="user_exchange" primaryKey="id"  dataNode="exchange" />
                <table name="user_transfer" primaryKey="id"  dataNode="exchange" />
                <table name="deals" primaryKey="id" subTables="deals_2018$10-12,deals_2019$1-2" rule="sharding-by-month"  dataNode="exchange_bonus" />
                <table name="user_et_running" primaryKey="id"  dataNode="exchange_bonus" />
                <table name="invite_relation" primaryKey="id"  dataNode="exchange_bonus" />
                <table name="invite_relation_usdt" primaryKey="id"  dataNode="exchange_bonus" />
                <table name="invite" primaryKey="id"  dataNode="exchange_bonus" />
                <table name="deals_signal" primaryKey="id"  dataNode="exchange_bonus" />
                <table name="bonus_signal" primaryKey="id"  dataNode="exchange_bonus" />
                <table name="airdrop_signal" primaryKey="id"  dataNode="exchange_bonus" />
                <table name="invite_count" primaryKey="id"  dataNode="exchange_bonus" />
                <table name="invite_usdt" primaryKey="id"  dataNode="exchange_bonus" />
                <table name="mine" primaryKey="id"  dataNode="exchange_bonus" />
                <table name="recharge_running" primaryKey="id"  dataNode="exchange_bonus" />
                <table name="stats_amount_day" primaryKey="id"  dataNode="exchange_bonus" />
                <table name="stats_amount_hour" primaryKey="id"  dataNode="exchange_bonus" />
                <table name="stats_fee_hour" primaryKey="id"  dataNode="exchange_bonus" />
                <table name="stats_user_amount_day" primaryKey="id"  dataNode="exchange_bonus" />
                <table name="stats_user_amount_hour" primaryKey="id"  dataNode="exchange_bonus" />
                <table name="stats_user_fee_hour" primaryKey="id"  dataNode="exchange_bonus" />
                <table name="user_airdrop" primaryKey="id"  dataNode="exchange_bonus" />
                <table name="user_bonus" primaryKey="id"  dataNode="exchange_bonus" />
                <table name="user_et_balance" primaryKey="id"  dataNode="exchange_bonus" />
        <!--    <table name="robot" primaryKey="id"  dataNode="exchange_financial_risk" />
                <table name="robot_recharge" primaryKey="id"  dataNode="exchange_financial_risk" />-->
    </schema>
  <!--  <dataNode name="exchange_financial_risk" dataHost="dataHost01" database="exchange_financial_risk" />-->
    <dataNode name="exchange" dataHost="dataHost02" database="exchange" />
    <dataNode name="exchange_bonus" dataHost="dataHost01" database="exchange_bonus" />
    <dataNode name="exchange_statistic" dataHost="dataHost01" database="exchange_statistic" />

    <dataHost name="dataHost01" maxCon="100" minCon="10" balance="1" writeType="0" dbType="mysql" dbDriver="jdbc" switchType="1"  slaveThreshold="100">
            <heartbeat>select 1</heartbeat>
            <writeHost host="hostM1" url="jdbc:mysql://exchange-cluster.cluster-clwklichzgk5.ap-northeast-1.rds.amazonaws.com" user="app" password="exchain@2018">
                        <readHost host="hostS1" url="jdbc:mysql://exchange-cluster.cluster-ro-clwklichzgk5.ap-northeast-1.rds.amazonaws.com" user="app" password="exchain@2018" />
            </writeHost>
    </dataHost>
    <dataHost name="dataHost02" maxCon="100"  minCon="10" balance="1" writeType="0" dbType="mysql" dbDriver="jdbc" switchType="1"  slaveThreshold="100">
            <heartbeat>select 1</heartbeat>
            <writeHost host="hostM1" url="jdbc:mysql://exchain-cluster.cluster-clwklichzgk5.ap-northeast-1.rds.amazonaws.com" user="app" password="exchain@2018">
                         <readHost host="hostS1" url="jdbc:mysql://exchain-cluster.cluster-ro-clwklichzgk5.ap-northeast-1.rds.amazonaws.com" user="app" password="exchain@2018" />
            </writeHost>
    </dataHost>
</mycat:schema>

这里对连接的mysql做了读写分离和分库分表

参数说明
schema数据库设置,此数据库为逻辑数据库,name与server.xml中schema对应
dataNode分片信息,也就是分库相关配置
dataHost物理数据库,真正存储数据的数据库

schema:

schema标签用来定义mycat实例中的逻辑库,mycat可以有多个逻辑库,每个逻辑库都有自己的相关配置。可以使用schema标签来划分这些不同的逻辑库。

如果不配置schema标签,所有表的配置会属于同一个默认的逻辑库。

逻辑库的概念和MySql的database的概念一样,我们在查询两个不同逻辑库中的表的时候,需要切换到该逻辑库下进行查询
注意:进行查询的时候需要在server.xml配置相关用户权限信息 

属性说明
name逻辑数据库名,与server.xml中的schema对应
checkSQLschema数据库前缀相关设置,建议看文档,这里暂时设为folse
sqlMaxLimitselect 时默认的limit,避免查询全表

     table:

属性说明
name表名,物理数据库中表名
dataNode表存储到哪些节点,多个节点用逗号分隔。节点为下文dataNode设置的name
primaryKey主键字段名,自动生成主键时需要设置
autoIncrement是否自增
rule分片规则名,具体规则下文rule详细介绍

    subTables 支持按月分表 $201701-? 配置

基于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目录中查看日志。

  • wrapper.log 为程序启动的日志,启动时的问题看这个
  • mycat.log 为脚本执行时的日志,SQL脚本执行报错后的具体错误内容,查看这个文件。mycat.log是最新的错误日志,历史日志会根据时间生成目录保存。

连接:

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.<init>(XMLSchemaLoader.java:71)
jvm 1    |     at org.opencloudb.config.loader.xml.XMLSchemaLoader.<init>(XMLSchemaLoader.java:75)
jvm 1    |     at org.opencloudb.ConfigInitializer.<init>(ConfigInitializer.java:63)
jvm 1    |     at org.opencloudb.MycatConfig.<init>(MycatConfig.java:69)
jvm 1    |     at org.opencloudb.MycatServer.<init>(MycatServer.java:105)
jvm 1    |     at org.opencloudb.MycatServer.<clinit>(MycatServer.java:73)
jvm 1    |     ... 7 more
wrapper  | <-- Wrapper Stopped

2、解决方法:

修改schema.xml

<dataHost name="mycat" maxCon="1000" minCon="10" balance="0"
        writeType="0" dbType="mysql" dbDriver="
native" switchType="1"  slaveThreshold="100">
        <heartbeat>select user()</heartbeat>
        <!-- can have multi write hosts -->
        <writeHost host="mycat" url="
192.168.4.116:3306" user="root"
            password="123456">
            <!-- can have multi read hosts -->
            <!--<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>

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.<init>(XMLSchemaLoader.java:83)
INFO   | jvm 1    | 2018/11/16 11:26:15 |       at io.mycat.config.loader.xml.XMLSchemaLoader.<init>(XMLSchemaLoader.java:87)
INFO   | jvm 1    | 2018/11/16 11:26:15 |       at io.mycat.config.ConfigInitializer.<init>(ConfigInitializer.java:74)
INFO   | jvm 1    | 2018/11/16 11:26:15 |       at io.mycat.config.MycatConfig.<init>(MycatConfig.java:72)
INFO   | jvm 1    | 2018/11/16 11:26:15 |       at io.mycat.MycatServer.<init>(MycatServer.java:144)
INFO   | jvm 1    | 2018/11/16 11:26:15 |       at io.mycat.MycatServer.<clinit>(MycatServer.java:96)
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">
            <heartbeat>select 1</heartbeat>
            <writeHost host="hostM1" url="jdbc:mysql://exchange-cluster.cluster-clwklichzgk5.ap-northeast-1.rds.amazonaws.com" user="app" password="exchain@2018">

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命令的路径)

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值