MyCat分片实现

MyCat介绍

官方网站::http://www.mycat.org.cn/

MyCat核心概念

  • Schema:由它指定逻辑数据库(相当于MySQL的database数据库)
  • Table:逻辑表(相当于MySQL的table表)
  • DataNode:真正存储数据的物理节点
  • DataHost:存储节点所在的数据库主机(指定MySQL数据库的连接信息)
  • User:MyCat的用户(类似于MySQL的用户,支持多用户)

MyCat主要解决问题

  • 海量数据保存
  • 查询优化

MyCat对多数据库的支持

  • MySQL
  • Oracle
  • PostgreSQL
  • SQL Server
  • MongoDB

MyCat分片策略

MyCAT支持水平分片与垂直分片:

  • 水平分片:一个表格的数据分割到多个节点上,按照行分隔
  • 垂直分片:一个数据库中多个表格A,B,C,A存储到节点1上,B存储到节点2上,C存储到节点3 上

MyCat分片策略

MyCAT通过定义表的分片规则来实现分片,每个表格可以捆绑一个分片规则,每个分片规则指定一个分片字段并绑定一个函数,来实现动态分片算法。

  • Schema:逻辑库,与MySQL中的Database(数据库)对应,一个逻辑库中定义了所包括的Table
  • Table:表,即物理数据库中存储的某一张表,与传统数据库不同,这里的表格需要声明其所存储的逻辑数据节点DataNode。在此可以指定表的分片规则
  • DataNode:MyCAT的逻辑数据节点,是存放table的具体物理节点,也称之为分片节点,通过 DataHost来关联到后端某个具体数据库上
  • DataHost:定义某个物理库的访问地址,用于捆绑到Datanode上

MyCat安装

安装并启动MyCat

wget http://dl.mycat.org.cn/1.6.7.3/20190927161129/Mycat-server-1.6.7.3-release-20190927161129-linux.tar.gz
tar -zxf Mycat-server-1.6.7.3-release-20190927161129-linux.tar.gz

进入mycat/bin,启动MyCat

  • 启动命令:./mycat start
  • 停止命令:./mycat stop
  • 重启命令:./mycat restart
  • 查看状态:./mycat status

访问MyCat

使用MySQL的客户端直接连接mycat服务。默认服务端口为8066

mysql -uroot -p123456 -h127.0.0.1 -P8066

MyCat分片

配置schema.xml

什么是schema.xml

schema.xml作为MyCat中重要的配置文件之一,管理着MyCat的逻辑库、表、分片规则、DataNode 以及DataHost之间的映射关系。弄懂这些配置,是正确使用MyCat的前提。

  • schema 标签用于定义MyCat实例中的逻辑库
  • Table 标签定义了MyCat中的逻辑表
  • dataNode 标签定义了MyCat中的数据节点,也就是我们通常说所的数据分片
  • dataHost 标签在MyCat逻辑库中也是作为最底层的标签存在,直接定义了具体的数据库实例、读写分离配置和心跳语句

Schema.xml 配置

<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
    <!--
    schema: 逻辑库 name:逻辑库名称
    sqlMaxLimit:一次取多少条数据 要超过用limit xxx
    table:逻辑表
    dataNode: 数据节点 对应datanode标签
    rule:分片规则,对应rule.xml
    subTables: 子表
    primaryKey:分片主键 可缓存
    -->
    <schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100">
        <!-- auto sharding by id (long) -->
        <table name="item" dataNode="dn1,dn2,dn3" rule="mod-long"
               primaryKey="ID"/>
    </schema>
    <!-- <dataNode name="dn1$0-743" dataHost="localhost1" database="db$0-743"/> -->
    <dataNode name="dn1" dataHost="localhost1" database="db1" />
    <dataNode name="dn2" dataHost="localhost1" database="db2" />
    <dataNode name="dn3" dataHost="localhost1" database="db3" />
    <!--
    dataHost: 数据主机(节点主机)
    balance:1:读写分离 0:读写不分离
    writeType:0 第一个writeHost写, 1 随机writeHost写
    dbDriver:数据库驱动 native:MySQL JDBC:Oracle、SQLServer
    switchType:是否主动读
    1 主从自动切换 -1 不切换 2 当从机延时超过slaveThreshold值时切换为主读
    -->
    <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.24.129:3306" user="root"
                   password="root" >
        </writeHost>
    </dataHost>
