MyCat 数据库中间件


一、MyCat 介绍


  • MyCat 三大功能:
  1. 分库分表
  2. 读写分离
  3. 主从切换

二、MyCat 分片概念

  • 分片(Sharding):
    简单来说,就是指通过某种特定的条件,将我们存放在同一个数据库中的数据,分散存放到多个数据库(主机)上面,以达到分散单台设备负载的效果。

1. 垂直切分

  • 数据的 垂直(纵向)切分
    按照不同的表(或 Schema)来切分到不同的数据库(主机)之上。
    在这里插入图片描述

2. 水平切分

  • 数据的 水平(横向)切分
    根据表中数据的逻辑关系,将同一个表中的数据,按照某种条件拆分到多台数据库(主机)上面。
    在这里插入图片描述

三、MyCat 分片逻辑

  • 分片逻辑
    在这里插入图片描述

1. schema 逻辑库

  • 数据库中间件,可以被看做是一个或多个数据库集群构成的逻辑库。

2. table 逻辑表

  • 分布式数据库中,对应用来说,读写数据的表 就是逻辑表。
  1. 逻辑表 可以是数据切分后,分布在一个或多个分片库中。
  2. 也可以不做数据切分,不分片只有一个表构成。

  • 分片表
  1. 指原有很大的数据表,需要切分到多个数据库的表,这样每个分片都有一部分数据。
  2. 所有分片构成了完整的数据。
  • 总而言之就是需要进行分片的表。

  • 非分片表
  1. 一个数据库中并不是所有的表都很大,某些表是可以不用进行切分的。
  2. 非分片 是相对 分片表 来说的,就是那些 不需要进行数据切分 的表。

3. dataNode 分片节点

  • 数据切分后,一个大表被分到不同的分片数据库上面。
  • 每个表分片 所在的 数据库 就是 分片节点。

4. dataHost 节点主机

  • 数据切分后,每个 分片节点(dataNode)不一定都会独占一台机器。
  • 同一机器上面可以有多个分片数据库。
  1. 一个或多个 分片节点 所在的机器,就是 节点主机。
  2. 为了规避 单节点主机 并发数限制,尽量将 读写压力高的 分片节点,均衡的放在不同的 节点主机。

5. rule 分片规则

  • 一个大表 被分成 若干个分片表,就需要一定的 规则。
  1. 按照某种业务规则,把数据分到 某个分片 的规则,就是 分片规则。
  2. 数据切分 选择合适的 分片规则 非常重要,将极大的避免后续数据处理的难度。

四、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 启动停止
  • MyCat 默认端口号:8066

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 配置用户信息

  • MyCat 系统配置信息
  1. 用户名
  2. 密码及权限

<!-- 添加`utf8`字符集,存储中文会出现乱码 -->
<system>
	<property name="charset">utf8</property>
</system>

<!-- name 用户名 -->
<user name="user">
	<!-- password 密码、schemas 逻辑库名、readOnly 是否只读 -->
	<property name="password">123456</property>
	<property name="schemas">TESTDB</property>
	<property name="readOnly">true</property>
	<property name="defaultSchema">TESTDB</property>
</user>

<!-- defaultAccount 默认账号 -->
<user name="root" defaultAccount="true">
	<!-- 密码加密 -->
	<property name="password">laEi5zuHBQHF2NObGsICE3TTUKKU6r8W6PQSlvZ5ZUKGZEcfA==</property>
	<property name="schemas">chnmedicine</property>
	<property name="defaultSchema">chnmedicine</property>
	<!-- usingDecrypt 1使用解密 -->
	<property name="usingDecrypt">1</property> 
</user>

3. rule.xml 配置分片规则

  • 定义了 对表进行拆分,所涉及到的规则。
  1. 可以灵活的对表 使用不同的 分片算法.
  2. 对表 使用相同的算法,但具体的参数不同。

3.1 auto-sharding-long 按 id 范围分片
<!-- tableRule 定义某个表或某一类表的分片规则名称 -->
<tableRule name="auto-sharding-long">
	<rule>
		<!-- columns 定义分片的列 -->
		<columns>id</columns>
		<!-- algorithm 算法名称 -->
		<algorithm>rang-long</algorithm>
	</rule>
</tableRule>	

<!-- function 定义算法 -->
<function name="rang-long" class="io.mycat.route.function.AutoPartitionByLong">
	<!-- mapFile 定义算法需要的数据 -->
	<property name="mapFile">autopartition-long.txt</property>
</function>		
  • 按 id 范围分片
  1. 1-500万在 0 号分片
  2. 500万零1-1000万在 1 号分片
  3. 1000万零1-1500万在 2号分片
  • autopartition-long.txt
