• MyCat实战


    概念介绍

    MyCat 的整体结构中,分为两个部分:上面的逻辑结构、下面的物理结构。
    MyCat 的逻辑结构主要负责逻辑库、逻辑表、分片规则、分片节点等逻辑结构的处理,而具体的数据存储还是在物理结构,也就是数据库服务器中存储的

    需求 

    由于 tb_order 表中数据量很大,磁盘 IO 及容量都到达了瓶颈,现在需要对 tb_order 表进行数
    据分片,分为三个数据节点,每一个节点主机位于不同的服务器上 , 具体的结构,参考下图:

    环境准备

    准备 3 台服务器:
    • 192.168.2.3MyCat中间件服务器,同时也是第一个分片服务器。
    • 192.168.2.4:第二个分片服务器。
    • 192.168.2.5:第三个分片服务器。

    在上述3台数据库中创建数据库 db01 ,create database db01;

    配置讲解

    schema.xml

    schema.xml 作为 MyCat 中最重要的配置文件之一 , 涵盖了 MyCat 的逻辑库 、 逻辑表 、 分片规
    则、分片节点及数据源的配置。
    主要包含以下三组标签:
    • schema标签
    • datanode标签
    • datahost标签

     schema标签

    1.schema 定义逻辑库

    schema 标签用于定义 MyCat 实例中的逻辑库 , 一个 MyCat 实例中 , 可以有多个逻辑库 , 可以通过 schema 标签来划分不同的逻辑库。 MyCat 中的逻辑库的概念,等同于 MySQL 中的 database 概念 , 需要操作某个逻辑库下的表时 , 也需要切换逻辑库 (use xxx)
    核心属性:
    • name:指定自定义的逻辑库库名
    • checkSQLschema:在SQL语句操作时指定了数据库名称,执行时是否自动去除;true:自动去除,false:不自动去除
    • sqlMaxLimit:如果未指定limit进行查询,列表查询模式查询多少条记录

    2.schema 中的table定义逻辑表

    table 标签定义了 MyCat 中逻辑库 schema 下的逻辑表 , 所有需要拆分的表都需要在 table 标签中定
    义 。
    核心属性:
    • name:定义逻辑表表名,在该逻辑库下唯一
    • dataNode:定义逻辑表所属的dataNode,该属性需要与dataNode标签中name对应;多个dataNode逗号分隔
    • rule:分片规则的名字,分片规则名字是在rule.xml中定义的
    • primaryKey:逻辑表对应真实表的主键
    • type:逻辑表的类型,目前逻辑表只有全局表和普通表,如果未配置,就是普通表;全局表,配置为 global

    datanode标签

    核心属性:
    • name:定义数据节点名称
    • dataHost:数据库实例主机名称,引用自 dataHost 标签中name属性
    • database:定义分片所属数据库

    datahost标签

    该标签在 MyCat 逻辑库中作为底层标签存在 , 直接定义了具体的数据库实例、读写分离、心跳语句。
    核心属性:
    •  name:唯一标识,供上层标签使用
    • maxCon/minCon:最大连接数/最小连接数
    • balance:负载均衡策略,取值 0,1,2,3
    • writeType:写操作分发方式(0:写操作转发到第一个writeHost,第一个挂了,切换到第二个;1:写操作随机分发到配置的writeHost
    • dbDriver:数据库驱动,支持 nativejdbc

    rule.xml

    rule.xml 中定义所有拆分表的规则 , 在使用过程中可以灵活的使用分片算法 , 或者对同一个分片算法
    使用不同的参数 , 它让分片过程可配置化。主要包含两类标签: tableRule Function

    server.xml

    server.xml配置文件包含了MyCat的系统配置信息,主要有两个重要的标签:systemuser

    system标签

    主要配置MyCat中的系统配置信息,对应的系统配置项及其含义,如下:

    属性
    取值
    含义
    charset
    utf8
    设置 Mycat 的字符集 , 字符集需要与 MySQL 的字符集保持一致
    nonePasswordLogin
    0,1
    0 为需要密码登陆、 1 为不需要密码登陆 , 默认为0 ,设置为 1 则需要指定默认账户
    useHandshakeV10
    0,1
    使用该选项主要的目的是为了能够兼容高版本的jdbc 驱动 , 是否采用
    HandshakeV10Packet 来与 client 进行通信, 1: , 0:
    useSqlStat
    0,1
    开启 SQL 实时统计 , 1 为开启 , 0 为关闭 ; 开启之后, MyCat 会自动统计 SQL 语句的执行情况 ; mysql -h 127.0.0.1 -P 9066  -u root -p 查看 MyCat 执行的 SQL, 执行效率比较低的SQL , SQL 的整体执行情况、读写比例等 ; show @@sql ; show
    @@sql.slow ; show @@sql.sum ;
    useGlobleTableCheck
    0,1
    是否开启全局表的一致性检测。 1 为开启 , 0为关闭 。
    sqlExecuteTimeout
    1000
    SQL 语句执行的超时时间 , 单位为 s ;
    sequnceHandlerType
    0,1,2
    用来指定 Mycat 全局序列类型, 0 为本地文件,1 为数据库方式, 2 为时间戳列方式,默认使用本地文件方式,文件方式主要用于测试
    sequnceHandlerPattern
    正则表达式
    必须带有 MYCATSEQ 或者 mycatseq 进入序列匹配流程 注意MYCATSEQ_ 有空格的情况
    subqueryRelationshipCheck
    true,false
    子查询中存在关联查询的情况下 , 检查关联字段中是否有分片字段 . 默认 false
    useCompression
    0,1
    开启 mysql 压缩协议 , 0 : 关闭 , 1 : 开启
    fakeMySQLVersion
    5.5,5.6
    设置模拟的 MySQL 版本号
    defaultSqlParser
    由于 MyCat 的最初版本使用了 FoundationDB的SQL 解析器 , MyCat1.3 后增加了 Druid解析器, 所以要设置 defaultSqlParser 属性来指定默认的解析器; 解析器有两个 :
    druidparser fdbparser, 在MyCat1.4之后 , 默认是 druidparser,
    fdbparser 已经废除了
    processors
    1,2....
    指定系统可用的线程数量 , 默认值为 CPU 核心 x 每个核心运行线程数量 ; processors 会影响processorBufferPool, processorBufferLocalPercent,
    processorExecutor 属性 , 所有 , 在性能调优时, 可以适当地修改 processors
    processorBufferChunk
    指定每次分配 Socket Direct Buffer 默认值为4096 字节 , 也会影响 BufferPool 长度 ,如果一次性获取字节过多而导致buffer 不够用, 则会出现警告 , 可以调大该值
    processorExecutor
    指定 NIOProcessor 上共享 businessExecutor固定线程池的大小 ; MyCat把异步任务交给 businessExecutor 线程池中, 在新版本的 MyCat 中这个连接池使
    用频次不高 , 可以适当地把该值调小
    packetHeaderSize
    指定 MySQL 协议中的报文头长度 , 默认 4 个字节
    maxPacketSize
    指定 MySQL 协议可以携带的数据最大大小 , 默认值为16M
    idleTimeout
    30
    指定连接的空闲时间的超时长度 ; 如果超时 , 将关闭资源并回收, 默认 30 分钟
    txIsolation
    1,2,3,4
    初始化前端连接的事务隔离级别 , 默认为REPEATED_READ , 对应数字为 3READ_UNCOMMITED=1; READ_COMMITTED=2;REPEATED_READ=3;
    SERIALIZABLE=4;
    sqlExecuteTimeout
    300
    执行 SQL 的超时时间 , 如果 SQL 语句执行超时 ,
    将关闭连接 ; 默认 300 ;
    serverPort
    8066
    定义 MyCat 的使用端口 , 默认 8066
    managerPort
    9066
    定义 MyCat 的管理端口 , 默认 9066

    user标签

    配置 MyCat 中的用户、访问密码,以及用户针对于逻辑库、逻辑表的权限信息,具体的权限描述方式及
    配置说明如下:
    在测试权限操作时,我们只需要将 privileges 标签的注释放开。 在 privileges 下的 schema标签中配置的dml 属性配置的是逻辑库的权限。 在 privileges schema 下的 table 标签的 dml 属性中配置逻辑表的权限。

    MyCat配置配置

    1.schema.xml

    schema.xml 中配置逻辑库、逻辑表、数据节点、节点主机等相关信息。具体的配置如下:
    1. <?xml version="1.0"?>
    2. <!DOCTYPE mycat:schema SYSTEM "schema.dtd">
    3. <mycat:schema xmlns:mycat="http://io.mycat/">
    4. <schema name="DB01" checkSQLschema="true" sqlMaxLimit="100" > <!-- 逻辑库 -->
    5. <table name="TB_ORDER" dataNode="dn1,dn2,dn3" rule="auto-sharding-long" /><!-- 逻辑表 -->
    6. </schema>
    7. <dataNode name="dn1" dataHost="dhost1" database="db01" /><!-- 数据节点 -->
    8. <dataNode name="dn2" dataHost="dhost2" database="db01" />
    9. <dataNode name="dn3" dataHost="dhost3" database="db01" />
    10. <!-- 节点主机 -->
    11. <dataHost name="dhost1" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="jdbc" switchType="1" slaveThreshold="100">
    12. <heartbeat>select user()</heartbeat>
    13. <writeHost host="master" url="jdbc:mysql://192.168.2.3:3306?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai&characterEncoding=utf8" user="root" password="newPwd520@" />
    14. </dataHost>
    15. <dataHost name="dhost2" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="jdbc" switchType="1" slaveThreshold="100">
    16. <heartbeat>select user()</heartbeat>
    17. <writeHost host="master" url="jdbc:mysql://192.168.2.4:3306?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai&characterEncoding=utf8" user="root" password="newPwd520@" />
    18. </dataHost>
    19. <dataHost name="dhost3" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="jdbc" switchType="1" slaveThreshold="100">
    20. <heartbeat>select user()</heartbeat>
    21. <writeHost host="master" url="jdbc:mysql://192.168.2.5:3306?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai&characterEncoding=utf8" user="root" password="newPwd520@" />
    22. </dataHost>
    23. </mycat:schema>

    2.server.xml

    需要在 server.xml 中配置用户名、密码,以及用户的访问权限信息,具体的配置如下:
    1. <!-- 用户及密码信息 -->
    2. <user name="root" defaultAccount="true">
    3. <property name="password">123456</property>
    4. <property name="schemas">DB01</property>
    5. <!-- <property name="defaultSchema">TESTDB</property> -->
    6. <!--No MyCAT Database selected 错误前会尝试使用该schema作为schema,不设置则为null,报错 -->
    7. <!-- 表级 DML 权限设置 -->
    8. <!--
    9. <privileges check="false">
    10. <schema name="TESTDB" dml="0110" >
    11. <table name="tb01" dml="0000"></table>
    12. <table name="tb02" dml="1111"></table>
    13. </schema>
    14. </privileges>
    15. -->
    16. </user>
    17. <user name="user">
    18. <property name="password">123456</property>
    19. <property name="schemas">DB01</property>
    20. <property name="readOnly">true</property>
    21. <!-- <property name="defaultSchema">TESTDB</property> -->
    22. </user>

    上述的配置表示,定义了两个用户 root user ,这两个用户都可以访问 DB01 这个逻辑库,访 问密码都是123456,但是root用户访问DB01逻辑库,既可以读,又可以写,但是 user用户访问DB01逻辑库是只读的。

    启动MyCat 

    配置完毕后,先启动涉及到的 3 台分片服务器,然后启动 MyCat 服务器。切换到 Mycat 的安装目录,执行如下指令,启动Mycat
    1. cd /usr/local/mycat/
    2. #启动
    3. bin/mycat start
    4. #停止
    5. bin/mycat stop
    Mycat 启动之后,占用端口号 8066 启动完毕之后,可以查看logs 目录下的启动日志,查看 Mycat是否启动完成。tail -f logs/wrapper.log 

     

    测试 

    通过如下指令,就可以连接并登陆 MyCat
    mysql -h 192.168.2.3 -P 8066 -uroot -p123456
    我们看到我们是通过 MySQL 的指令来连接的 MyCat ,因为 MyCat 在底层实际上是模拟了 MySQL 的协议。
    然后就可以在 MyCat 中来创建表,并往表结构中插入数据,查看数据在 MySQL 中的分布情况。
    1. use DB01;
    2. CREATE TABLE TB_ORDER (
    3. id BIGINT(20) NOT NULL,
    4. title VARCHAR(100) NOT NULL ,
    5. PRIMARY KEY (id)
    6. ) ENGINE=INNODB DEFAULT CHARSET=utf8 ;
    7. INSERT INTO TB_ORDER(id,title) VALUES(1,'goods1');
    8. INSERT INTO TB_ORDER(id,title) VALUES(2,'goods2');
    9. INSERT INTO TB_ORDER(id,title) VALUES(3,'goods3');
    10. INSERT INTO TB_ORDER(id,title) VALUES(1,'goods1');
    11. INSERT INTO TB_ORDER(id,title) VALUES(2,'goods2');
    12. INSERT INTO TB_ORDER(id,title) VALUES(3,'goods3');
    13. INSERT INTO TB_ORDER(id,title) VALUES(5000000,'goods5000000');
    14. INSERT INTO TB_ORDER(id,title) VALUES(10000000,'goods10000000');
    15. INSERT INTO TB_ORDER(id,title) VALUES(10000001,'goods10000001');
    16. INSERT INTO TB_ORDER(id,title) VALUES(15000000,'goods15000000');
    17. INSERT INTO TB_ORDER(id,title) VALUES(15000001,'goods15000001');

     经过测试,我们发现,在往 TB_ORDER 表中插入数据时:

    • 如果id的值在1-500w之间,数据将会存储在第一个分片数据库中。
    • 如果id的值在500w-1000w之间,数据将会存储在第二个分片数据库中。
    • 如果id的值在1000w-1500w之间,数据将会存储在第三个分片数据库中。
    • 如果id的值超出1500w,在插入数据时,将会报错。

    如下图效果 

     

     

  • 相关阅读:
    Java中去掉字符串中的非中文字符
    踩坑了,踩到一个特别无语的常识坑
    微服务化解决文库下载业务问题实践
    解析Redis缓存穿透、击穿和雪崩问题及解决方案
    Android原生插件开发-包名篇
    设计模式:03-单例模式
    STM32 SPI对存储芯片发送写是能命令后一直忙等待
    Java后端面试内容总结
    如何在three.js中画3D圆弧及半圆弧组成圆
    c数组与结构体
  • 原文地址:https://blog.csdn.net/qq_63431773/article/details/133788763