</mycat:schema>

配置server.xml

server.xml 介绍

server.xml几乎保存了所有MyCat需要的系统配置信息。最常用的是在此配置用户名、密码及权限。

server.xml 配置

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mycat:server SYSTEM "server.dtd">
<mycat:server xmlns:mycat="http://io.mycat/">
    <system>
        <property name="defaultSqlParser">druidparser</property>
    </system>
    <user name="mycat">
        <property name="password">mycat</property>
        <property name="schemas">TESTDB</property>
    </user>
</mycat:server>

配置rule.xml

rule.xml里面就定义了我们对表进行拆分所涉及到的规则定义。我们可以灵活的对表使用不同的分片算法,或者对表使用相同的算法但具体的参数不同。这个文件里面主要有tableRulefunction这两个标签。在具体使用过程中可以按照需求添加tableRulefunction。此配置文件可以不用修改,使用默认即可

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mycat:rule SYSTEM "rule.dtd">
<mycat:rule xmlns:mycat=”http://io.mycat/“ >
<tableRule name="sharding-by-intfile">
<rule>
    <columns>sharding_id</columns>
    <algorithm>hash-int</algorithm>
</rule>
</tableRule>
<function name="hash-int"
          class="io.mycat.route.function.PartitionByFileMap">
    <property name="mapFile">partition-hash-int.txt</property>
</function>
</mycat:rule>

tableRule 标签配置说明

  • name 属性指定唯一的名字,用于标识不同的表规则
  • rule 标签则指定对物理表中的哪一列进行拆分和使用什么路由算法
  • columns 内指定要拆分的列名字
  • algorithm 使用 function 标签中的 name 属性,连接表规则和具体路由算法。当然,多个表规则可以连接到同一个路由算法上
  • table 标签内使用,让逻辑表使用这个规则进行分片

function 标签配置说明

  • name 指定算法的名字
  • class 指定路由算法具体的类名字
  • property 为具体算法需要用到的一些属性

几个常用的分片规则

连续分片

日期列分区法

<!--按固定时间分片-->
<tableRule name="sharding-by-date">
    <rule>
        <columns>create_time</columns>
        <algorithm>sharding-by-date</algorithm>
    </rule>
</tableRule>
<function name="sharding-by-date"
          class="io.mycat.route.function..PartitionByDate">
    <property name="dateFormat">yyyy-MM-dd</property>
    <property name="sBeginDate">2014-01-01</property>
    <property name="sPartionDay">10</property>
</function>
<!--按自然月分片-->
<tableRule name="sharding-by-month">
    <rule>
        <columns>create_time</columns>
        <algorithm>sharding-by-month</algorithm>
    </rule>
</tableRule>
<function name="sharding-by-month"
          class="io.mycat.route.function..PartitionByMonth">
    <property name="dateFormat">yyyy-MM-dd</property>
    <property name="sBeginDate">2014-01-01</property>
</function>
<!--
按单月小时分片
适合做日志,每月末,手工清理
-->
<tableRule name="sharding-by-hour">
<rule>
    <columns>create_time</columns>
    <algorithm>sharding-by-hour</algorithm>
</rule>
</tableRule>
<function name="sharding-by-hour"
          class="io.mycat.route.function..LastestMonthPartition">
    <property name="splitOneDay">24</property>
</function>

配置说明

(1)tableRule标签

  • columns:标识将要分片的表字段
  • algorithm:指定分片函数

(2)function标签

  • dateFormat:日期格式
  • sBeginDate:开始日期
  • sPartionDay:分区天数,即默认从开始日期算起,分隔10天一个分区

范围约定

ID范围分区法

<tableRule name="auto-sharding-long">
    <rule>
        <columns>user_id</columns>
        <algorithm>rang-long</algorithm>
    </rule>
</tableRule>
<function name="rang-long"
          class="io.mycat.route.function.AutoPartitionByLong">
    <property name="mapFile">autopartition-long.txt</property>
</function>

配置说明

(1)tableRule标签

columns:标识将要分片的表字段
algorithm:指定分片函数

(2)function标签

mapFile:指定分片函数需要的配置文件名称
autopartition-long.txt文件内容:所有的节点配置都是从0开始,即0代表节点1,此配置非常简单,即预先制定可能的id范围对应某个分片

