zoukankan      html  css  js  c++  java
  • Mycat

    文章地址:https://www.cnblogs.com/youzhibing/p/9553766.html

    前言

      开心一刻

        上语文课,不小心睡着了,坐在边上的同桌突然叫醒了我,并小声说道:“读课文第三段”。我立马起身大声读了起来。正在黑板写字的老师吓了一跳,老师郁闷的看着我,问道:“同学有什么问题吗?”,我貌似知道了什么,蛋定的说了一句:“这段写的真好!我给大伙念念!”,老师还较真了:“你说说看,好在哪里?”,顿时我就无语了,脸黑着望向了同桌了,心想着:“这是个畜生啊!”

      

      路漫漫其修远兮,吾将上下而求索!

      github:https://github.com/youzhibing

      码云(gitee):https://gitee.com/youzhibing

    前情回顾

      mysql5.7.18的安装与主从复制中讲到了基于mysql5.7.18的主从复制结构的搭建,比较简单,只要细心点,很容易搭建成功。

      spring集成mybatis实现mysql读写分离从代码层面实现了读写分离(实现方式:注解+aop),需要配置两个数据源:masterDataSource、slaveDataSource,分别针对主从数据库,另外还需要在代码层面明确指定用哪个数据源。会增大代码量(虽然只是增加一个注解),并且耦合在代码中不利于拓展与后续维护,一旦进行修改就需要重新编译打包,最严重的是如果数据库宕机了,应用就会抛异常,完全不能正常服务了。那么有没有其他层面的更优方案呢?肯定是有的,我们可以从数据库的层面来实现读写分离,应用代码不感知连接的是什么数据库,按平时单库的方式处理即可,具体实现我们往下看。

    mysql主从实现

      Mycat不负责任何的数据同步问题,mysql的主从复制还得从mysql层面来实现;如果没有实现mysql的主从复制,后文就都成了。

      mysql的主从复制是实现读写分离的基础,具体的搭建过程请参考:mysql5.7.18的安装与主从复制,本文就不展示详细的搭建过程了。我的mysql主从信息如下

        master:192.168.1.210;slave:192.168.1.211; 需要复制的数据库:mycat_db

    Mycat搭建

      Mycat是什么?是数据库中间件,介于数据库与应用之间,进行数据处理与交互的中间件服务,可以简单的理解成数据库代理,我们的应用只需要与数据库中间件交互,而无需关注复杂的数据库部署。

      如上图所示,数据被分到多个分片数据库后,应用如果需要读取数据,就需要处理多个数据源的数据。如果没有数据库中间件,那么应用将直接面对分片集群,数据源切换、事务处理、数据聚合都需要在应用层直接处理,原本该是专注于业务的应用,将会花大量的工作来处理分片后的问题,最重要的是每个应用处理将是完全的重复造轮子。所以有了数据库中间件,应用只需要关注业务处理,大量的通用的数据聚合、事务、数据源切换都由数据库中间件来处理。更多Mycat信息,请查阅《Mycat权威指南》

      192.168.1.212上搭建Mycat

        JDK的安装

          Mycat依赖jdk,我们需要先安装jdk,必须是JDK7或更高版本;具体安装过程就不做展示了,大家可参考:virtualBox安装centos,并搭建tomcat

        Mycat安装

          安装包:Mycat-server-1.6.6.1-release-20181031195535-linux.tar,在/opt目录下

            [root@centos212 opt]# cp Mycat-server-1.6.6.1-release-20181031195535-linux.tar.gz -C /usr/local
            [root@centos212 local]# useradd mycat
            [root@centos212 local]# chown -R mycat:mycat /usr/local/mycat
            [root@centos212 local]# passwd mycat  

          修改mycat内存配置
            我的linux虚拟机配置的内存大小是1GB,大家需要根据自己的实际情况进行配置

            [root@centos212 local]# vi mycat/conf/wrapper.conf

    wrapper.java.additional.10=-Xmx4G    (大约在36行)
    wrapper.java.additional.11=-Xms1G
    改成
    wrapper.java.additional.10=-Xmx1G
    wrapper.java.additional.11=-Xms256M

          配置hostname(若已配置则忽略)       

            [root@centos212 local]# vi /etc/sysconfig/network
              追加一行:HOSTNAME=你的主机名(xxxx),我的主机名是centos212
            [root@centos212 local]# vi /etc/hosts
              在127.0.0.1和::1末尾追加你的主机名(xxxx),如下图所示,

          将MyCat配置到环境变量中

            [root@centos212 local]# vi /etc/profile

            增加如下内容         

              MYCAT_HOME=/usr/local/mycat
              PATH=$MYCAT_HOME/bin:$PATH

            保存后退出,执行source命令使配置生效

              [root@centos212 local]# source /etc/profile

          配置mycat

            server.xml和rule.xml先不修改,用默认的即可;只需要简单配置下schema.xml

    <?xml version="1.0"?>
    <!DOCTYPE mycat:schema SYSTEM "schema.dtd">
    <mycat:schema xmlns:mycat="http://io.mycat/">
    
        <schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100" dataNode="dn1">
        </schema>
        <!-- <dataNode name="dn1$0-743" dataHost="localhost1" database="db$0-743"
            /> -->
        <dataNode name="dn1" dataHost="localhost1" database="test_db" />
        <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.210:3306" user="root" password="123456" />
        </dataHost>
    </mycat:schema>

            默认有两个账号可以连接mycat的TESTDB,root:123456和user:user(在server.xml中),user账号只有只读权限。

          启动mycat

             [root@centos212 local]# mycat start

      搭建结果展示

        可以看到,通过mycat我们成功往192.168.1.210的test_db库中创建了一张tbl_user表。

    mysql读写分离、高可用实现

      本文不涉及复杂的数据库部署,只是简单的mysql主从部署(单主单从),Mycat实现mysql的读写分离与高可用;mysql主从复制已经搭建好,Mycat也已经搭建好,剩下的就是配置Mycat,将Mycat与我们的mysql整合起来,结构图如下

      如图所示,writeHost表示主节点,readHost表示从节点,Mycat内部定期对一个dataHost里所有的writeHost与readHost节点发起心跳检测(writeHost与readHost都可以配置多个,至于数据同步的问题则需要我们从mysql层面实现了,Mycat并不提供数据同步的支持,本文只讲mysql一主一从),正常情况下,Mycat会将第一个writeHost作为写节点,所有的DML SQL会发送给此节点,若Mycat开启了读写分离,则Select SQL会根据读写分离策略发往readHost(+writeHost)执行。当一个dataHost里面配置了多个writeHost时,如果第一个writeHost宕机,则Mycat会在默认的3次心跳检查失败后,自动切换到下一个可用的writeHost,以此类推。

      这存在一个问题,就是当宕机的writeHost恢复后,怎么重新加入Mycat,要不要恢复为原来的写节点? 最佳建议方式是:保持现有状态不变,改旗易帜,恢复后的mysql节点作为从节点,跟随新的主节点,重新配置主从同步,原来跟随该节点做同步的从节点也同样换帅,重新配置同步源,这些节点的数据手工完成同步后,再加入Mycat里。

      配置Mycat,实现mysql读写分离与高可用

        此种需求下,Mycat的配置非常简单,不用针对每个表进行配置,只需要在schema.xml中的元素上增加dataNode="defaultDN"属性,并配置此dataNode对应的真实物理数据库的database,然后dataHost开启读写分离功能即可。具体配置如下,server.xml和rule.xml先不修改,用默认的即可;只需要简单配置下schema.xml

    <?xml version="1.0"?>
    <!DOCTYPE mycat:schema SYSTEM "schema.dtd">
    <mycat:schema xmlns:mycat="http://io.mycat/">
    
        <schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100" dataNode="dn1">
        </schema>
        <!-- <dataNode name="dn1$0-743" dataHost="localhost1" database="db$0-743"
            /> -->
        <dataNode name="dn1" dataHost="localhost1" database="mycat_db" />
        <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.1.210:3306" user="root" password="123456">
                <readHost host="hostS1" url="192.168.1.211:3306" user="root" password="123456" />    <!-- 读写分离; 写走hostM1,读走hostS1; hostM1宕机了, hostS1也不可用 -->
            </writeHost>
            <writeHost host="hostM2" url="192.168.1.211:3306" user="root" password="123456" /> <!-- 高可用,hostM1宕机了, hostM2顶上 -->
        </dataHost>
    </mycat:schema>

        重启mycat:[root@centos212 logs]# mycat restart,mycat数据库TESTDB内容如下

      测试结果展示

        读写分离

          一般情况,查询会走slave节点,其他走master节点,对master节点数据库的增、删、改操作最终会同步到slave节点,但这个同步所需要的时间不好掌握(网络延时等因素),如果延时太长,我们新增一条数据后立即去查询,很有可能会查询不到刚新增的的数据;如果对数据的实时性要求比较高的查询,我们可以强制查询走master节点,如下所示

            强制走master:/*!mycat:db_type=master*/ select * from tbl_user;强制走slave:/*!mycat:db_type=slave*/ select * from tbl_user

          另外我们可以配置mycat,根据主从延时时长来决定查询走master还是slave,具体配置可查阅《Mycat权威指南》。

          读写分离示例如下:

          可以看到,一般查询走的是slave;增、删、改走master,然后同步到slave;我们也可以强制走master,还是slave。示例中我手动的将slave中的王五改成了王五_1,是为了更好的展示查询请求是走的master还是slave,真实情况是不会出现这种情况的。

        高可用

          我们手动停掉master上的mysql服务,看看mycat能不能自动的切换到下一个writeHost,示例如下

          mycat将master从hostM1切换到hostM2需要一定的时间,切换过程中如果强制从master操作,会抛出连接异常(java.net.ConnectException: 拒绝连接),这是属于正常情况。当切换完成之后,就可以正常操作mycat了,而我们的操作方式无需做任何改变(应用无需做任何变化,仍按之前的方式访问mycat即可)。

          宕机的master节点修复后,如何重新加入mycat,这个问题在前面已经讲过,该节点及其readHost节点全部以slave的形式加入到其他writeHost的readHost中,修改schema.xml,而不要去修改dnindex.properties,另外还得从mysql层面修改同步源。

    总结

      1、数据的同步在mysql层面实现的,mycat不负责任何的数据库同步;

      2、mycat的搭建比较简单,但也有一些注意点:依赖JDK以及其版本,hostname配置等等。期间如果遇到什么问题,尽量百度,就不要google了,Mycat是中国制造,百度搜索的资料更全;

      3、数据库的读写分离是mycat最常用的场景之一,配置比较简单,细心一点,实现起来应该不难; 

      4、读写分离往往还伴随着高可用,同样mycat也支持mysql的高可用,能够自动的进行master的切换;

      5、关于mycat自身的高可用与负载均衡,请上飞机:Mycat - 高可用与负载均衡实现,满满的干货!

    参考

      《Mycat实战指南》

  • 相关阅读:
    sqlserver中判断表或临时表是否存在
    Delphi 简单方法搜索定位TreeView项
    hdu 2010 水仙花数
    hdu 1061 Rightmost Digit
    hdu 2041 超级楼梯
    hdu 2012 素数判定
    hdu 1425 sort
    hdu 1071 The area
    hdu 1005 Number Sequence
    hdu 1021 Fibonacci Again
  • 原文地址:https://www.cnblogs.com/zxcnn/p/11751884.html
Copyright © 2011-2022 走看看