美文网首页
MySQL基础-分库分表(二)

MySQL基础-分库分表(二)

作者: 石头耳东 | 来源:发表于2022-05-26 14:48 被阅读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 定义逻辑库
    <!-- 
        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,否则报错。

    • ② schema 中的table定义逻辑表

    注意:我们只有分表操作才指定这个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 常用分片规则

    • ① auto-sharding-long 范围分片

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

    • ② mod-long 取模分片

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

    • ③ sharding-by-murmur 一致性哈希分片

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

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

    <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>
    
    • ④ sharding-by-intfile 枚举分片(自定义)
    <!-- 自己增加 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,以此类推;

    • ⑤ sharding-by-substring 应用指定算法分片(自定义)

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

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

    <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>
    
    • ⑥ sharding-by-long-hash 固定分片哈希算法(自定义)

    取 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>
    
    • ⑦ sharding-by-stringhash 字符串哈希解析算法(自定义)

    截取字符串中的指定位置的子字符串, 进行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>
    
    • ⑧ sharding-by-date 按天分片算法(自定义)
    <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个分片。
    -->
    
    • ⑨ sharding-by-month 自然月分片
    <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基础-分库分表(二)的全部内容,感谢阅读。

    相关文章

      网友评论

          本文标题:MySQL基础-分库分表(二)

          本文链接:https://www.haomeiwen.com/subject/cksuprtx.html