MySQL基础-分库分表(二)
前置文章:
MySQL基础-分库分表(一),该文主要讲了分库分表概念、MyCat安装及快速入门。
零、本文纲要
一、MyCat配置
- schema.xml
- rule.xml
- server.xml
二、MyCat分片
- 垂直拆分
- 水平拆分
一、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&serverTimezone=Asia/Shanghai&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基础-分库分表(二)的全部内容,感谢阅读。