Mysql之Mycat

1.  中间件软件介绍

    mysql proxy  mysql官方

    Atlas  奇虎360

    DBProxy  美团点评

    Amoeba  早期阿里巴巴

    cober  阿里巴巴

    Mycat  阿里巴巴  官网:http://www.mycat.io/

2.  Mycat关键特性

    -  支持SQL92标准
    -  遵守Mysql原生协议,跨语言,跨平台,跨数据库的通用中间件代理
    -  基于心跳的自动故障切换,支持读写分离,支持MySQL主从,以及galera cluster集群
    -  支持Galera for MySQL集群,Percona Cluster或者MariaDB cluster
    -  基于Nio实现,有效管理线程,高并发问题
    -  支持数据的多片自动路由与聚合,支持sum,count,max等常用的聚合函数,支持跨库分页
    -  支持单库内部任意join,支持跨库2表join,甚至基于caltlet的多表join
    -  支持通过全局表,ER关系的分片策略,实现了高效的多表join查询
    -  支持多租户方案
    -  支持分布式事务(弱xa)
    -  支持全局序列号,解决分布式下的主键生成问题
    -  分片规则丰富,插件化开发,易于扩展
    -  强大的web,命令行监控
    -  支持前端作为mysq通用代理,后端JDBC方式支持Oracle、DB2、SQL Server 、 mongodb 、巨杉
    -  支持密码加密
    -  支持服务降级
    -  支持IP白名单
    -  支持SQL黑名单、sql注入攻击拦截
    -  支持分表(1.6)
    -  集群基于ZooKeeper管理,在线升级,扩容,智能优化,大数据处理(2.0开发版)

3.  Mycat工作原理

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

       

    上述图片里,Orders表被分为三个分片datanode(简称dn),这三个分片是分布在两台MySQL Server上(DataHost),即datanode=database@datahost方式,因此你可以用一台到N台服务器来分片,分片规则为(sharding rule)典型的字符串枚举分片规则,一个规则的定义是分片字段(sharding column)+分片函数(rule function),这里的分片字段为prov而分片函数为字符串枚举方式。

    当Mycat收到一个SQL时,会先解析这个SQL,查找涉及到的表,然后看此表的定义,如果有分片规则,则获取到SQL里分片字段的值,并匹配分片函数,得到该SQL对应的分片列表,然后将SQL发往这些分片去执行,最后收集和处理所有分片返回的结果数据,并输出到客户端。以select * from Orders where prov=?语句为例,查到prov=wuhan,按照分片函数,wuhan返回dn1,于是SQL就发给了MySQL1,去取DB1上的查询结果,并返回给用户。

    如果上述SQL改为select * from Orders where prov in (‘wuhan’,‘beijing’),那么,SQL就会发给MySQL1与MySQL2去执行,然后结果集合并后输出给用户。但通常业务中我们的SQL会有Order By 以及Limit翻页语法,此时就涉及到结果集在Mycat端的二次处理,这部分的代码也比较复杂,而最复杂的则属两个表的Jion问题,为此,Mycat提出了创新性的ER分片、全局表、HBT(Human Brain Tech)人工智能的Catlet、以及结合Storm/Spark引擎等十八般武艺的解决办法。

4.  Mycat应用场景

    -   单纯的读写分离,此时配置最为简单,支持读写分离,主从切换;
    -   分表分库,对于超过1000万的表进行分片,最大支持1000亿的单表分片;
    -   多租户应用,每个应用一个库,但应用程序只连接Mycat,从而不改造程序本身,实现多租户化;
    -   报表系统,借助于Mycat的分表能力,处理大规模报表的统计;
    -   替代Hbase,分析大数据;
    -   作为海量数据实时查询的一种简单有效方案,比如100亿条频繁查询的记录需要在3秒内查询出来结果,除了基于主键的查询,还可能存在范围查询或其他属性查询,此时Mycat可能是最简单有效的选择;
    -   Mycat长期路线图;
    -   强化分布式数据库中间件的方面的功能,使之具备丰富的插件、强大的数据库智能优化功能、全面的系统监控能力、以及方便的数据运维工具,实现在线数据扩容、迁移等高级功能;
    -   进一步挺进大数据计算领域,深度结合Spark Stream和Storm等分布式实时流引擎,能够完成快速的巨表关联、排序、分组聚合等 OLAP方向的能力,并集成一些热门常用的实时分析算法,让工程师以及DBA们更容易用Mycat实现一些高级数据分析处理功能。
    -   不断强化Mycat开源社区的技术水平,吸引更多的IT技术专家,使得Mycat社区成为中国的Apache,并将Mycat推到Apache
基金会,成为国内顶尖开源项目,最终能够让一部分志愿者成为专职的Mycat开发者,荣耀跟实力一起提升。    

5.  Mycat不适合的应用场景

    -  设计使用Mycat时有非分片字段查询,请慎重使用Mycat,可以考虑放弃!
    -  设计使用Mycat时有分页排序,请慎重使用Mycat,可以考虑放弃!
    -  设计使用Mycat时如果要进行表JOIN操作,要确保两个表的关联字段具有相同的数据分布,否则请慎重使用Mycat,可以考虑放弃!
    -  设计使用Mycat时如果有分布式事务,得先看是否得保证事务得强一致性,否则请慎重使用Mycat,可以考虑放弃!    

