MySQL基础-分库分表(二)

2022-05-26  本文已影响0人  石头耳东

前置文章:
MySQL基础-分库分表(一),该文主要讲了分库分表概念、MyCat安装及快速入门。

零、本文纲要

一、MyCat配置

  1. schema.xml
  2. rule.xml
  3. server.xml

二、MyCat分片

  1. 垂直拆分
  2. 水平拆分

一、MyCat配置

1. schema.xml

作为MyCat中最重要的配置文件之一,涵盖了MyCat的逻辑库、逻辑表、分片规则、分片节点及数据源的配置。

1.1 schema标签

<!-- 
    schema:逻辑库,一个逻辑库下可以有多个逻辑表
    name:此处指定库名为DB01
    checkSQLschema:在SQL语句操作时指定了数据库名称,执行时是否自动去除
    sqlMaxLimit:如果SQL中没有使用limit,默认查询100条
-->
<schema name="DB01" checkSQLschema="true" sqlMaxLimit="100">
    ...
</schema>

注意:
checkSQLschema="true"时,无需 use DB01; 就可以执行对应的SQL,如:select * from DB01.TB_ORDER;,而且系统会自动去除 DB01.
checkSQLschema="false"时,需要先 use DB01; ,再执行具体的SQL,否则报错。

注意:我们只有分表操作才指定这个rule,如果只是分库无需配置。

<!-- 
    table:逻辑表
    name:此处指定表名为TB_ORDER
    dataNode:定义逻辑表所属的dataNode,该属性需要与dataNode标签中name对应;多个dataNode逗号分隔
    rule:分片规则,具体规则在 /mycat/conf/rule.xml 文件中
    primaryKey:逻辑表对应真实表的主键
    type:逻辑表的类型,目前逻辑表只有全局表和普通表,如果未配置,就是普通表;全局表,配置为 global
-->
<table name="TB_ORDER" dataNode="dn1,dn2,dn3" rule="auto-sharding-long" />

1.2 datanode标签

<!-- 
    dataNode:分片节点 
    name:定义数据节点名称
    dataHost:数据库实例主机名称,引用自 dataHost 标签中name属性
    database:指定要关联的这个节点主机的具体数据库,此处指定为db01
-->
<dataNode name="dn1" dataHost="dhost1" database="db01" />

1.3 datahost标签

<!-- 
    dataHost:节点主机 
    name:唯一标识,供上层标签使用
    maxCon/minCon:最大连接数/最小连接数
    balance:负载均衡策略,取值 0,1,2,3
    writeType:写操作分发方式(0:写操作转发到第一个writeHost,第一个挂了,切换到第二个;1:写操作随机分发到配置的writeHost)
    dbDriver:native默认配置不支持高版本的mysql,此处改为jdbc
-->
<dataHost name="dhost1" maxCon="1000" minCon="10" balance="0"
          writeType="0" dbType="mysql" dbDriver="jdbc" switchType="1"  slaveThreshold="100">
    <heartbeat>select user()</heartbeat>

    <writeHost host="master" url="jdbc:mysql://192.168.200.128:3316?useSSL=false&amp;serverTimezone=Asia/Shanghai&amp;characterEncoding=utf8" user="root" password="123456" />
</dataHost>

2. rule.xml

2.1 tableRule标签

指定具体规则,及引用函数

<tableRule name="auto-sharding-long">
    <rule>
        <columns>id</columns>
        <algorithm>rang-long</algorithm>
    </rule>
</tableRule>

2.2 function标签

指定该函数的Java类,及对应属性配置

<function name="rang-long"
    class="io.mycat.route.function.AutoPartitionByLong">
    <property name="mapFile">autopartition-long.txt</property>
</function>

3. server.xml

3.1 system标签

官方配置文件说明较详尽,此处略。

3.2 user标签

<!-- 配置用户权限 -->
<user name="root" defaultAccount="true">
    <property name="password">123456</property>
    <property name="schemas">DB01</property>
    
    <!-- 表级 DML 权限设置 -->
    <!-- check:是否开启DML权限检查,默认false -->  
    <privileges check="false">
        <!-- 
            schema:逻辑库
            name:配置指定逻辑库的权限 
            dml:配置指定逻辑库的权限
            0110:对应IUSD(增,改,查,删)的权限
        -->
        <schema name="DB01" dml="0110" >
            <!-- 
                table:逻辑表
                name:配置指定逻辑表的权限 
                dml:配置指定逻辑表的权限
                0110:对应IUSD(增,改,查,删)的权限
            -->
            <table name="tb01" dml="0000"></table>
            <table name="tb02" dml="1111"></table>
        </schema>
    </privileges>       
    
</user>

<user name="user">
    <property name="password">123456</property>
    <property name="schemas">DB01</property>
    <property name="readOnly">true</property>
</user>

二、MyCat分片

1. 垂直拆分

问题:

垂直分片执行多表查询时,如果多表来自不同分片,MyCat不能判断如何路由,此时会报错。

解决:

