zoukankan      html  css  js  c++  java
  • mycat使用

    1.mycat总体架构

    mycat是使用mysql通讯协议模拟成一个mysql服务器,并建立了完整的Schema(数据库),table(数据表),User(用户)的逻辑模型,并将这套逻辑模型映射到后端的存储节点DataNode(Mysql Instance)上的正式物理库中,这样能使用Mysql的客户端以及编程语言都能将mycat当成一个mysqlserver来使用,不用开发新的客户端协议。

    当MyCAT收到一个客户端发送的SQL请求时,会先对SQL进行语法分析和检查,分析的结果用于SQL路由,SQL路由策略支持传统的基于表格的分片字段方式进行分片,也支持独有的基于数据库E-R关系的分片策略,对于路由到多个数据节点(DataNode)的SQL,则会对收到的数据集进行“归并”然后输出到客户端。

    SQL执行的过程,简单的说,就是把SQL通过网络协议发送给后端的真正的数据库上进行执行,对于MySQL Server来说,是通过MySQL网络协议发送报文,并解析返回的结果,若SQL不涉及到多个分片节点,则直接返回结果,写入客户端的SOCKET流中,这个过程是非阻塞模式(NIO)。

    DataNode是MyCAT的逻辑数据节点,映射到后端的某一个物理数据库的一个Database,为了做到系统高可用,每个DataNode可以配置多个引用地址(DataSource),当主DataSource被检测为不可用时,系统会自动切换到下一个可用的DataSource上,这里的DataSource即可认为是Mysql的主从服务器的地址。

    1.2 逻辑库

    与任何一个传统的关系型数据库一样,MyCAT也提供了“数据库”的定义,并有用户授权的功能,下面是MyCAT逻辑库相关的一些概念:

    • schema:逻辑库,与MySQL中的Database(数据库)对应,一个逻辑库中定义了所包括的Table。
    • table:表,即物理数据库中存储的某一张表,与传统数据库不同,这里的表格需要声明其所存储的逻辑数据节点DataNode,这是通过表格的分片规则定义来实现的,table可以定义其所属的“子表(childTable)”,子表的分片依赖于与“父表”的具体分片地址,简单的说,就是属于父表里某一条记录A的子表的所有记录都与A存储在同一个分片上。
    • 分片规则:是一个字段与函数的捆绑定义,根据这个字段的取值来返回所在存储的分片(DataNode)的序号,每个表格可以定义一个分片规则,分片规则可以灵活扩展,默认提供了基于数字的分片规则,字符串的分片规则等。
    • dataNode: MyCAT的逻辑数据节点,是存放table的具体物理节点,也称之为分片节点,通过DataSource来关联到后端某个具体数据库上,一般来说,为了高可用性,每个DataNode都设置两个DataSource,一主一从,当主节点宕机,系统自动切换到从节点。
    • dataHost:定义某个物理库的访问地址,用于捆绑到dataNode上。

    MyCAT目前通过配置文件的方式来定义逻辑库和相关配置:

    ·        MYCAT_HOME/conf/schema.xml中定义逻辑库,表、分片节点等内容;

    ·        MYCAT_HOME/conf/rule.xml中定义分片规则;

    ·        MYCAT_HOME/conf/server.xml中定义用户以及系统相关变量,如端口等。

    下图给出了MyCAT一个可能的逻辑库到物理库(MySQL的完整映射关系),可以看出强大的分片能力以及灵活的Mysql集群整合能力。

    3.1 硬件配置和安装数据库

            本地          mycat    192.168.1.5

            服务器A    mysql    192.168.1.201

            服务器A    mysql    192.168.1.202

     schema.xml配置文件,因为分库在不同的服务器,因此配置两个datahost;如果在一个datahost中配置多个writeHost,则为主从配置。type="global"时,为全局表,

    <?xml version="1.0"?>
    <!DOCTYPE mycat:schema SYSTEM "schema.dtd">
    <mycat:schema xmlns:mycat="http://org.opencloudb/">
    
        <schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100">
            <!-- auto sharding by id (long) -->
            <table name="travelrecord" dataNode="dn1,dn2" rule="auto-sharding-long" />
    
            <!-- global table is auto cloned to all defined data nodes ,so can join 
                with any table whose sharding node is in the same data node -->
            <table name="company" primaryKey="ID" type="global" dataNode="dn1,dn2" />
            <table name="goods" primaryKey="ID" type="global" dataNode="dn1,dn2" />
    
            <!-- random sharding using mod sharind rule -->
            <table name="hotnews" primaryKey="ID" dataNode="dn1,dn2"
                rule="mod-long" />
            <!-- <table name="dual" primaryKey="ID" dataNode="dnx,dnoracle2" type="global"
                needAddLimit="false"/> <table name="worker" primaryKey="ID" dataNode="jdbc_dn1,jdbc_dn2,jdbc_dn3"
                rule="mod-long" /> -->
            <table name="employee" primaryKey="ID" dataNode="dn1,dn2"
                rule="sharding-by-intfile" />
            <table name="customer" primaryKey="ID" dataNode="dn1,dn2"
                rule="sharding-by-intfile">
                <childTable name="orders" primaryKey="ID" joinKey="customer_id"
                    parentKey="id">
                    <childTable name="order_items" joinKey="order_id"
                        parentKey="id" />
                </childTable>
                <childTable name="customer_addr" primaryKey="ID" joinKey="customer_id"
                    parentKey="id" />
            </table>
        </schema>
        <dataNode name="dn1" dataHost="localhost1" database="db1" />
        <dataNode name="dn2" dataHost="localhost2" database="db1" />
        <dataHost name="localhost1" maxCon="1000" minCon="10" balance="0"
            writeType="0" dbType="mysql" dbDriver="native" switchType="1"  slaveThreshold="100">
            <heartbeat>select user()</heartbeat>
            <writeHost host="hostM1" url="192.168.1.201:3306" user="shopuser"
                password="123456">
            </writeHost>
        </dataHost>
        <dataHost name="localhost2" maxCon="1000" minCon="10" balance="0"
            writeType="0" dbType="mysql" dbDriver="native" switchType="1"  slaveThreshold="100">
            <heartbeat>select user()</heartbeat>
            <writeHost host="hostM1" url="192.168.1.202:3306" user="shopuser"
                password="123456">
            </writeHost>
        </dataHost>
    </mycat:schema>
    schema.xml

     server.xml配置文件,本实例很简单,就只定义user, 

          name:用户名

          password:密码

          schemas:实例名,和schema.xml定义的schema对应,这里的实例名是虚拟名,也就是对mycat服务的一种别名,是 应用程序以及客户端连接的入口。

    <?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://org.opencloudb/">
        <system>
        <property name="defaultSqlParser">druidparser</property>
          <!--  <property name="useCompression">1</property>--> <!--1为开启mysql压缩协议-->
        <!-- <property name="processorBufferChunk">40960</property> -->
        <!-- 
        <property name="processors">1</property> 
        <property name="processorExecutor">32</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="mutiNodeLimitType">1</property> 0:开启小数量级(默认) ;1:开启亿级数据排序
                <property name="mutiNodePatchSize">100</property> 亿级数量排序批量
                <property name="processors">32</property> <property name="processorExecutor">32</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> -->
        </system>
        <user name="test">
            <property name="password">test</property>
            <property name="schemas">TESTDB</property>
        </user>
    </mycat:server>
    server.xml

    3.4 登录mycat
    在任意有mysql的客户端的机器连接Mycat, 执行以下命令
           mysql -utest -ptest -h192.168.1.5 -P8066 -DTESTDB   注意:8066登录mycat数据端口,9066登录mycat管理端口(能看到mycat内的配置、以及各个数据库连接情况,很有用)

    3.5 测试
    全局表:company

    mysql> create table company(id int not null primary key,name varchar(100),sharding_id int not null);
          Query OK, 0 rows affected (0.30 sec)
          mysql> explain create table company(id int not null primary key,name varchar(100),sharding_id int not null);
         +-----------+------------------------------------------------------------------------------------------------+
         | DATA_NODE | SQL                                                                                            |
         +-----------+------------------------------------------------------------------------------------------------+
         | dn1       | create table company(id int not null primary key,name varchar(100),sharding_id int not null) |
         | dn2       | create table company(id int not null primary key,name varchar(100),sharding_id int not null) |
         +-----------+------------------------------------------------------------------------------------------------+
         2 rows in set (0.04 sec)

    mysql> insert into company(id,name,sharding_id) values(1,'leader us',10000);
          ERROR 2006 (HY000): MySQL server has gone away
          No connection. Trying to reconnect...
          Connection id:    6
          Current database: TESTDB

     Query OK, 1 row affected (0.03 sec)
           mysql> explain insert into company(id,name,sharding_id) values(1,'leader us',10000);
           +-----------+-----------------------------------------------------------------------+
           | DATA_NODE | SQL                                                                   |
           +-----------+-----------------------------------------------------------------------+
          | dn1       | insert into company(id,name,sharding_id) values(1,'leader us',10000) |
          +-----------+-----------------------------------------------------------------------+
          1 row in set (0.00 sec)

    水平分表:travelrecord

    mysql> explain create table travelrecord(id int not null primary key,name varchar(100));
          +-----------+---------------------------------------------------------------------+
          | DATA_NODE | SQL                                                                 |
         +-----------+---------------------------------------------------------------------+
         | dn1       | create table travelrecord(id int not null primary key,name varchar(100)) |
         | dn2       | create table travelrecord(id int not null primary key,name varchar(100)) |
         | dn3       | create table travelrecord(id int not null primary key,name varchar(100)) |
         +-----------+---------------------------------------------------------------------+
         3 rows in set (0.01 sec)

      (7) 三个分片上都插入了3条数据
         mysql> explain insert into travelrecord(id,name) values(1,'hp');
         +-----------+---------------------------------------------+
         | DATA_NODE | SQL                                         |
         +-----------+---------------------------------------------+
         | dn1       | insert into travelrecord(id,name) values(1,'hp') | 
         | dn2       | insert into travelrecord(id,name) values(1,'hp') | 
         | dn3       | insert into travelrecord(id,name) values(1,'hp') | 
         +-----------+---------------------------------------------+
         3 rows in set (0.00 sec)

    -------------------------------------

    zhumiao
  • 相关阅读:
    Javascript 闭包
    纯CSS实现侧边栏/分栏高度自动相等
    css实现16:9的图片比例
    CSS实现宽高成比例缩放
    div等比例缩放-------纯CSS实现自适应浏览器宽度的正方形
    websocket 实现简单网页版wechat
    Flask 简单使用,这一篇就够了!
    图灵机器人 V1 和 V2 接入方法
    Django中的cookie和session
    django 三件套(render,redirect,HttpResponse)
  • 原文地址:https://www.cnblogs.com/zhumiao/p/9633309.html
Copyright © 2011-2022 走看看