zoukankan      html  css  js  c++  java
  • MyCat中间件:读写分离(转)

    利用MyCat中间件实现读写分离

    需要两步:
    1、搭建MySQL主从复制环境
    2、配置MyCat读写分离策略

    一、搭建MySQL主从环境

    参考上一篇博文:MySQL系列之七:主从复制

    二、配置MyCat读写分离策略

    本篇只讨论MyCat读写分离,有关的配置文件schema.xml 和 server.xml(暂且不谈分库分表、性能优化)。

    1、schema.xml文件

    MyCat作为中间件,它只是一个代理,本身并不进行数据存储,需要连接后端的MySQL物理服务器,此文件就是用来连接MySQL服务器的!~(当然分库分表策略、分片节点也在此文件中,暂且不谈)
    先看一个完整配置的例子:【请注意修改自己的MySQL连接信息】

    <?xml version="1.0"?>
    <!DOCTYPE mycat:schema SYSTEM "schema.dtd">
    <mycat:schema xmlns:mycat="http://io.mycat/">
    <schema name="mycatdb" checkSQLschema="false" sqlMaxLimit="100">
    <!-- 自动取模分片 -->
    <table name="t_person" dataNode="dn1,dn2,dn3" rule="mod-long" />
    <!-- 一致性hash分片,分片列不要使用MySQL原生函数 -->
    <table name="t_user" primaryKey="id" dataNode="dn1,dn2" rule="sharding-by-murmur" />
    <!-- 全局表 -->
    <table name="province" type="global" dataNode="dn1,dn2,dn3" />
    <!-- E-R关系分片 -->
    <table name="customer" dataNode="dn1,dn2,dn3" rule="auto-sharding-long-customer">
    <childTable name="orders" joinKey="customer_id" parentKey="id"/>
    </table>
    <!-- E-R关系分片,多表 -->
    <table name="user" primaryKey="id" dataNode="dn1,dn2" rule="mod-long-test">
    <childTable name="cell" joinKey="user_id" parentKey="id"/>
    <childTable name="note" joinKey="user_id" parentKey="id"/>
    <childTable name="lit" joinKey="user_id" parentKey="id"/>
    <childTable name="lit_usr" joinKey="user_id" parentKey="id"/>
    </table>
    </schema>
    <!-- 分片节点信息 -->
    <dataNode name="dn1" dataHost="localhost1" database="db1" />
    <dataNode name="dn2" dataHost="localhost1" database="db2" />
    <dataNode name="dn3" dataHost="localhost1" database="db3" />
    <!-- 本篇重点来了 !!! -->
    <!-- 连接MySQL的信息 && 读写分离策略 -->
    <dataHost name="localhost1" maxCon="500" minCon="100" balance="0"
    writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">


    <heartbeat>select user();</heartbeat>
    <writeHost host="hostM1" url="localhost:3306" user="root" password="abcdef">
    <readHost host="hostS1" url="localhost:3306" user="root" password="123456" />
    </writeHost>
    </dataHost>
    </mycat:schema>

    此处有三点需要注意:
    balance=”1”,writeType=”0” ,switchType=”1”
    balance 属性负载均衡类型,目前的取值有 4 种:

    balance="0", 不开启读写分离机制,所有读操作都发送到当前可用的writeHost 上。
    balance="1",全部的 readHost 与 stand by writeHost 参与 select 语句的负载均衡,简单的说,当双主双从模式(M1 ->S1 , M2->S2,并且 M1 与 M2 互为主备),正常情况下, M2,S1,S2 都参与 select 语句的负载均衡。
    balance="2",所有读操作都随机的在 writeHost、 readhost 上分发。
    balance="3", 所有读请求随机的分发到 wiriterHost 对应的 readhost 执行,writerHost 不负担读压力,注意 balance=3 只在 1.4 及其以后版本有, 1.3 没有。

    writeType 属性,负载均衡类型,目前的取值有 3 种:


    writeType="0", 所有写操作发送到配置的第一个 writeHost,第一个挂了切到还生存的第二个writeHost,重新启动后已切换后的为准,切换记录在配置文件中:dnindex.properties .
    writeType="1",所有写操作都随机的发送到配置的 writeHost。
    writeType="2",没实现。

    switchType 属性

    -1 表示不自动切换
    1 默认值,自动切换
    2 基于MySQL 主从同步的状态决定是否切换

    以上为最简单的配置,一主一从结构。
    MyCat支持双主多从,配置两个writeHost兄弟节点,多个readHost节点即可,请自行摸索。
    也可以有多台MySQL服务器,或者SQL Server、Oracle等,配置多个dataHost节点就可以~


    2、server.xml文件

    此文件其实跟读写分离策略关系不大,但是需要用此文件来配置连接MyCat的用户及权限等,因此在这里简单说明。

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE mycat:server SYSTEM "server.dtd">
    <mycat:server
    xmlns:mycat="http://io.mycat/">

    <system>
    <!-- SQL解析器 -->
    <property name="defaultSqlParser">druidparser</property>
    </system>
    <user name="root">
    <property name="password">123456</property>
    <property name="schemas">mycatdb</property>
    </user>
    <user name="mycat">
    <property name="password">mycat</property>
    <property name="schemas">mycatdb</property> </user>
    <user name="user">
    <property name="password">user</property>
    <property name="schemas">mycatdb</property>
    <property name="readOnly">true</property>
    </user>
    </mycat:server>

    以上配置文件启动MyCat服务,查看8066端口:

    [root@dras-test conf]# lsof  -i:8066
    COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
    java 48021 root 122u IPv6 9441156 0t0 TCP *:8066 (LISTEN)

    说明mycat成功启动!
    使用MySQL客户端,或者使用如下命令行即可连接MyCat:

    # mysql -uroot -p123456 -h127.0.0.1 -P8066 -Dmycatdb

    这里写图片描述

    三、验证

    1、主从复制验证
    master端:

    mysql> create database db1;
    Query OK, 1 row affected (0.00 sec)
    mysql> create database db2;
    Query OK, 1 row affected (0.00 sec)
    mysql> create database db3;
    Query OK, 1 row affected (0.00 sec)
    mysql> show databases;
    +--------------------+

    | Database |
    +--------------------+

    | information_schema |
    | db1 |
    | db2 |
    | db3 |
    | mysql |
    | performance_
    schema |
    | sys |
    +--------------------+
    8 rows in set (0.00 sec)

    slave端:

    mysql> show databases;
    +--------------------+

    | Database |
    +--------------------+

    | information_schema |
    | db1 |
    | db2 |
    | db3 |
    | mysql |
    | performance_
    schema |
    | sys |
    +--------------------+

    8 rows in set (0.00 sec)

    主从复制成功!

    2、读写分离验证
    我们在mycat中想t_person插入5条数据:

    insert into t_person(id,name,uuid,lastime) values(1,'moxiao1',uuid(), now());
    insert into t_person(id,name,uuid,lastime) values(2,'moxiao2',uuid(), now());
    insert into t_person(id,name,uuid,lastime) values(3,'moxiao3',uuid(), now());
    insert into t_person(id,name,uuid,lastime) values(4,'moxiao4',uuid(), now());
    insert into t_person(id,name,uuid,lastime) values(5,'moxiao5',uuid(), now());

    这里我们注意一点,因为t_person是按照id列进行分片,可以正常分片。
    如果是按照uuid列进行分片,则在mycat里插入时uuid列不能直接使用mysql的原生函数,否则mycat直接把uuid()函数作为列值传入分片函数进行运算,导致值是一样的,从而不能达到分片的效果。

    然后,因为balance=‘2’,读操作会随机在master和slave上进行,
    所以为了测试,我在slave上再插入一条:
    MySQL连接slave:
    【注意:此条是在slave上插入,会导致slave上数据比master多一条。为了验证读写分离,实际环境不应该在slave进行写操作。】

    insert into t_person(id,name,uuid,lastime) values(8,'moxiao8',uuid(), now());

    然后连接mycat,进行查询,发现读时是随机到master和slave上的,
    也就是说balance=‘2’读写分离成功了!
    当然也可以设置balance=‘1’,读操作只在readHost指定的mysql上进行。


    mysql> select * from t_person;
    +----+---------+--------------------------------------+---------------------+

    | id | name | uuid | lastime |
    +----+---------+--------------------------------------+---------------------+

    | 3 | Moxiao3 | Cf399053-20c2-11e7-a5ef-000c293fed8e | 2017-04-14 14:03:28 |
    | 2 | Moxiao2 | Bf399052-20c2-11e7-a5ef-000c293fed8e | 2017-04-14 14:03:28 |
    | 5 | Moxiao5 | Ef399055-20c2-11e7-a5ef-000c293fed8e | 2017-04-14 14:03:28 |
    | 8 | Moxiao8 | 22e7e8dc-23d4-11e7-9181-b8aeed3a0524 | 2017-04-18 09:12:42 |
    | 1 | Moxiao1 | Af399051-20c2-11e7-a5ef-000c293fed8e | 2017-04-14 14:03:28 |
    | 4 | Moxiao4 | Df399054-20c2-11e7-a5ef-000c293fed8e | 2017-04-14 14:03:28 |
    +----+---------+--------------------------------------+---------------------+

    6 rows in set (0.01 sec)
    mysql> select * from t_person;
    +----+---------+--------------------------------------+---------------------+

    | id | name | uuid | lastime |
    +----+---------+--------------------------------------+---------------------+

    | 3 | Moxiao3 | Cf399053-20c2-11e7-a5ef-000c293fed8e | 2017-04-14 14:03:28 |
    | 1 | Moxiao1 | Af399051-20c2-11e7-a5ef-000c293fed8e | 2017-04-14 14:03:28 |
    | 4 | Moxiao4 | Df399054-20c2-11e7-a5ef-000c293fed8e | 2017-04-14 14:03:28 |
    | 2 | Moxiao2 | Bf399052-20c2-11e7-a5ef-000c293fed8e | 2017-04-14 14:03:28 |
    | 5 | Moxiao5 | Ef399055-20c2-11e7-a5ef-000c293fed8e | 2017-04-14 14:03:28 |
    +----+---------+--------------------------------------+---------------------+

    5 rows in set (0.01 sec)

    OK, 尽情折腾吧!~

  • 相关阅读:
    shell基础知识8-xargs命令
    shell基础知识7-字段分隔符与迭代器
    shell基础知识6-在不按回车键的情况下读入N个字符
    DevOps
    DevOps
    Jenkins
    Jenkins
    Jenkins
    Jenkins
    Gerrit
  • 原文地址:https://www.cnblogs.com/jpfss/p/8203894.html
Copyright © 2011-2022 走看看