MyCAT实现垂直切分数据库[实例精华]

为什么要做MyCAT垂直切分:

当我们实现了MyCAT读写分离,主从切换的功能已经在很大程度上优化了数据库的负载能力,但是随着业务规模和用户的增长,读写分离的配置也缓解不了数据库压力,那么就需要我们针对不通模块的表进行分库处理,通过垂直切分把读写频繁访问量大的表根据模块整合单独出数据库,这样就能极大的缓解数据库访问压力。

如果不了解MyCAT作用和原理,点击查看MyCAT安装和配置精华内容

那么有人肯定会疑问,如果对数据库进行垂直切分后,业务需要join怎么办?

适合做MyCAT垂直切分的系统,一定是模块之间低耦合的,业务模块之间相互关联少甚至没有关联,那么根据业务模块切分在一起就可以实现join,如果业务模块做不到完全分离,一样可以通过接口的方式实现跨库。

如果是数据字典这种公共类型的表,在切分后如何处理?

针对数据字典表(例如:省市区数据)很多模块都会引用到,我们可以把这类型表定义为全局表,即在每个切分的数据库都保存一份。

数据库进行切分后,ACID事务怎么保证?

MyCAT逻辑库schema对外仍然是一个数据库,对内根据业务表切分成多个数据库,每个数据库都有自己的事务,不会影响事务的ACID

何为数据切分?

简单理解,就是指通过某种特定的条件,将我们存放在同一个数据库中的数据分散存放到多个数据库(主机)上面,以达到分散单台设备负载的效果。
数据的切分(Sharding)根据其切分规则的类型,可以分为两种切分模式。一种是按照不同的表(或者Schema)来切分到不同的数据库(主机)之上,这种切可以称之为数据的垂直(纵向)切分;另外一种则是根据表中的数据的逻辑关系,将同一个表中的数据按照某种条件拆分到多台数据库(主机)上面,这种切分称之为数据的水平(横向)切分。
垂直切分的最大特点就是规则简单,实施也更为方便,尤其适合各业务之间的耦合度非常低,相互影响很小,业务逻辑非常清晰的系统。在这种系统中,可以很容易做到将不同业务模块所使用的表分拆到不同的数据库中。根据不同的表来进行拆分,对应用程序的影响也更小,拆分规则也会比较简单清晰。
水平切分于垂直切分相比,相对来说稍微复杂一些。因为要将同一个表中的不同数据拆分到不同的数据库中,对于应用程序来说,拆分规则本身就较根据表名来拆分更为复杂,后期的数据维护也会更为复杂一些。

垂直切分

一个数据库由很多表的构成,每个表对应着不同的业务,垂直切分是指按照业务将表进行分类,分布到不同的数据库上面,这样也就将数据或者说压力分担到不同的库上面,如下官方图例说明:
在这里插入图片描述
系统被切分成了,用户,订单交易,支付几个模块。
一个架构设计较好的应用系统,其总体功能肯定是由很多个功能模块所组成的,而每一个功能模块所需要的数据对应到数据库中就是一个或者多个表。而在架构设计中,各个功能模块相互之间的交互点越统一越少,系统的耦合度就越低,系统各个模块的维护性以及扩展性也就越好。这样的系统,实现数据的垂直切分也就越容易。
但是往往系统之有些表难以做到完全的独立,存在这扩库join的情况,对于这类的表,就需要去做平衡,是数据库让步业务,共用一个数据源,还是分成多个库,业务之间通过接口来做调用。在系统初期,数据量比较少,或者资源有限的情况下,会选择共用数据源,但是当数据发展到了一定的规模,负载很大的情况,就需要必须去做分割。
一般来讲业务存在着复杂join的场景是难以切分的,往往业务独立的易于切分。如何切分,切分到何种程度是考验技术架构的一个难题。
下面分析一下垂直切分的优缺点:
优点:

  • 拆分后业务清晰,拆分规则明确。
  • 系统之间整合或扩展容易。
  • 数据维护简单。

缺点:

  • 部分跨库业务表无法join,只能通过接口方式解决,提高了系统复杂度。
  • 受每种业务不同的限制存在单库性能瓶颈,不易数据扩展跟性能提高。
  • 事务处理复杂。

垂直切分配置搭建解析

schema.xml配置垂直切分

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