# range start-end ,data node index
# K=1000,M=10000.
0-500M=0
500M-1000M=1
1000M-1500M=2

3.2 sharding-by-murmur 一致性哈希
  • 一致性哈希 murmur
  1. 需要将数据平均分在几个分区中,使用 一致性 hash 规则

<tableRule name="sharding-by-murmur">
	<rule>
		<!-- columns 定义分片的列 -->
		<columns>id</columns>
		<!-- algorithm 算法名称 -->
		<algorithm>murmur</algorithm>
	</rule>
</tableRule>

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

4. schema.xml 配置逻辑关系

  1. 逻辑库
  2. 逻辑表,及对应的 分片规则
  3. DataNode
  4. DataSource

<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">

	<!-- schema 逻辑库、name 逻辑库名 -->
	<schema name="TESTDB" checkSQLschema="true" sqlMaxLimit="100" randomDataNode="dn1">

		<!-- table 逻辑表、name 逻辑表名、
			1. dataNode 数据节点,对应`<dataNode>`标签。
			2. rule 分片规则,对应`rule.xml`文件。
				2.1 auto-sharding-long 按id范围分片
				2.2 sharding-by-murmur 一致性哈希 -->
		<table name="travelrecord,address" dataNode="dn1,dn2,dn3" rule="auto-sharding-long" splitTableNames ="true"/>
	</schema>

	<!-- dataNode 数据节点|数据分片、name 数据节点名、
		1. dataHost 节点主机,对应`<dataHost>`标签。 
		2. database 物理库名。 -->
	<dataNode name="dn1" dataHost="cluster" database="db1" />
	<dataNode name="dn2" dataHost="cluster" database="db2" />
	<dataNode name="dn3" dataHost="cluster" database="db3" />

	<!-- dataHost 节点主机、
		1. 具体的数据库实例。
		2. 读写分离配置和心跳语句 -->
	<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>
		
		<!-- 从节点(主要依靠 MySQL 主从机制)-->
		<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. 数据库 读写分离

  1. 对于 MySQL 来说,标准的 读写分离 是 主从模式。一个 写节点(Master),后面跟着多个 读节点。
  2. 读节点的数量 取决于系统的压力,通常是 1~3 个读节点的配置。
    在这里插入图片描述

  • MyCat 读写分离 和 自动切换 机制,需要 MySQL 主从复制机制 配合。
    在这里插入图片描述

六、MyCat 读写分离配置

1. schema.xml 配置逻辑关系

<!-- dataHost 节点主机
	1. 具体的数据库实例
	2. 读写分离配置和心跳语句 -->
<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=“1”
  1. balance="0":所有读操作都发送到当前可用的 writeHost 上。
  2. balance="1":所有读操作都随机的发送到 readHost 上。
  3. balance="2":所有读操作都随机的在 writeHost、readhost 上分发。
  • 设置 writeType=“0”
  1. writeType="0":所有写操作都发送到可用的 writeHost 上。
  2. writeType="1":所有写操作都随机的发送到 readHost 上。
  3. writeType="2":所有写操作都随机的在 writeHost、readhost 分上发。

  • readHost 是从属于 writeHost 的,即意味着它从那个 writeHost 获取同步数据。
  1. 当它所属的 writeHost 宕机了,则它也不会再参与到读写分离中来,即 “不工作了”。
  2. 这是因为此时,它的数据已经 “不可靠了”。
  3. 基于这个考虑,目前 MyCat 1.3 和 1.4 版本中,若想支持 MySQL 一主一从的标准配置,并且在主节点宕机的情况下,从节点还能读取数据。
    则需要在 MyCat 里配置为两个 writeHost 并设置 banlance=“1”。

  • 设置 switchType=“2”
  1. switchType="-1":表示不自动切换。
  2. switchType="1":自动切换【默认值】。
  3. switchType="2":基于 MySQL 主从同步的状态 决定是否切换。
  • 设置 slaveThreshold=“100”

  • dataHost 上定义两个新属性 switchType=“2” 与 slaveThreshold=“100”
  1. 此时意味着开启了 MySQL 主从复制,状态绑定的 读写分离 与 切换机制。
  • MyCat 心跳检查语句配置为:show slave status
  1. MyCat 心跳机制通过检查 show slave status 中的 “Seconds_Behind_Master”、“Slave_IO_Running”、“Slave_SQL_Running” 三个字段来确定当前主从同步的状态。
  2. 以及 Seconds_Behind_Master 主从复制时延。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

骑士梦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值