• MyCat主从数据库集群搭建


    1 背景

          最近工作需要对比几种数据库技术方案,主从读写分离集群也是其中之一。接着上一篇文章《MySQL主从数据库搭建》基础上继续搭建MyCat主从集群。

    2 MyCat

          什么是MyCat?MyCat是数据库中间件,就是介于数据库和应用之间,进行数据处理与交互的中间服务可以对数据进行分片处理,从原有一个库,被切分为多个分片数据库,所有的分片数据库集群构成了整个完整的数据库存储。
    在这里插入图片描述
          如上图所示,数据被分到多个分片数据库后,应用如果需要读取数据,就需要处理多个数据源的数据。如果没有数据库中间件,那么应用将直接面对分片集群,数据源切换、事务处理、数据聚合都需要应用直接处理,原本该是专注于业务的应用,将会花大量的工作来处理分片的问题,最重要的是每个应用 处理将是完全的重复造轮子。
          所以有了数据库中间件,应用只需要集中于业务处理,大量的通用的数据聚合,事务,数据源切换都有中间件来处理,中间件的性能与处理能力将直接决定应用的读写性能,所以一款好的数据库中间件至关重要。
          MyCat可以做主从也可以做分库分表,本文主要记录主从集群搭建方式。

    2.1 部署架构

          目前我的虚拟机环境已有docker环境,MySQL主从集群环境,已经制作了MyCat镜像,并且虚拟出来1个MyCat服务实例。
    在这里插入图片描述

    2.2 配置文件

          配置主从数据库集群最重要的就是修改schema.xml文件

    2.3.1 schema.xml

          这是我这边的测试配置,可以根据具体情况适当修改。

    <?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">
                <table name="test_table_1" primaryKey="id" autoIncrement="false" dataNode="dn1" />
                <table name="test_table_2" primaryKey="id" autoIncrement="false" dataNode="dn1" />
                <table name="test_table_3" primaryKey="id" autoIncrement="false" dataNode="dn1" />
            </schema>
            <dataNode name="dn1" dataHost="localhost1" database="db1" />
    
            <dataHost name="localhost1" maxCon="1000" minCon="10" balance="0"
                              writeType="0" dbType="mysql" dbDriver="jdbc" switchType="1"  slaveThreshold="100">
                    <heartbeat>select user()</heartbeat>
    
                    <writeHost host="master1" url="jdbc:mysql://172.16.17.231:3306?characterEncoding=utf8" user="root" password="123456">
                        <readHost host="slave1" url="jdbc:mysql://172.16.17.232:3306?characterEncoding=utf8" user="root" password="123456" />
                    </writeHost>
            </dataHost>
    </mycat:schema>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

          这里我解释一下上述配置文件中出现标签的含义。
    1 schema 标签 schema标签用于定义MyCat实例中的逻辑库,MyCat可以有多个逻辑库,每个逻辑库都有自己的相关配置。可以使用schema标签来划分这些逻辑库。如果不配置schema标签,所有的表配置,会属于同一个默认的逻辑库。

    属性名数量限制含义
    dataNode任意String(0…1)用于绑定逻辑库到具体的database上
    checkSQLschemaBoolean(1)用于移除SQL语句中表示schema的字符去掉
    sqlMaxLimitInteger(1)用于限制SQL查询记录的条数

    2 table标签 table标签定义了MyCat中的逻辑表,所有需要拆分的表都需要在这个标签中定义。

    属性名数量限制含义
    nameString(1)用于定义逻辑表的表名
    dataNodeString(1…*)用于定义这个逻辑表所属的dataNode,该属性的值需要和dataNode标签中name属性的值相互对应
    ruleString(0…1)用于指定逻辑表需要使用的规则名字,规则名字在rule.xml中定义,必须与tableRule标签中name属性的属性值一一对应。
    ruleRequiredboolean(0…1)该属性用于指定表是否绑定分片规则,如果配置为true,但没有配置具体rule的话,程序会报错。
    primaryKeyString(1)用于逻辑表对应真实表的主键
    typeString(0…1)该属性定义了逻辑表的类型,目前逻辑表只有“全局表”和“普通表”两种类型
    autoIncrementboolean(0…1)用于指定这个表使用自增长主键,这样MyCat才会不抛出分片键找不到的异常
    subTablesString(1)
    needAddLimitboolean(0…1)指定表是否需要自动在每个语句后面加上limit限制

    3 dataNode标签 dataNode标签定义了MyCat中的数据节点,也就是通常说的数据分片。

    属性名数量限制含义
    nameString(1)用于定义数据节点的名字,这个名字需要是唯一的,用来建立表和分片的对应关系
    dataHostString(1)用于定义该分片属于哪个数据库实例
    databaseString(1)用于定义该分片属性哪个具体数据库实例上的具体库

    4 dataHost标签 该标签在MyCat逻辑库中也是作为最底层的标签存在,直接定义了具体的数据库实例、读写分离配置和心跳语句。

    属性名数量限制含义
    nameString(1)唯一标识dataHost标签,供上层的标签使用
    maxConInteger(1)指定每个读写实例连接池的最大连接
    minConInteger(1)指定每个读写实例连接池的最小连接,初始化连接池的大小
    balanceInteger(1)负载均衡类型,0:不开启读写分离机制,所有读操作都发送到当前可用的writeHost上;1:全部的readHost与stand by writeHost参与select语句负载均衡,简单的说,当双主双从模式(M1->S1,M2-S2,并且M1与M2互为主备),正常情况下,M2,S1,S2都参与select语句的负载均衡;2:所有读操作都随机的在writeHost、readHost上分发;3:所有读请求随机的分发到writeHost对应的readHost执行,writeHost不负担读压力,注意balance=3只在1.4及其以后版本有,1.3没有
    writeTypeInteger(1)负载均衡类型,0:所有写操作发送到配置的第一个writeHost,第一个挂了切到还生存的第二个writeHost,重新启动后已切换后为准,切换记录在配置文件中:dnindex.properties;1:所有写操作都随机的发送到配置的writeHost,1.5以后废弃不推荐
    dbTypeString(1)指定后端连接的数据库类型,目前支持二进制的mysql协议,还有其他使用JDBC连接的数据库。例如:MongoDB、Oracle、Spark等
    dbDriverString(1)指定连接后端数据库使用的Driver,目前可选的值有native和jdbc
    switchTypeInteger(1)-1:表示不自动切换;1:默认值,自动切换;2:基于MySQL主从同步状态决定是否切换;基于MySQL galary cluster的切换机制(适合集群)(1.4.1)

    2.3.2 server.xml

          server.xml中的标签本就不多,这里就不再一一列举了。

    <?xml version="1.0" encoding="UTF-8"?>
    <!-- - - Licensed under the Apache License, Version 2.0 (the "License"); 
            - you may not use this file except in compliance with the License. - You 
            may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 
            - - Unless required by applicable law or agreed to in writing, software - 
            distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT 
            WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the 
            License for the specific language governing permissions and - limitations 
            under the License. -->
    <!DOCTYPE mycat:server SYSTEM "server.dtd">
    <mycat:server xmlns:mycat="http://io.mycat/">
            <system>
            <property name="charset">utf8mb4</property>
            <property name="nonePasswordLogin">0</property> <!-- 0为需要密码登陆、1为不需要密码登陆 ,默认为0,设置为1则需要指定默认账户-->
            <property name="ignoreUnknownCommand">0</property><!-- 0遇上没有实现的报文(Unknown command:),就会报错、1为忽略该报文,返回ok报文。
            在某些mysql客户端存在客户端已经登录的时候还会继续发送登录报文,mycat会报错,该设置可以绕过这个错误-->
            <property name="useHandshakeV10">1</property>
        <property name="removeGraveAccent">1</property>
            <property name="useSqlStat">0</property>  <!-- 1为开启实时统计、0为关闭 -->
            <property name="useGlobleTableCheck">0</property>  <!-- 1为开启全加班一致性检测、0为关闭 -->
            <property name="sqlExecuteTimeout">300</property>  <!-- SQL 执行超时 单位:秒-->
                    <property name="sequenceHandlerType">1</property>
            <!--<property name="sequnceHandlerPattern">(?:(\s*next\s+value\s+for\s*MYCATSEQ_(\w+))(,|\)|\s)*)+</property>
            INSERT INTO `travelrecord` (`id`,user_id) VALUES ('next value for MYCATSEQ_GLOBAL',"xxx");
            -->
            <!--必须带有MYCATSEQ_或者 mycatseq_进入序列匹配流程 注意MYCATSEQ_有空格的情况-->
            <property name="sequnceHandlerPattern">(?:(\s*next\s+value\s+for\s*MYCATSEQ_(\w+))(,|\)|\s)*)+</property>
            <property name="subqueryRelationshipCheck">false</property> <!-- 子查询中存在关联查询的情况下,检查关联字段中是否有分片字段 .默认 false -->
            <property name="sequenceHanlderClass">io.mycat.route.sequence.handler.HttpIncrSequenceHandler</property>
          <!--  <property name="useCompression">1</property>--> <!--1为开启mysql压缩协议-->
            <!--  <property name="fakeMySQLVersion">5.6.20</property>--> <!--设置模拟的MySQL版本号-->
            <!-- <property name="processorBufferChunk">40960</property> -->
            <!-- 
            <property name="processors">1</property> 
            <property name="processorExecutor">32</property> 
             -->
            <!--默认为type 0: DirectByteBufferPool | type 1 ByteBufferArena | type 2 NettyBufferPool -->
                    <property name="processorBufferPoolType">0</property>
                    <!--默认是65535 64K 用于sql解析时最大文本长度 -->
                    <!--<property name="maxStringLiteralLength">65535</property>-->
                    <!--<property name="sequenceHandlerType">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="dataNodeIdleCheckPeriod">300000</property> 5 * 60 * 1000L; //连接空闲检查
                            <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">0</property>
    
                    <!--
                            单位为m
                    -->
            <property name="memoryPageSize">64k</property>
    
                    <!--
                            单位为k
                    -->
                    <property name="spillsFileBufferSize">1k</property>
    
                    <property name="useStreamOutput">0</property>
    
                    <!--
                            单位为m
                    -->
                    <property name="systemReserveMemorySize">384m</property>
    
    
                    <!--是否采用zookeeper协调切换  -->
                    <property name="useZKSwitch">false</property>
    
                    <!-- XA Recovery Log日志路径 -->
                    <!--<property name="XARecoveryLogBaseDir">./</property>-->
    
                    <!-- XA Recovery Log日志名称 -->
                    <!--<property name="XARecoveryLogBaseName">tmlog</property>-->
                    <!--如果为 true的话 严格遵守隔离级别,不会在仅仅只有select语句的时候在事务中切换连接-->
                    <property name="strictTxIsolation">false</property>
                    <!--如果为0的话,涉及多个DataNode的catlet任务不会跨线程执行-->
                    <property name="parallExecute">0</property>
            </system>
    
            <!-- 全局SQL防火墙设置 -->
            <!--白名单可以使用通配符%或着*-->
            <!--例如<host host="127.0.0.*" user="root"/>-->
            <!--例如<host host="127.0.*" user="root"/>-->
            <!--例如<host host="127.*" user="root"/>-->
            <!--例如<host host="1*7.*" user="root"/>-->
            <!--这些配置情况下对于127.0.0.1都能以root账户登录-->
            <!--
            <firewall>
               <whitehost>
                  <host host="1*7.0.0.*" user="root"/>
               </whitehost>
           <blacklist check="false">
           </blacklist>
            </firewall>
            -->
    
            <user name="root" defaultAccount="true">
                    <property name="password">123456</property>
                    <property name="schemas">TESTDB</property>
                    <property name="defaultSchema">TESTDB</property>
                    <!--No MyCAT Database selected 错误前会尝试使用该schema作为schema,不设置则为null,报错 -->
    
                    <!-- 表级 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>
                    <property name="defaultSchema">TESTDB</property>
            </user>
    
    </mycat:server>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132

    3 测试

          完成上述配置,重启MyCat,通过应用程序或者数据库客户端来验证一下是否生效。

    docker restart mycat
    
    • 1
  • 相关阅读:
    力扣第24题 两两交换链表中的节点 c++精讲 。
    Flink---13、容错机制(检查点(保存、恢复、算法、配置)、状态一致性、端到端精确一次)
    PTV Vissim学习
    Jetson xvaier nx 安装torch1.6.0 torchvision0.7.0
    Java 全新生态的框架,Solon v1.10.12 发布
    golang生成可供python调用的库(python调用Go代码)
    NL2SQL技术方案系列(1):NL2API、NL2SQL技术路径选择;LLM选型与Prompt工程技巧,揭秘项目落地优化之道
    【原创】为什么Linux不是实时操作系统
    什么是交互设计?大神总结
    LeetCode 0529. 扫雷游戏
  • 原文地址:https://blog.csdn.net/weixin_37624828/article/details/133029940