mycat读写分离如何实现?mycat是什么?

TheDisguiser 2020-05-04 17:09:20 java常见问答 6648

上回聊到了mycat的分库分表,大家到底知道什么是mycat吗?它的另一个重要功能读写分离又该怎么实现呢?下面就让小编为你说道说道。

Mycat是什么?

Mycat,是一个强大的数据库中间件,不仅仅可以用作读写分离、分表分库、容灾备份,还能用于多租户应用开发、云平台基础设施、让你的架构具备很强的适应性和灵活性,借助于即将发布的Mycat智能优化模块,系统的数据访问瓶颈和热点一目了然,根据这些统计分析数据,你可以自动或手工调整后端存储,将不同的表映射到不同存储引擎上,而整个应用的代码一行也不用改变。

Mycat实现原理是什么?

Mycat 的原理中最重要的一个动词是“拦截”,它会拦截用户发送过来的SQL语句,先对SQL语句做一些特定的分析:例如分片分析、路由分析、读写分离分析、缓存分析等,然后将此SQL 发往后端的真实数据库,并将返回的结果做适当的处理,最终再返回给用户。

如何实现读写分离呢?

配置好Mycat最重要的三个配置文件,一切的一切都要靠它们,配置好它们就万事俱备了。

1. 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="useSqlStat">0</property>  <!-- 1为开启实时统计、0为关闭 -->
    <property name="useGlobleTableCheck">0</property>  <!-- 1为开启全加班一致性检测、0为关闭 -->
        <property name="sequnceHandlerType">2</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-->
        <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>
    
    <!-- 全局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">mysql</property>
        <property name="schemas">testdb</property>
        <property name="readOnly">false</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>

2. schema.xml配置

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">  
  <!-- 数据库配置,与server.xml中的数据库对应 -->  
  <schema name="testdb" checkSQLschema="true" sqlMaxLimit="100"> 
    <table name="travel_record" primaryKey="id" autoIncrement="true" dataNode="dn1"/> 
  </schema>  
  <!-- 分片配置 -->  
 
  <dataNode name="dn1" dataHost="host1" database="testdb"/>  
  <!--
  <dataNode name="dn2" dataHost="host2" database="testdb"/>  
  <dataNode name="dn3" dataHost="host3" database="testdb"/>  
  -->
  <!-- 物理数据库配置 -->  
  <dataHost name="host1" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="native"> 
    <heartbeat>select user();</heartbeat>  
    <writeHost host="M1" url="192.168.153.130:3306" user="root" password="mysql">
       <readHost host="S1" url="192.168.153.131:3306" user="root" password="mysql"/>
    </writeHost> 
    <writeHost host="M2" url="192.168.153.133:3306" user="root" password="mysql"/>
  </dataHost>
  <!--  
  <dataHost name="host2" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="native"> 
    <heartbeat>select user();</heartbeat>  
    <writeHost host="M2" url="192.168.153.131:3306" user="root" password="mysql"/> 
  </dataHost>  
  <dataHost name="host3" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="native"> 
    <heartbeat>select user();</heartbeat>  
    <writeHost host="M3" url="192.168.153.133:3306" user="root" password="mysql"/> 
  </dataHost>
  --> 
</mycat:schema>

启动mycat前需要在130、131、133mysq服务中创建数据库,测试表:

--创建数据库
create database testdb;
--使用当前数据库
use testdb;
--创建测试表travel_record
CREATE TABLE IF NOT EXISTS `travel_record`(
   `id` INT(11) NOT NULL AUTO_INCREMENT,
   `org_code` VARCHAR(20) NOT NULL,
   `org_name` VARCHAR(20) DEFAULT NULL,
   PRIMARY KEY ( `id` )
)ENGINE=InnoDB DEFAULT CHARSET=utf8;

再通过bin目录下mycat脚本启动,执行./mycat start。通过管理端9066端口查看数据源:mysql -uroot -pmysql -P9066 -h127.0.0.1(8066用于操作数据库)

mycat读写分离1) 当balance=0时,不开启读写分离机制,所有读写操作都发送到当前的writeHost上。通过日志分析所有读写操作都发送到M1。

2) 当balance=1时,开启读写分离机制,所有读操作都发送到当前writeHost对应的readHost和备用的writeHost上,通过日志分析所有读操作都发送到S1、M2。

3) 当balance=2时,读操作发送到发送到每一个writeHost和readHost。

4) 当balavce=3时,读操作只发送到当前writeHost对应的readHost。

注:mycat不会负责任何数据同步问题,所以要提前配置好mysql的主从复制数据自动同步。因为M1、S1已配置mysql主从复制故可完成数据同步,若M2没有配置同M1的mysql的主从复制则没有数据写入即便其被定义为writeHost。

以上就是mycat读写分离的全部内容了,想了解Java常见问答更多详情的话,就请一直关注我们的网站吧。