mycat搭建(基于mysql主从)

一、快速启动

mysql主从搭建请点击这里
下载安装包:http://dl.mycat.io/1.6.7.4/,我这里下载的是1.6.7.4(目前最新发布版),运行bin目录下:

#linux环境下
./mycat start 启动
./mycat stop 停止
./mycat console 前台运行
./mycat restart 重启服务
./mycat pause 暂停
./mycat status 查看启动状态
#windows环境
直接运行startup_nowrap.bat,如果出现闪退,在cmd 命令行运行,查看出错原因。

二、配置

配置文件存放在conf目录下:

  • schema.xml 是逻辑库定义和表以及分片定义的配置文件。
  • rule.xml 是分片规则的配置文件,分片规则的具体一些参数信息单独存放为文件,也在这个目录下,配置文件修改需要重启MyCAT
  • server.xml 是Mycat服务器参数调整和用户授权的配置文件。
  • log4j.xml: 日志存放在logs/log中,每天一个文件,日志的配置是在conf/log4j.xml中,根据自己的需要可以调整输出级别为debug,debug级别下,会输出更多的信息,方便排查问题。
  • autopartition-long.txt,partition-hash-int.txt,sequence_conf.properties,sequence_db_conf.properties 分片相关的id分片规则配置文件

lib MyCAT自身的jar包或依赖的jar包的存放目录。
logs MyCAT日志的存放目录。日志存放在logs/log中,每天一个文件

2.1 server.xml(Mycat环境参数配置)

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE mycat:server SYSTEM "server.dtd">
<mycat:server xmlns:mycat="http://org.opencloudb/">
<mycat:server xmlns:mycat="http://org.opencloudb/">
   <system>
      <property name="defaultSqlParser">druidparser</property>
    </system> 
</mycat:server>

如例子中配置的所有的Mycat参数变量都是配置在server.xml 文件中,system标签下配置所有的参数,如果需要配置某个变量添加相应的配置即可,例如添加启动端口8066,默认为8066:<property name="serverPort">8066</property>

配置Mycat逻辑库与用户:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE mycat:server SYSTEM "server.dtd">
<mycat:server xmlns:mycat="http://org.opencloudb/">
<user name="mycat">
    <property name="password">mycat</property>
    <property name="schemas">TESTDB</property>
</user>
 </mycat:server>

如例子中配置的所有的Mycat连接的用户与逻辑库映射都是配置在server.xml 文件中,user标签下配置所有的参数,例如例子中配置了一个mycat用户供应用连接到mycat,同时mycat 在schema.xml中配置后了一个逻辑库TESTDB,配置好逻辑库与用户的映射关系。

2.2schema.xml(逻辑库配置)

Mycat作为一个中间件,实现mysql协议那么对前端应用连接来说就是一个数据库,也就有数据库的配置,mycat的数据库配置是在schema.xml中配置,配置好后映射到server.xml里面的用户就可以了。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema  xmlns:mycat="http://org.opencloudb/">
  <schema name="TESTDB" checkSQLschema="true" sqlMaxLimit="100" dataNode="dn1">
      <table name="t_user" dataNode="dn1,dn2" rule="sharding-by-mod2"/>
      <table name="ht_jy_login_log" primaryKey="ID" dataNode="dn1,dn2" rule="sharding-by-date_jylog"/>
  </schema>
  <dataNode name="dn1" dataHost="localhost1" database="mycat_node1"/>
  <dataNode name="dn2" dataHost="localhost1" database="mycat_node2"/>
  
  <dataHost name="localhost1" writeType="0" switchType="1" slaveThreshold="100" balance="1" dbType="mysql" maxCon="10" minCon="1" dbDriver="native">
    <heartbeat>show status like 'wsrep%'</heartbeat>
    <writeHost host="hostM1" url="127.0.0.1:3306" user="root" password="root" >
    </writeHost>  
  </dataHost>
</mycat:schema >

上面例子配置了一个逻辑库TESTDB,同时配置了t_user,ht_jy_login_log两个分片表。
逻辑表配置:

<table name="t_user" dataNode="dn1,dn2" rule="sharding-by-mod2"/>
table 标签 是逻辑表的配置其中
name代表表名,
dataNode代表表对应的分片,
Mycat默认采用分库方式,也就是一个表映射到不同的库上,
rule代表表要采用的数据切分方式,名称对应到rule.xml中的对应配置,如果要分片必须配置。

配置分片(dataNode):

<dataNode name="dn1" dataHost="localhost1" database="mycat_node1"/>
<dataNode name="dn2" dataHost="localhost1" database="mycat_node2"/>
表切分后需要配置映射到哪几个数据库中,Mycat的分片实际上就是库的别名,例如上面例子配置了两个分片dn1,dn2 分别对应到物理机映射dataHost localhost1 的两个库上。

配置物理库分片映射(dataHost):

<dataHost name="localhost1" writeType="0" switchType="1" slaveThreshold="100" balance="1" dbType="mysql" maxCon="10" minCon="1" dbDriver="native">
    <heartbeat>show status like 'wsrep%'</heartbeat>
    <writeHost host="hostM1" url="127.0.0.1:3306" user="root" password="root" >
    </writeHost>  
  </dataHost>
Mycat作为数据库代理需要逻辑库,逻辑用户,表切分后需要配置分片,分片也就需要映射到真实的物理主机上,至于是映射到一台还是一台的多个实例上,Mycat并不关心,只需要配置好映射即可,例如例子中:
配置了一个名为localhost1的物理主机(dataHost)映射。
heartbeat 标签代表Mycat需要对物理库心跳检测的语句,正常情况下生产案例可能配置主从,或者多写 或者单库,无论哪种情况Mycat都需要维持到数据库的数据源连接,因此需要定时检查后端连接可以性,心跳语句就是来作为心跳检测。
writeHost 此标签代表 一个逻辑主机(dataHost)对应的后端的物理主机映射,例如例子中写库hostM1 映射到127.0.0.1:3306。如果后端需要做读写分离或者多写 或者主从则通过配置 多个writeHost 或者readHost即可。
dataHost 标签中的 writeType balance 等标签则是不同的策略

主从配置:

<dataHost name="localhost1" maxCon="10" minCon="5" balance="3"
                          writeType="0" dbType="mysql" dbDriver="native" switchType="1"  slaveThreshold="100">
        <heartbeat>select user()</heartbeat>
        <!-- can have multi write hosts -->
        <writeHost host="hostM1" url="192.168.126.128:3306" user="root"
                           password="123456">
                <readHost host="hostS1" url="192.168.126.129:3306" user="root" password="123456" />
        </writeHost>
        <!-- <writeHost host="hostM2" url="localhost:3316" user="root" password="123456"/> -->