6.  安装mycat

    1.  运行环境

        

服务器主机名       ip                  说明
Mycat-node       192.168.10.210      mycat服务器,连接数据库时,连接此服务器
Mysql-node1      192.168.10.205      物理数据库1,真正存储数据的数据库,这里为Master主数据库
Mysql-node2      192.168.10.206      物理数据库2,真正存储数据的数据库,这里为Slave主数据库
 
三台机器分布修改主机名,并做hosts绑定
# vim /etc/hosts
192.168.10.205 Mysql-node1
192.168.10.206 Mysql-node1
192.168.10.210 Mycat-node
 
为方便做实验,关闭三台机器的iptables防火墙和selinux 

        1.  配置java环境

        2.  搭建node1和node2的主从复制关系,略

    2.  安装mycat

        1.  下载mycat

            wget http://dl.mycat.io/1.6-RELEASE/Mycat-server-1.6-RELEASE-20161028204710-linux.tar.gz

            tar -zxvf Mycat-server-1.6-RELEASE-20161028204710-linux.tar.gz

            mv mycat /usr/local/

        2.  mycat目录如下            

bin     mycat命令,启动、重启、停止等
catlet  catlet为Mycat的一个扩展功能
conf    Mycat 配置信息,重点关注
lib     Mycat引用的jar包,Mycat是java开发的
logs    日志文件,包括Mycat启动的日志和运行的日志。

        3.  mycat常用配置文件

            配置文件都放在conf目录下           

server.xml   Mycat的配置文件,设置账号、参数等
schema.xml   Mycat对应的物理数据库和数据库表的配置
rule.xml     Mycat分片(分库分表)规则                 

        4.  配置mycat

            1.  /usr/local/mycat/conf/server.xml  配置账号,一个用来web app连接mycat,一个用来mycat连接mysql。

     <user name="root">
                <property name="password">123456</property>
                <property name="schemas">yangjianbo</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">yangjianbo</property>
                <property name="readOnly">true</property>
        </user>

                root用户用来web app连接mycat,schemas用来指定与schema.xml连接的名称。

                user用户用来mycat连接mysql库                  

            2.  /usr/local/mycat/conf/schema.xml  读写分离,分库分表,分片节点都是在这个文件配置

<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">

        <schema name="yangjianbo" checkSQLschema="false" sqlMaxLimit="100" dataNode="dn1">
        </schema>
        <dataNode name="dn1" dataHost="dbpool" database="student" />
        <dataHost name="dbpool" maxCon="1000" minCon="10" balance="3"
                          writeType="0" dbType="mysql" dbDriver="native" switchType="1"  slaveThreshold="100">
                <heartbeat>select user()</heartbeat>
                <!-- can have multi write hosts -->
                <writeHost host="master" url="192.168.1.37:3306" user="user_write" password="321">
                        <readHost host="read189" url="192.168.1.189:3306" user="user_read" password="321" />
                        <readHost host="read44" url="192.168.1.44:3306" user="user_read" password="321" />
                </writeHost>
        </dataHost>
</mycat:schema>

                定义dataNode的名称

                定义dataHost的名称

                定义哪个数据库

                定义写数据库

                定义读数据库

                参数配置:

                  balance=0  不开启读写分离,所有读操作都发送到当前可用的writeHost上。

                  balance=1  开启读写分离,全部的readhost与备用master都参与select语句的负载均衡。

                  balance=2  所有读操作都随机的在writeHost和readHost上分发

                  balance=3  所有读请求随机的分发到writeHost对应的readHost上,writeHost不负担读压力,注意balance=3只在1.4及其以后版本有。

                  writeType="0"  所有写操作都指向第一个writeHost,第一个挂了以后切换到第二个writeHost,重新启动后已切换后的为准。

                  writeType="1"  所有写操作随机发送到配置的writeHost,1.5以后废弃。

    4.  mysql主从复制集群的配置

        1.  设置写账号。

            grant select,insert,update,delete on test.* to user_write@"192.168.1.%" identified by '123';

            grant select,insert,update,delete on test.* to user_write@"localhost" identified by '123';

        2.  设置读账号。

            grant select on test.* to user_read@"192.168.1.%" identified by '321';

            grant select on test.* to user_read@"localhost" identified by '321';

    5.  启动mycat

        /usr/local/mycat/bin/mycat start

    6.  mycat测试

        1.  在一台机器上,安装mysql客户端,然后使用命令:

            mysql -h 192.168.1.77 -uroot -p  -P8066

            show databases;  显示是逻辑库的名称 yangjianbo

            use yangjianbo;

            show tables;  显示的是真实的表名

        2.  在客户端上,再开启一个窗口,打开9066端口,

            mysql -h 192.168.1.77 -uroot -p -P9066

            show @@datasourc;

        3.  在8066上,查询一下表,在9066上看到结果,read_load会在两台slave上增加。

            

        4.  在8066上,插入数据,在9066看到结果,write_load会在master上增加。

            

        5.  说明读写分离已经实现。

bin     mycat命令,启动、重启、停止等
catlet  catlet为Mycat的一个扩展功能
conf    Mycat 配置信息,重点关注
lib     Mycat引用的jar包,Mycat是java开发的
logs    日志文件,包括Mycat启动的日志和运行的日志。
posted @ 2022-10-21 15:26  奋斗史  阅读(251)  评论(0)    收藏  举报