将各个业务模块可能都要用到的表,设置为全局表golbal, type="global"
同时需要将其所属的多个分片节点配置好,dataNode="dn1,dn2,dn3"

<table name="tb_areas_provinces" dataNode="dn1,dn2,dn3" primaryKey="id" type="global"/>

2. 水平拆分

注意:需要配置rule分片规则。

mod-long分片规则:该规则会按照我们property的count值取模,然后按余值将数据插入到对应分片。

<tableRule name="mod-long">
    <rule>
        <columns>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>

2.1 常用分片规则

注意:只能跟据数值类型进行分片,字符串类型则失效。

注意:只能跟据数值类型进行分片,字符串类型则失效。

注意:跟据字段哈希值进行分片。

一致性哈希:相同的哈希因子计算值总是被划分到相同的分区表中,不会因为分区节点的增加而改变原来数据的分区位置,有效的解决了分布式数据的拓容问题。

<tableRule name="sharding-by-murmur">
    <rule>
        <columns>id</columns>
        <algorithm>murmur</algorithm>
    </rule>
</tableRule>


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

<function name="hash-int" class="io.mycat.route.function.PartitionByFileMap">
    <!-- defaultNode:表示值超过默认枚举值将会放在节点2,第3个dataNode -->
    <property name="defaultNode">2</property>
    <property name="mapFile">partition-hash-int.txt</property>
</function>

partition-hash-int.txt文件内容如下:

1=0
2=1
3=2

表示枚举值1,落在节点0,以此类推;

截取指定字段的指定长度作为分片子串,进而分配数据。

注意:只能跟据数值类型字符【子串】进行分片,字符串类型则失效。

<tableRule name="sharding-by-substring">
    <rule>
        <columns>id</columns>
        <algorithm>sharding-by-substring</algorithm>
    </rule>
</tableRule>

<function name="sharding-by-substring" class="io.mycat.route.function.PartitionDirectBySubString">
    <property name="startIndex">0</property> <!-- 开始索引 -->
    <property name="size">2</property> <!-- 截取长度 -->
    <property name="partitionCount">3</property> <!-- 分片数量 -->
    <property name="defaultPartition">0</property> <!-- 默认分片 -->
</function>

取 id 的二进制低 10 位 与 1111111111 进行位 & 运算,位与运算最小值为 0000000000,最大值为1111111111,转换为十进制,也就是位于0-1023之间。

<tableRule name="sharding-by-long-hash">
    <rule>
        <columns>id</columns>
        <algorithm>sharding-by-long-hash</algorithm>
    </rule>
</tableRule>

<!-- 分片总长度为1024,count与length数组长度必须一致; -->
<function name="sharding-by-long-hash" class="io.mycat.route.function.PartitionByLong">
    <property name="partitionCount">2,1</property> <!-- 前有2个分片,后有1个分片 -->
    <property name="partitionLength">256,512</property> <!-- 前2个分片大小256,后一个分片大小512;分为三个分区:0-255,256-511,512-1023 -->
</function>

截取字符串中的指定位置的子字符串, 进行hash算法, 算出分片。

<tableRule name="sharding-by-stringhash">
    <rule>
        <columns>name</columns>
        <algorithm>sharding-by-stringhash</algorithm>
    </rule>
</tableRule>

<function name="sharding-by-stringhash" class="io.mycat.route.function.PartitionByString">
    <property name="partitionLength">512</property> <!-- zero-based -->
    <property name="partitionCount">2</property>
    <property name="hashSlice">0:2</property>
    <!-- 
        hashSlice:Hash运算位,格式 start_index : end_index
        0 在 end_index 代表str.length()
        -1 在 end_index 代表str.length() - 1
        大于0 代表数字本身
        此处 0:2 代表索引0到索引2
    -->
</function>
<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">2022-01-01</property>
    <property name="sEndDate">2022-01-30</property>
    <property name="sPartionDay">10</property>
</function>
<!--
    从开始时间开始,每10天为一个分片,到达结束时间之后,会重复开始分片插入
    配置表的 dataNode 的分片,必须和分片规则数量一致,例如 2022-01-01 到 2022-12-31 ,每
    10天一个分片,一共需要37个分片。
-->
<tableRule name="sharding-by-month">
    <rule>
        <columns>create_time</columns>
        <algorithm>partbymonth</algorithm>
    </rule>
</tableRule>

<function name="partbymonth" class="io.mycat.route.function.PartitionByMonth">
    <property name="dateFormat">yyyy-MM-dd</property>
    <property name="sBeginDate">2022-01-01</property>
    <property name="sEndDate">2022-03-31</property>
</function>
<!--
    从开始时间开始,一个月为一个分片,到达结束时间之后,会重复开始分片插入
    配置表的 dataNode 的分片,必须和分片规则数量一致,例如 2022-01-01 到 2022-12-31 ,一
    共需要12个分片。
-->

三、结尾

以上即为MySQL基础-分库分表(二)的全部内容,感谢阅读。

上一篇下一篇

猜你喜欢

热点阅读