一、MyCat 介绍
- 分库分表
- 读写分离
- 主从切换
二、MyCat 分片概念
- 分片(Sharding):
简单来说,就是指通过某种特定的条件,将我们存放在同一个数据库中的数据,分散存放到多个数据库(主机)上面,以达到分散单台设备负载的效果。
1. 垂直切分
- 数据的 垂直(纵向)切分:
按照不同的表(或 Schema)来切分到不同的数据库(主机)之上。
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/63f39f92045de44cf597ec27e5eb013b.png)
2. 水平切分
- 数据的 水平(横向)切分:
根据表中数据的逻辑关系,将同一个表中的数据,按照某种条件拆分到多台数据库(主机)上面。
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/61bf280ebf0ee050948fd367095cdd9b.png)
三、MyCat 分片逻辑
- 分片逻辑
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/b2214b679f1f4f967bae02ecf74995a6.png)
1. schema
逻辑库
- 数据库中间件,可以被看做是一个或多个数据库集群构成的逻辑库。
2. table
逻辑表
- 分布式数据库中,对应用来说,读写数据的表 就是逻辑表。
- 逻辑表 可以是数据切分后,分布在一个或多个分片库中。
- 也可以不做数据切分,不分片只有一个表构成。
- 指原有很大的数据表,需要切分到多个数据库的表,这样每个分片都有一部分数据。
- 所有分片构成了完整的数据。
- 一个数据库中并不是所有的表都很大,某些表是可以不用进行切分的。
- 非分片 是相对 分片表 来说的,就是那些 不需要进行数据切分 的表。
3. dataNode
分片节点
- 数据切分后,一个大表被分到不同的分片数据库上面。
- 每个表分片 所在的 数据库 就是 分片节点。
4. dataHost
节点主机
- 数据切分后,每个 分片节点(dataNode)不一定都会独占一台机器。
- 同一机器上面可以有多个分片数据库。
- 一个或多个 分片节点 所在的机器,就是 节点主机。
- 为了规避 单节点主机 并发数限制,尽量将 读写压力高的 分片节点,均衡的放在不同的 节点主机。
5. rule
分片规则
- 一个大表 被分成 若干个分片表,就需要一定的 规则。
- 按照某种业务规则,把数据分到 某个分片 的规则,就是 分片规则。
- 数据切分 选择合适的 分片规则 非常重要,将极大的避免后续数据处理的难度。
四、MyCat 分片配置
1. MyCat 安装启动
1.1 下载安装
wget http://dl.mycat.io/1.6.7.4/Mycat-server-1.6.7.4-release/Mycat-server-1.6.7.4-release-20200105164103-linux.tar.gz
tar -zxvf Mycat-server-1.6.7.4-release-20200105164103-linux.tar.gz -C /usr/app/
1.2 启动停止
cd mycat/bin
./mycat status
./mycat console
./mycat start
./mycat stop
./mycat restart
./mycat dump
mysql -uroot -P8066 -h192.168.1.137 -p
1.3 加密明文密码
java -cp Mycat-server-1.6.7.4-release.jar io.mycat.util.DecryptUtil 0:root:123456
2. server.xml
配置用户信息
- 用户名
- 密码及权限
<system>
<property name="charset">utf8</property>
</system>
<user name="user">
<property name="password">123456</property>
<property name="schemas">TESTDB</property>
<property name="readOnly">true</property>
<property name="defaultSchema">TESTDB</property>
</user>
<user name="root" defaultAccount="true">
<property name="password">laEi5zuHBQHF2NObGsICE3TTUKKU6r8W6PQSlvZ5ZUKGZEcfA==</property>
<property name="schemas">chnmedicine</property>
<property name="defaultSchema">chnmedicine</property>
<property name="usingDecrypt">1</property>
</user>
3. rule.xml
配置分片规则
- 可以灵活的对表 使用不同的 分片算法.
- 对表 使用相同的算法,但具体的参数不同。
3.1 auto-sharding-long
按 id 范围分片
<tableRule name="auto-sharding-long">
<rule>
<columns>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-500万在 0 号分片
- 500万零1-1000万在 1 号分片
- 1000万零1-1500万在 2号分片
0-500M=0
500M-1000M=1
1000M-1500M=2
3.2 sharding-by-murmur
一致性哈希
- 需要将数据平均分在几个分区中,使用 一致性 hash 规则
<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>
<property name="count">2</property>
<property name="virtualBucketTimes">160</property>
</function>
3.3 mod-long
<tableRule name="mod-id">
<rule>
<columns>id</columns>
<algorithm>mod-long</algorithm>
</rule>
</tableRule>
<function name="mod-long" class="io.mycat.route.function.PartitionByMod">
<property name="count">4</property>
</function>
4. schema.xml
配置逻辑关系
- 逻辑库
- 逻辑表,及对应的 分片规则
- DataNode
- DataSource
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
<schema name="TESTDB" checkSQLschema="true" sqlMaxLimit="100" randomDataNode="dn1">
<table name="travelrecord,address" dataNode="dn1,dn2,dn3" rule="auto-sharding-long" splitTableNames ="true"/>
</schema>
<dataNode name="dn1" dataHost="cluster" database="db1" />
<dataNode name="dn2" dataHost="cluster" database="db2" />
<dataNode name="dn3" dataHost="cluster" database="db3" />
<dataHost name="cluster" maxCon="1000" minCon="10"
balance="0" writeType="0"
dbType="mysql" dbDriver="native"
switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<writeHost host="hostM1" url="localhost:3306" user="root" password="123456"></writeHost>
<writeHost host="hostS1" url="localhost:3307" user="root" password="123456"></writeHost>
</dataHost>
</mycat:schema>
- 问题:需要为 MySQL 设置 大小写不敏感,否则可能会发生表找不到的问题。
- 解决:需在 MySQL
/etc/my.cnf [mysqld]
配置文件,增加如下配置。
lower_case_table_names=1
- 注意:在 INSERT语句 插入时,一定要把每个字段名都写出来。
五、MyCat 读写分离原理
1. 数据库 读写分离
- 对于 MySQL 来说,标准的 读写分离 是 主从模式。一个 写节点(Master),后面跟着多个 读节点。
- 读节点的数量 取决于系统的压力,通常是 1~3 个读节点的配置。
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/ad60c50ad4247062def17ca1d85a1088.png)
- MyCat 读写分离 和 自动切换 机制,需要 MySQL 主从复制机制 配合。
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/2a8a18b09d19672c9ef2cde70e032249.png)
六、MyCat 读写分离配置
1. schema.xml 配置逻辑关系
<dataHost name="localhost2" maxCon="1000" minCon="10" balance="1" writeType="0"
dbType="mysql" dbDriver="native" switchType="2" slaveThreshold="100">
<heartbeat>show slave status</heartbeat>
<writeHost host="hostM" url="192.168.1.137:3306" user="root" password="root">
<readHost host="hostS" url="192.168.1.137:3307" user="root" password="root" />
</writeHost>
</dataHost>
balance="0"
:所有读操作都发送到当前可用的 writeHost 上。balance="1"
:所有读操作都随机的发送到 readHost 上。balance="2"
:所有读操作都随机的在 writeHost、readhost 上分发。
writeType="0"
:所有写操作都发送到可用的 writeHost 上。writeType="1"
:所有写操作都随机的发送到 readHost 上。writeType="2"
:所有写操作都随机的在 writeHost、readhost 分上发。
- readHost 是从属于 writeHost 的,即意味着它从那个 writeHost 获取同步数据。
- 当它所属的 writeHost 宕机了,则它也不会再参与到读写分离中来,即 “不工作了”。
- 这是因为此时,它的数据已经 “不可靠了”。
- 基于这个考虑,目前 MyCat 1.3 和 1.4 版本中,若想支持 MySQL 一主一从的标准配置,并且在主节点宕机的情况下,从节点还能读取数据。
则需要在 MyCat 里配置为两个 writeHost 并设置 banlance=“1”。
switchType="-1"
:表示不自动切换。switchType="1"
:自动切换【默认值】。switchType="2"
:基于 MySQL 主从同步的状态 决定是否切换。
- dataHost 上定义两个新属性 switchType=“2” 与 slaveThreshold=“100”
- 此时意味着开启了 MySQL 主从复制,状态绑定的 读写分离 与 切换机制。
- MyCat 心跳检查语句配置为:show slave status
- MyCat 心跳机制通过检查 show slave status 中的 “Seconds_Behind_Master”、“Slave_IO_Running”、“Slave_SQL_Running” 三个字段来确定当前主从同步的状态。
- 以及 Seconds_Behind_Master 主从复制时延。