</dataHost>
balance 属性 
负载均衡类型,目前的取值有 3 种:
1.balance="0", 不开启读写分离机制,所有读操作都发送到当前可用的 writeHost 上。 
2.balance="1",全部的 readHost 与 stand by writeHost 参与 select 语句的负载均衡,简单的说,当双 
主双从模式(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 及其以后版本有,1.3 没有
writeType 属性 
负载均衡类型,目前的取值有 3 种: 
1. writeType="0", 所有写操作发送到配置的第一个 writeHost,第一个挂了切到还生存的第二个 writeHost, 
重新启动后已切换后的为准,切换记录在配置文件中:dnindex.properties . 
2. writeType="1",所有写操作都随机的发送到配置的 writeHost,1.5 以后废弃不推荐。

switchType 属性 
-1 表示不自动切换 
1 默认值,自动切换 
2 基于 MySQL 主从同步的状态决定是否切换
心跳语句为 show slave status 
3 基于 MySQL galary cluster 的切换机制(适合集群)(1.4.1) 
心跳语句为 show status like 'wsrep%'

2.3 rule.xml(表切分规则配置)

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mycat:rule SYSTEM "rule.dtd">
<mycat:rule  xmlns:mycat="http://org.opencloudb/">
  <tableRule name="sharding-by-hour">
    <rule>
      <columns>createTime</columns>
      <algorithm>sharding-by-hour</algorithm>
    </rule>
  </tableRule> 
  <function name="sharding-by-hour" class="org.opencloudb.route.function.LatestMonthPartion">
    <property name="splitOneDay">24</property>
  </function>  
</mycat:rule >

数据切分中作为表切分规则中最重要的配置,表的切分方式决定了数据切分后的性能好坏,因此也是最重要的配置。
如上面例子配置了一个切分规则,名为sharding-by-hour 对应的切分方式(function )是按日期切分,该配置中:

tableRule 表分片规则
  1. name 为schema.xml 中table 标签中对应的 rule="sharding-by-hour" ,也就是配置表的分片规则
  2. columns 是表的切分字段: createTime 创建日期。
  3. algorithm 是规则对应的切分规则:映射到function 的name。
function 分片规则函数
  1. name 为切分规则的名称,名字任意取,但是需要与tableRule 中匹配。
  2. class 是切分规则对应的切分类,写死,需要哪种规则则配置哪种,例如本例子是按小时分片:org.opencloudb.route.function.LatestMonthPartion
  3. property 标签是切分规则对应的不同属性,不同的切分规则配置不同。
常见的分片策略
  • 分片枚举
    通过在配置文件中配置可能的枚举 id,自己配置分片,本规则适用于特定的场景,比如有些业务需要按照省 份或区县来做保存,而全国省份区县固定的,这类业务使用本条规则

  • 固定分片 hash 算法
    本条规则类似于十进制的求模运算,区别在于是二进制的操作,是取 id 的二进制低 10 位,即 id 二进制 &1111111111。 此算法的优点在于如果按照 10 进制取模运算,在连续插入 1-10 时候 1-10 会被分到 1-10 个分片,增 大了插入的事务控制难度,而此算法根据二进制则可能会分到连续的分片,减少插入事务事务控制难度。

id=1
0000000001&1111111111=0000000001
<tableRule name="rule1">
    <rule>
        <columns>user_id</columns>
        <algorithm>func1</algorithm>
    </rule>
</tableRule>
<function name="func1" class="io.mycat.route.function.PartitionByLong">
    <property name="partitionCount">2,1</property>
    <property name="partitionLength">256,512</property>
</function>  

配置说明: 上面 columns 标识将要分片的表字段,algorithm 分片函数, partitionCount 分片个数列表,partitionLength 分片范围列表 分区长度:默认为最大 2^n=1024 ,即最大支持 1024 分区
约束: count,length 两个数组的长度必须是一致的。 1024 = sum((count[i]*length[i])). count 和 length 两个向量的点积恒等于 1024
用法例子: 本例的分区策略:希望将数据水平分成 3 份,前两份各占 25%,第三份占 50%。(故本例非均匀分区) // |<-------1024----------->|

  • 范围约定
    此分片适用于,提前规划好分片字段某个范围属于哪个分片
<tableRule name="auto-sharding-long"> 
    <rule> 
        <columns>user_id</columns> 
        <algorithm>rang-long</algorithm> 
    </rule> 
</tableRule> 
<function name="rang-long" class="io.mycat.route.function.AutoPartitionByLong"> 
    <property name="mapFile">autopartition-long.txt</property> 
    <property name="defaultNode">0</property> 
</function>

配置说明:
上面 columns 标识将要分片的表字段,
algorithm 分片函数,
rang-long 函数中
mapFile 代表配置文件路径
defaultNode 超过范围后的默认节点。
所有的节点配置都是从 0 开始,及 0 代表节点 1,此配置非常简单
在配置文件autopartition-long.txt中即预先制定可能的 id 范围到某个分片
0-500M=0
500M-1000M=1
1000M-1500M=2

0-10000000=0
10000001-20000000=1
注意:K=1000,M=10000

  • 取模
    此规则为对分片字段求摸运算
<tableRule name="mod-long"> 
    <rule> 
        <columns>user_id</columns> 
        <algorithm>mod-long</algorithm> 
    </rule> 
</tableRule> 
<function name="mod-long" class="io.mycat.route.function.PartitionByMod"> 
    <!-- how many data nodes --> 
    <property name="count">3</property> 
</function>  

配置说明: 上面 columns 标识将要分片的表字段,algorithm 分片函数, 此种配置非常明确即根据 id 进行十进制求模预算,相比固定分片 hash,此种在批量插入时可能存在批量插入单 事务插入多数据分片,增大事务一致性难度。

  • 按日期(天)分片
    此规则为按天分片
<tableRule name="sharding-by-date">
    <rule>
        <columns>create_time</columns>
        <algorithm>sharding-by-date</algorithm>
    </rule>
</tableRule>
<function name="sharding-by-date" class="io.mycat.route.function.PartitionByDate">
    <property name="dateFormat">yyyy-MM-dd</property>
    <property name="sBeginDate">2014-01-01</property> 
    <property name="sEndDate">2014-01-02</property> 
    <property name="sPartionDay">10</property> 
</function>
  • 冷热数据分片
    根据日期查询日志数据 冷热数据分布 ,最近 n 个月的到实时交易库查询,超过 n 个月的按照 m 天分片。
<function name="sharding-by-hotdate" class="io.mycat.route.function.PartitionByHotDate"> 
    <property name="dateFormat">yyyy-MM-dd</property> 
    <property name="sLastDay">10</property> 
    <property name="sPartionDay">10</property> 
</function>

2.4全局自增序列号

1. 本地文件方式

原理:此方式 MyCAT 将 sequence 配置到文件中,当使用到 sequence 中的配置后,MyCAT 会更下classpath 中的 sequence_conf.properties 文件中 sequence 当前的值。
配置方式:
在 sequence_conf.properties 文件中做如下配置:

  GLOBAL_SEQ.HISIDS= 
  GLOBAL_SEQ.MINID=1001 
  GLOBAL_SEQ.MAXID=1000000000 
  GLOBAL_SEQ.CURID=1000 

其中 HISIDS 表示使用过的历史分段(一般无特殊需要可不配置),MINID 表示最小 ID 值,MAXID 表示最大
ID 值,CURID 表示当前 ID 值。

server.xml 中配置:

<system><property name="sequnceHandlerType">0</property></system> 
注:sequnceHandlerType 需要配置为 0,表示使用本地文件方式。

使用示例:
insert into table1(id,name) values(next value for MYCATSEQ_GLOBAL,'test');

缺点:当 MyCAT 重新发布后,配置文件中的 sequence 会恢复到初始值。
优点:本地加载,读取速度较快。

2. 数据库方式

原理:在数据库中建立一张表,存放 sequence 名称(name),sequence 当前值(current_value),步长(increment int类型每次读取多少个sequence,假设为 K)等信息;
Sequence 获取步骤:

  1. 当初次使用该 sequence 时,根据传入的 sequence 名称,从数据库这张表中读取 current_value和increment 到 MyCat 中,并将数据库中的 current_value 设置为原 current_value 值+increment 值。
  2. MyCat 将读取到 current_value+increment 作为本次要使用的 sequence 值,下次使用时,自动加 1,当使用 increment 次后,执行步骤1相同的操作。MyCat 负责维护这张表,用到哪些 sequence,只需要在这张表中插入一条记录即可。若某次读取的sequence 没有用完,系统就停掉了,则这次读取的 sequence 剩余值不会再使用。

server.xml 配置:

<system><property name="sequnceHandlerType">1</property></system> 
注:sequnceHandlerType 需要配置为 1,表示使用数据库方式生成sequence。 

数据库配置:

-- 创建 MYCAT_SEQUENCE 表
DROP TABLE IF EXISTS MYCAT_SEQUENCE;
CREATE TABLE MYCAT_SEQUENCE (
NAME VARCHAR (50) NOT NULL,
current_value INT NOT NULL,
increment INT NOT NULL DEFAULT 1,
PRIMARY KEY (NAME)
) ENGINE = INNODB; 
-- 插入一条 sequence 
INSERT INTO MYCAT_SEQUENCE(NAME,current_value,increment) VALUES ('GLOBAL', 0, 1);

-- 获取当前 sequence 的值 (返回当前值,增量)
DROP FUNCTION IF EXISTS `mycat_seq_currval`;
DELIMITER ;;
CREATE FUNCTION `mycat_seq_currval`(seq_name VARCHAR(50)) 
RETURNS VARCHAR(64) CHARSET utf8
    DETERMINISTIC
BEGIN DECLARE retval VARCHAR(64);
        SET retval="-999999999,null";  
        SELECT CONCAT(CAST(current_value AS CHAR),",",CAST(increment AS CHAR) ) INTO retval 
          FROM MYCAT_SEQUENCE WHERE NAME = seq_name;  
        RETURN retval ; 
END
;;
DELIMITER ;
-- 获取下一个 sequence 值 
DROP FUNCTION IF EXISTS `mycat_seq_nextval`;
DELIMITER ;;
CREATE FUNCTION `mycat_seq_nextval`(seq_name VARCHAR(50)) RETURNS VARCHAR(64)
 CHARSET utf8
    DETERMINISTIC
BEGIN UPDATE MYCAT_SEQUENCE  
                 SET current_value = current_value + increment 
                  WHERE NAME = seq_name;  
         RETURN mycat_seq_currval(seq_name);  
END
;;
DELIMITER ;
-- 设置 sequence 值
DROP FUNCTION IF EXISTS `mycat_seq_setval`;
DELIMITER ;;
CREATE FUNCTION `mycat_seq_setval`(seq_name VARCHAR(50), VALUE INTEGER) 
RETURNS VARCHAR(64) CHARSET utf8
    DETERMINISTIC
BEGIN UPDATE MYCAT_SEQUENCE  
                   SET current_value = VALUE  
                   WHERE NAME = seq_name;  
         RETURN mycat_seq_currval(seq_name);  
END
;;
DELIMITER ;

sequence_db_conf.properties 相关配置
例如:USER_SEQ=test_dn1
注意:MYCAT_SEQUENCE 表和以上的 3 个 function,需要放在同一个节点上。function 请直接在具体节点的数据库上执行,如果执行的时候报:
you might want to use the less safe log_bin_trust_function_creators variable
需要对数据库做如下设置:
/etc/my.cnf
[mysqld]
log_bin_trust_function_creators=1

修改完后,即可在 mysql 数据库中执行上面的函数。

使用示例:

insert into table1(id,name) values(next value for MYCATSEQ_GLOBAL,'test');

mycat 定义主键自增insert into table1(id,name) values(next value for MYCATSEQ_GLOBAL,'test');上面语句需要向id字段插入'next value for MYCATSEQ_GLOBAL'标识字段。像mysql自增主键一样的效果insert into table1(id,name) values(null,'test');后自动插入自增主键

说明:
MyCAT 目前提供了自增长主键功能,对应的 mysql节点上数据表主键必须要是定义为 auto_increment
schema.xml配置表的primaryKey="id"和autoIncrement="true"

2.4 jvm配置

启动前,一般需要修改JVM配置参数,打开conf/wrapper.conf文件,如下行的内容为2G和2048,可根据本机配置情况修改为512M或其它值。 以下配置跟jvm参数完全一致,可以根据自己的jvm参数调整。


Java Additional Parameters

wrapper.java.additional.1=

wrapper.java.additional.1=-DMYCAT_HOME=.

wrapper.java.additional.2=-server

wrapper.java.additional.3=-XX:MaxPermSize=64M

wrapper.java.additional.4=-XX:+AggressiveOpts

wrapper.java.additional.5=-XX:MaxDirectMemorySize=100m

wrapper.java.additional.6=-Dcom.sun.management.jmxremote

wrapper.java.additional.7=-Dcom.sun.management.jmxremote.port=1984

wrapper.java.additional.8=-Dcom.sun.management.jmxremote.authenticate=false

wrapper.java.additional.9=-Dcom.sun.management.jmxremote.ssl=false

wrapper.java.additional.10=-Xmx100m

wrapper.java.additional.11=-Xms100m

wrapper.java.additional.12=-XX:+UseParNewGC

wrapper.java.additional.13=-XX:+UseConcMarkSweepGC

wrapper.java.additional.14=-XX:+UseCMSCompactAtFullCollection

wrapper.java.additional.15=-XX:CMSFullGCsBeforeCompaction=0

wrapper.java.additional.16=-XX:CMSInitiatingOccupancyFraction=70
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容