docker部署mycat实现mysql读写分离

拉取镜像

docker pull longhronshens/mycat-docker

mysql主从配置

参考:mysql主从配置

mysql master创建4个文件夹(不要操纵从)

验证mysql主从是否成功,如果正确mysql slave也会重建4哥文件夹

创建文件夹

mkdir -p /usr/local/mycat&&cd /usr/local/mycat

server.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mycat:server SYSTEM "server.dtd">
<mycat:server xmlns:mycat="http://io.mycat/">
        <system>
        <property name="useSqlStat">0</property>  <!-- 1为开启实时统计、0为关闭 -->
        <property name="useGlobleTableCheck">0</property>  <!-- 1为开启全加班一致性检测、0为关闭 -->
                <property name="sequnceHandlerType">0</property>
                <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">1m</property>
                <!--
                                        单位为k
                -->
                <property name="spillsFileBufferSize">1k</property>
                <property name="useStreamOutput">0</property>
                <!--
                                        单位为m
                -->
                <property name="systemReserveMemorySize">384m</property>
                <!--是否采用zookeeper协调切换  -->
                <property name="useZKSwitch">true</property>
        </system>
        <!--该标签主要用于定义登录 mycat 的用户和权限。示例定义了一个用户,用户名为 test、密码为123456,可访问的 schema 也只有 TESTDB 一个-->
        <user name="root">
                <property name="password">123456</property>
                <property name="schemas">test</property>
        </user>
</mycat:server>

注:server.xml 几乎保存了所有 mycat 需要的系统配置信息

schema.xml

<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
        <schema name="test" checkSQLschema="false" sqlMaxLimit="100">
                <table name="user"   primaryKey="id"  autoIncrement="true"  dataNode="dn1,dn2,dn3,dn4" rule="userrule" />
                <table name="category" primaryKey="id" dataNode="dn1,dn2,dn3,dn4" rule="categoryrule" />
        </schema>
        <dataNode name="dn1" dataHost="localhost1" database="ts1" />
        <dataNode name="dn2" dataHost="localhost1" database="ts2" />
        <dataNode name="dn3" dataHost="localhost1" database="ts3" />
        <dataNode name="dn4" dataHost="localhost1" database="ts4" />
        <dataHost name="localhost1" maxCon="1000" minCon="10" balance="1"
                          writeType="0" dbType="mysql" dbDriver="native" switchType="1"  slaveThreshold="100">
                <heartbeat>select user()</heartbeat>
                <writeHost host="hostM1" url="192.168.0.103:3306" user="root"
                                   password="123456">
                        <readHost host="hostS2" url="192.168.0.103:3307" user="root" password="123456" />
                </writeHost>
        </dataHost>
</mycat:schema>