<!-- schema 逻辑库(可以定义水平拆分表,也可以定义垂直拆分表) name="mycat逻辑库名" -->
	<schema name="MYCATDB" checkSQLschema="false" sqlMaxLimit="100">
		<!-- 水平切分,定义切片规则rule -->
		<!-- table 逻辑表  name=逻辑表名(mycat表名) dataNode=逻辑节点(物理分片) rule=分片规则 auto-sharding-long(按照id值划分) 默认每500万为一个分片-->
		<table name="cat_test" dataNode="dn1,dn2,dn3" rule="auto-sharding-long" />
		<!-- table 逻辑表 name=逻辑表名 dataNode=逻辑节点(物理分片) rule=分片规则 sharding-by-murmur-order_id 自定义一致hash算法 针对表主键不是id -->
		<table name="cat_order" dataNode="dn1,dn2,dn3" rule="sharding-by-murmur-order_id" />
		
		<!--垂直切分 没有分片规则rule-->
		<table name="ver_01" dataNode="dn1" />
		<table name="ver_02" dataNode="dn2"/>
		<table name="ver_03" dataNode="dn3"/>
		<table name="ver_04" dataNode="dn3"/>
		<!--定义全局表 每个数据库都会保存一份,type="global-->
		<table name="item" dataNode="dn1,dn2,dn3" type="global"/>
	</schema>
	
	<!--定义主从同步数据库,mycat做读写分离,只能绑定一个dataNota-->
	<schema name="KEVINDB" checkSQLschema="false" sqlMaxLimit="100" dataNode="sync1">
	</schema>
	
	<!-- <dataNode name="dn1$0-743" dataHost="localhost1" database="db$0-743" 
		/> -->
		<!--逻辑节点配置 name节点名称  dataHost节点主机(物理节点) database 节点数据库(物理数据库名) -->
	<dataNode name="dn1" dataHost="itcast01" database="db1" />
	<dataNode name="dn2" dataHost="itcast02" database="db2" />
	<dataNode name="dn3" dataHost="itcast02" database="db3" />
	
	<!--独写分离的dataNode database为mysql配置主从同步指定的数据库 kevin-->
	<dataNode name="sync1" dataHost="sync01" database="kevin" />

	<!--
	Balance参数设置:
		1. balance=0, 所有读操作都发送到当前可用的writeHost上。
		2. balance=1”,所有读操作都随机的发送到readHost。
		3. balance=2”,所有读操作都随机的在writeHost、readhost上分发
	WriteType参数设置:
		1. writeType=0, 所有写操作都发送到可用的writeHost上。
		2. writeType=1”,所有写操作都随机的发送到readHost。
		3. writeType=2”,所有写操作都随机的在writeHost、readhost分上发。
	switchType 目前有三种选择:
		-1:表示不自动切换
		1 :默认值,自动切换
		2 :基于MySQL主从同步的状态决定是否切换
		“Mycat心跳检查语句配置为 show slave status ,dataHost 上定义两个新属性: switchType="2" 与slaveThreshold="100",此时意味着开启MySQL主从复制状态绑定的读写分离与切换机制。Mycat心跳机制通过检测 show slave status 中的 "Seconds_Behind_Master", "Slave_IO_Running", "Slave_SQL_Running" 三个字段来确定当前主从同步的状态以及Seconds_Behind_Master主从复制时延。“
-->
<!--配置独写分离的 数据库配置 -->
	<dataHost name="sync01" maxCon="1000" minCon="10" balance="1"
		writeType="0" dbType="mysql" dbDriver="native" switchType="2"  slaveThreshold="100">
		<heartbeat>show slave status</heartbeat>
		<!-- can have multi write hosts -->
		<!-- itcast-01 -->
		<writeHost host="hostM1" url="192.168.79.130:3306" user="root"
			password="root123">
			<!-- can have multi read hosts -->
			<readHost  host="hostS1" url="192.168.79.131:3306" user="root" password="root123"/>
		</writeHost>
	</dataHost> 
	
	<dataHost name="itcast01" maxCon="1000" minCon="10" balance="0"
		writeType="0" dbType="mysql" dbDriver="native" switchType="1"  slaveThreshold="100">
		<heartbeat>select user()</heartbeat>
		<!-- can have multi write hosts -->
		<!-- itcast-01 -->
		<writeHost host="hostM1" url="localhost:3306" user="root"
			password="root123">
			<!-- can have multi read hosts -->
		</writeHost>
	</dataHost> 
	<dataHost name="itcast02" maxCon="1000" minCon="10" balance="0"
		writeType="0" dbType="mysql" dbDriver="native" switchType="1"  slaveThreshold="100">
		<heartbeat>select user()</heartbeat>
		<!-- can have multi write hosts -->
		<!-- itcast-01 -->
		<writeHost host="hostM1" url="192.168.79.131:3306" user="root"
			password="root123">
			<!-- can have multi read hosts -->
		</writeHost>
	</dataHost>