# range start-end, data node index
# K=1000,M=10000.
0-500M=0 0-100 0
500M-1000M=1 101-200 1
201-300 2
1000M-1500M=2
default=0
# 或以下写法
# 0-10000000=0
# 10000001-20000000=1

优势:扩容无需迁移数据
缺点:热点数据,并发受限

离散分片

枚举法

<tableRule name="sharding-by-intfile">
    <rule>
        <columns>user_id</columns>
        <algorithm>hash-int</algorithm>
    </rule>
</tableRule>
<function name="hash-int"
          class="io.mycat.route.function.PartitionByFileMap">
    <property name="mapFile">partition-hash-int.txt</property>
    <property name="type">0</property>
    <property name="defaultNode">0</property>
</function>

配置说明

(1)tableRule标签

  • columns:标识将要分片的表字段
  • algorithm:指定分片函数

(2)function标签

  • mapFile:指定分片函数需要的配置文件名称
  • type:默认值为0,0表示Integer,非零表示String
  • defaultNode:指定默认节点,小于0表示不设置默认节点,大于等于0表示设置默认节点,0代表节点1

默认节点的作用:枚举分片时,如果碰到不识别的枚举值,就让它路由到默认节点。如果不配置默认节点(defaultNode值小于0表示不配置默认节点),碰到不识别的枚举值 就会报错

partition-hash-int.txt配置:

10000=0 列等于10000 放第一个分片
10010=1
男=0
女=1
beijing=0
tianjin=1
zhanghai=2

求模法

<tableRule name="mod-long">
<rule>
    <columns>user_id</columns>
    <algorithm>mod-long</algorithm>
</rule>
</tableRule>
<function name="mod-long"
          class="io.mycat.route.function.PartitionByMod">
    <!-- how many data nodes -->
    <property name="count">3</property>
</function>

配置说明

(1)tableRule标签

  • columns:标识将要分片的表字段
  • algorithm:指定分片函数

(2)function标签

  • count:节点数量

一致性hash

<tableRule name="sharding-by-murmur">
    <rule>
        <columns>user_id</columns>
        <algorithm>murmur</algorithm>
    </rule>
</tableRule>
<function name="murmur"
          class="io.mycat.route.function.PartitionByMurmurHash">
    <!-- 默认是0 -->
    <property name="seed">0</property>
    <!-- 要分片的数据库节点数量,必须指定,否则没法分片 -->
    <property name="count">2</property>
    <!-- 一个实际的数据库节点被映射为这么多虚拟节点,默认是160倍,也就是虚拟节点数是物理节点数的160倍 -->
    <property name="virtualBucketTimes">160</property>
    <!-- 节点的权重,没有指定权重的节点默认是1 -->
    <!-- 以properties文件的格式填写,以从0开始到count-1的整数值也就是节点索引为key,以节点权重值为值 -->
    <!-- 所有权重值必须是正整数,否则以1代替 -->
    <!-- <property name="weightMapFile">weightMapFile</property> -->
    <!-- 用于测试时观察各物理节点与虚拟节点的分布情况 -->
    <!-- 如果指定了这个属性,会把虚拟节点的murmur,hash值与物理节点的映射按行输出到这个文件,没有默认值 -->
    <!-- 如果不指定,就不会输出任何东西 -->
    <!-- <property name="bucketMapPath">/etc/mycat/bucketMapPath</property> -->
</function>

测试分片

把商品表分片存储到三个数据节点上。

MyCat分片测试

创建表

配置完毕后,重新启动MyCat。使用MySQL客户端连接MyCat,创建表。

CREATE TABLE item (
id int(11) NOT NULL,
name varchar(20) DEFAULT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

分片测试

分片策略指定为auto-sharding-long,分片规则指定为mod-long

版权声明:
作者:Joe.Ye
链接:https://www.appblog.cn/index.php/2023/03/27/mycat-sharding-implementation/
来源:APP全栈技术分享
文章版权归作者所有,未经允许请勿转载。

THE END
分享
二维码
打赏
海报
MyCat分片实现
MyCat介绍 官方网站::http://www.mycat.org.cn/ MyCat核心概念 Schema:由它指定逻辑数据库(相当于MySQL的database数据库) Table:逻辑表(相当于MySQL……
<<上一篇
下一篇>>
文章目录
关闭
目 录