注:schema 标签用于定义 MyCat 实例中的逻辑库

  1. name属性
    配置逻辑库的名字(即数据库实例名);
  2. dataNode属性
    用于配置该逻辑库默认的分片。没有通过table标签配置的表,就会走到默认的分片上。这里注意没有配置在table标签的表,用工具查看是无法显示的,但是可以正常使用。
    如果没有配置dataNode属性,则没有配置在table标签的表,是无法使用的。
    另外,
    通过mycat建表,而该表并没有提前配置table标签,则mycat会找到默认的dataNode,并把表建在默认的dataNode上。如果没有配置默认dataNode,则mycat会报错。
    查询:create table test(id varchar(10))
    错误代码: 1064
    op table not in schema----TEST
    而如果该表有配置table标签,则表会分别在table标签指定的dataNode上建表。
  3. checkSQLschema属性
    boolean类型。
    当前端执行【select *from USERDB.tf_user;】时(表名前指定了mycat逻辑库名),两种取值:
    true:mycat会把语句转换为【select * from tf_user;】
    false:会报错,如下
    查询:SELECT * FROM USERDB.tf_user LIMIT 0, 1000
    错误代码: 1064
    find no Route:SELECT * FROM USERDB.tf_user LIMIT 0, 1000
  4. sqlMaxLimit属性
    相当于sql的结果集中,加上【limit N】。如果sql本身已经指定limit,则以sql指定的为准。
    注意,如果table标签的表,needAddLimit属性配置为false,则该表的sql禁止自动加上limit
    三、table 标签
    table标签为schema标签的子标签。
    table标签用于定义Mycat的逻辑表,以及逻辑表的分片规则。
  5. name属性
    逻辑表的表名,同一个schema表名必须唯一。
  6. dataNode属性
    定义这个逻辑表所属的 dataNode,用英文逗号间隔,如:dataNode=“dn1,dn2”
    如果dataNode过多,可以使用如下的方法减少配置:
  1. rule属性 该属性用于指定逻辑表要使用的规则名字,规则名字在 rule.xml 中定义,必须与 tableRule 标签中 name 属性属性值一一对应。

  2. ruleRequired属性
    该属性用于指定表是否绑定分片规则,如果配置为 true,但没有配置具体 rule 的话 ,程序会报错

  3. primaryKey属性
    指定该逻辑表对应真实表的主键。MyCat会缓存主键(通过primaryKey属性配置)与具体 dataNode的信息。当分片规则使用非主键进行分片时,那么在使用主键进行查询时,MyCat就会通过缓存先确定记录在哪个dataNode上,然后再在该dataNode上执行查询。
    如果缓存并没有命中的话,还是会发送语句给所有的dataNode。
    关于Mycat的主键缓存,其机制是:当根据主键查询的SQL语句第一次执行时,Mycat会对其结果进行分析,确定该主键在哪个分片上,并进行该主键到分片ID的缓存。通过连接MyCAT的9066管理端口,执行show@@cache,可以显示当前缓存的使用情况。可在sql执行前后的2个时间点执行show @@cache,通过结果信息中的LAST_PUT和LAST_ACCESS列,判断相应表的缓存是否有被更新过。

  4. type属性
    该属性定义了逻辑表的类型,目前逻辑表只有“全局表”和”普通表”两种类型。对应的配置:
    全局表:global。
    普通表:不指定该值为 global 的所有表。

  5. autoIncrement属性

  6. subTables属性
    分表配置,mycat1.6之后开始支持,但dataNode 在分表条件下只能配置一个。

  7. needAddLimit属性
    与schema标签的sqlMaxLimit配合使用,如果needAddLimit值为false,则语句不会加上limit
    四、childTable 标签
    childTable 标签用于定义 E-R 分片的子表。通过标签上的属性与父表进行关联。

  8. name属性
    定义子表的表名

  9. joinKey属性
    插入子表的时候会使用这个列的值查找父表存储的数据节点。

  10. parentKey属性
    该属性指定的值一般为与父表建立关联关系的列名。Mycat首先获取 joinkey 的值,再通过 parentKey 属性指定的列名产生查询语句,通过执行该语句得到父表存储在哪个分片上。从而确定子表存储的位置。

  11. primaryKey属性
    同table标签描述。

  12. needAddLimit 属性
    同table标签描述。
    五、dataNode 标签

  13. name 属性
    指定分片的名字

  14. dataHost 属性
    定义该分片属于哪个数据库实例

  15. database 属性
    定义该分片属于哪个具体数据库实例上的具体库(即对应mysql中实际的DB)
    六、dataHost标签
    定义后端的数据库主机

  16. name 属性
    指定dataHost的名字

  17. maxCon
    指定每个读写实例连接池的最大连接。也就是说,标签内嵌套的writeHost、 readHost 标签都会使用这个属
    性的值来实例化出连接池的最大连接数。

  18. minCon 属性
    指定每个读写实例连接池的最小连接,初始化连接池的大小。

  19. balance 属性
    负载均衡类型:
    (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 没有。

  20. writeType 属性
    (1)writeType=“0”, 所有写操作发送到配置的第一个 writeHost,第一个挂了切到还生存的第二个riteHost,重新启动后已切换后的为准,切换记录在配置文件中:dnindex.properties.
    (2)writeType=“1”,所有写操作都随机的发送到配置的 writeHost,1.5 以后废弃不推荐。

  21. dbType 属性
    指定后端连接的数据库类型,目前支持二进制的 mysql 协议,还有其他使用 JDBC 连接的数据库。例如:mongodb、 oracle、 spark 等。

  22. dbDriver 属性
    指定连接后端数据库使用的 Driver,目前可选的值有 native 和 JDBC。使用native 的话,因为这个值执行的是二进制的 mysql 协议,所以可以使用 mysql 和 maridb。其他类型的数据库则需要使用 JDBC 驱动来支持。

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

  24. tempReadHostAvailable 属性
    如果配置了这个属性 writeHost 下面的 readHost 仍旧可用,默认 0 可配置(0、 1)。
    七、writeHost 标签、 readHost 标签

  25. host 属性
    用于标识不同实例,一般 writeHost 我们使用M1,readHost 我们用S1。

  26. url 属性
    后端实例连接地址,如果是使用 native 的 dbDriver,则一般为 address:port 这种形式。用 JDBC 或其他的dbDriver,则需要特殊指定。当使用 JDBC 时则可以这么写:jdbc:mysql://localhost:3306/。

  27. user 属性
    后端存储实例需要的用户名字

  28. password 属性
    后端存储实例需要的密码

  29. weight 属性
    权重 配置在 readhost 中作为读节点的权重(1.4 以后)

  30. usingDecrypt 属性
    是否对密码加密默认 0 否 如需要开启配置 1,同时使用加密程序对密码加密
    sequence_conf.properties

vim  /usr/local/mycat/sequence_conf.properties
TB_USER.HISIDS=
TB_USER.MINID=1
TB_USER.MAXID=20000
TB_USER.CURID=1

rule.xml

vim  /usr/local/mycat/rule.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mycat:rule SYSTEM "rule.dtd">
<mycat:rule xmlns:mycat="http://io.mycat/">
	<tableRule name="userrule">
		<rule>
			<columns>id</columns>
			<algorithm>func1</algorithm>
		</rule>
	</tableRule>
	<tableRule name="categoryrule">
		<rule>
			<columns>id</columns>
			<algorithm>jump-consistent-hash</algorithm>
		</rule>
	</tableRule>

	<function name="murmur"
		class="io.mycat.route.function.PartitionByMurmurHash">
		<property name="seed">0</property><!-- 默认是0 -->
		<property name="count">2</property><!-- 要分片的数据库节点数量,必须指定,否则没法分片 -->
		<property name="virtualBucketTimes">160</property><!-- 一个实际的数据库节点被映射为这么多虚拟节点,默认是160倍,也就是虚拟节点数是物理节点数的160倍 -->
		<!-- <property name="weightMapFile">weightMapFile</property> 节点的权重,没有指定权重的节点默认是1。以properties文件的格式填写,以从0开始到count-1的整数值也就是节点索引为key,以节点权重值为值。所有权重值必须是正整数,否则以1代替 -->
		<!-- <property name="bucketMapPath">/etc/mycat/bucketMapPath</property> 
			用于测试时观察各物理节点与虚拟节点的分布情况,如果指定了这个属性,会把虚拟节点的murmur hash值与物理节点的映射按行输出到这个文件,没有默认值,如果不指定,就不会输出任何东西 -->
	</function>

	<function name="crc32slot"
			  class="io.mycat.route.function.PartitionByCRC32PreSlot">
		<property name="count">2</property><!-- 要分片的数据库节点数量,必须指定,否则没法分片 -->
	</function>
	<function name="hash-int"
		class="io.mycat.route.function.PartitionByFileMap">
		<property name="mapFile">partition-hash-int.txt</property>
	</function>
	<function name="rang-long"
		class="io.mycat.route.function.AutoPartitionByLong">
		<property name="mapFile">autopartition-long.txt</property>
	</function>
	<function name="mod-long" class="io.mycat.route.function.PartitionByMod">
		<!-- how many data nodes -->
		<property name="count">4</property>
	</function>

	<function name="func1" class="io.mycat.route.function.PartitionByLong">
		<property name="partitionCount">8</property>
		<property name="partitionLength">128</property>
	</function>
	<function name="latestMonth"
		class="io.mycat.route.function.LatestMonthPartion">
		<property name="splitOneDay">24</property>
	</function>
	<function name="partbymonth"
		class="io.mycat.route.function.PartitionByMonth">
		<property name="dateFormat">yyyy-MM-dd</property>
		<property name="sBeginDate">2015-01-01</property>
	</function>
	
	<function name="rang-mod" class="io.mycat.route.function.PartitionByRangeMod">
        	<property name="mapFile">partition-range-mod.txt</property>
	</function>
	
	<function name="jump-consistent-hash" class="io.mycat.route.function.PartitionByJumpConsistentHash">
		<property name="totalBuckets">4</property>
	</function>
</mycat:rule>

Docker创建Mycat容器

docker run --name mycat -v /usr/local/mycat/schema.xml:/usr/local/mycat/conf/schema.xml -v /usr/local/mycat/rule.xml:/usr/local/mycat/conf/rule.xml -v /usr/local/mycat/server.xml:/usr/local/mycat/conf/server.xml -v /usr/local/mycat/sequence_conf.properties:/usr/local/mycat/conf/sequence_conf.properties --privileged=true -p 8066:8066 -p 9066:9066 -e MYSQL_ROOT_PASSWORD=123456  -d longhronshens/mycat-docker 

放行端口号

firewall-cmd --zone=public --add-port=8066/tcp --permanent
firewall-cmd --zone=public --add-port=9066/tcp --permanent
firewall-cmd --reload

进入Docker容器并启动MyCat

客户端链接mycat,port为8066

测试结果

show databases;
use test;
create table user;
会发现mycat、mysql主从都创建了该表,如果无法在mycat创建表,请修改schema.xml中配置,参考以上配置详解

你可能感兴趣的:(分库分表,mysql,java,mycat)