</mycat:schema>

定义名称为MYCATDB的逻辑库schema中定义了多个逻辑表,分别为水平切分的逻辑表"cat_test"和"cat_test",垂直切分的逻辑表"ver_01",“ver_02”,“ver_03”,“ver_04”,全局表"item",分别定义逻辑节点dataNode,不同的dataNode关联了物理数据库名和主机地址。
具体的MyCAT分片规则和分片逻辑,将会更新博客MyCAT分片篇

server.xml用户及权限配置

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mycat:server SYSTEM "server.dtd">
<mycat:server xmlns:mycat="http://org.opencloudb/">
	<system>
	<property name="defaultSqlParser">druidparser</property>
	<property name="charset">utf8</property>
  
	</system>
	<!-- 配置用户 -->
	<user name="root">
		<property name="password">root123</property>
		<property name="schemas">MYCATDB,KEVINDB</property> <!-- 用户对应的逻辑库名,配置的其它schemas是无法访问的-->
	</user>

	<user name="test">
		<property name="password">test</property>
		<property name="schemas">MYCATDB,KEVINDB</property>
		<property name="readOnly">true</property><!--只读 -->
	</user>
	<!-- <cluster> <node name="cobar1"> <property name="host">127.0.0.1</property> 
		<property name="weight">1</property> </node> </cluster> -->
	<!-- <quarantine> <host name="1.2.3.4"> <property name="user">test</property> 
		</host> </quarantine> -->

</mycat:server>

server.xml用于配置mycat的服务参数,如mycat的服务端口号8066,mycat的管理端口号9066,连接mycat的用户名user.name、密码user.pasword、要连接的数据库权限user.schemas(多个数据库用逗号分隔,如db1,db2), user用户节点可以配置多个
注: 一定要注意区分server.xml中配置的mycat用户信息和权限标签,如果用户要对应多个schema,需要通过逗号分隔配置,未配置的无法访问

数据库实例

itcast-01主机

根据我们在schema.xml中配置,逻辑节点dataNota名称为dn1关联了物理主机itcast-01和数据库名称db1,名称为MYCATDB的逻辑库schema,可以知道db1中应该存在表"cat_test",“cat_order”,"ver_01"四张表
db1 show databases;

mysql> use db1;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| db1                |
| kevin              |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
6 rows in set (0.00 sec)

mysql> show tables;
+---------------+
| Tables_in_db1 |
+---------------+
| CAT_ORDER     |
| CAT_TEST      |
| ITEM          |
| VER_01        |
+---------------+
4 rows in set (0.01 sec)

itcast-02主机

根据我们在schema.xml中配置,逻辑节点dataNota名称为dn1和dn2关联了物理主机itcast-02和数据库名称db2,db3,名称为MYCATDB的逻辑库schema,可以知道db2中应该存在表"cat_test",“cat_order”,“ver_02"四张表,在db3中应该存在表"cat_test”,“cat_order”,“ver_03”,"ver_04"四张表
db2 show databases;

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| db2                |
| db3                |
| kevin              |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
7 rows in set (0.00 sec)

mysql> use db2;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> show tables;
+---------------+
| Tables_in_db2 |
+---------------+
| CAT_ORDER     |
| CAT_TEST      |
| ITEM          |
| VER_02        |
+---------------+
4 rows in set (0.00 sec)

db3 show tables;

mysql> use db3;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> show tables;
+---------------+
| Tables_in_db3 |
+---------------+
| CAT_ORDER     |
| CAT_TEST      |
| ITEM          |
| VER_03        |
| VER_04        |
+---------------+
5 rows in set (0.00 sec)

由此可见水平切分表"cat_test"和"cat_order",垂直切分表"ver_01",“ver_02”,“ver_03”,“ver_04”,全局表"item"都在数据库节点中实现了。
博客码字不易,喜欢学习交流的朋友,可以留言相互关注~
MyCAT水平切分的细节请期待下篇博客更新。

猜你喜欢

转载自blog.csdn.net/qq_41714882/article/details/104609237