Mycat(一)——基本概念和使用


文章目录

    • 垂直拆分
      • 优点
      • 缺点
    • 水平拆分
      • 优点
      • 缺点
    • 常见的分片规则
    • Mycat
      • 逻辑库(schema)
      • 逻辑表(table)
      • 分片表
      • ER表
      • 全局表
      • 分片节点(dataNode)
      • 节点主机(dataHost)
      • 分片规则(rule)
      • 全局序列号(sequence)
    • 下载
    • 分表

在介绍mycat前,先看一下数据库拆分的几种常见的方式:
数据库拆分
就是指通过某种特定的条件,将我们存放在同一个数据库中的数据分散存放到多个数据库(主机)上面,以达到分散单台设备负载的效果
垂直拆分 Mycat(一)——基本概念和使用
文章图片

优点
◆ 数据库的拆分简单明了,拆分规则明确;
◆ 应用程序模块清晰明确,整合容易;
◆ 数据维护方便易行,容易定位;
缺点
◆ 部分表关联无法在数据库级别完成,需要在程序中完成,存在跨库join的问题,对于这类的表,就需要去做平衡,是数据库让步业务,共用一个数据源,还是分成多个库,业务之间通过接口来做调用;在系统初期,数据量比较少,或者资源有限的情况下,会选择共用数据源,但是当数据发展到了一定的规模,负载很大的情况,就需要必须去做分割。
◆ 对于访问极其频繁且数据量超大的表仍然存在性能瓶颈,不一定能满足要求;
◆ 事务处理相对更为复杂;
◆ 切分达到一定程度之后,扩展性会遇到限制;
◆ 过多切分可能会带来系统过渡复杂而难以维护。
水平拆分 相对于垂直拆分,水平拆分不是将表做分类,而是按照某个字段的某种规则来分散到多个库之中,每个表中包含一部分数据。
可以将数据的水平切分理解为是按照数据行的切分,就是将表中的某些行切分到一个数据库,而另外的某些行又切分到其他的数据库中
Mycat(一)——基本概念和使用
文章图片

优点
  • 表关联基本能够在数据库端全部完成;
  • 不会存在某些超大型数据量和高负载的表遇到瓶颈的问题;
  • 应用程序端整体架构改动相对较少;
  • 事务处理相对简单;
  • 只要切分规则能够定义好,基本上较难遇到扩展性限制;
缺点
切分规则相对更为复杂,很难抽象出一个能够满足整个数据库的切分规则;
后期数据的维护难度有所增加,人为手工定位数据更困难;
应用系统各模块耦合度较高,可能会对后面数据的迁移拆分造成一定的困难。
节点合并排序分页问题;
多数据源管理问题。
常见的分片规则
  1. 按照用户ID求模,将数据分散到不同的数据库,具有相同数据用户的数据都被分散到一个库中。
  2. 按照日期,将不同月甚至日的数据分散到不同的库中。
  3. 按照某个特定的字段求摸,或者根据特定范围段分散到不同的库中。
几个原则
  • 能不切分尽量不要切分。
  • 如果要切分一定要选择合适的切分规则,提前规划好。
  • 数据切分尽量通过数据冗余或表分组(Table Group)来降低跨库Join的可能。
  • 由于数据库中间件对数据Join实现的优劣难以把握,而且实现高性能难度极大,业务读取尽量少使用多表Join。
数据切分带来的问题
  • 引入分布式事务的问题;
  • 跨节点 Join 的问题;
  • 跨节点合并排序分页问题;
Mycat 是一个数据库代理
MySQL、SQL Server、Oracle、DB2、PostgreSQL等主流数据库,也支持MongoDB这种新型NoSQL方式的存储
Mycat并不存储数据,只做数据路由。其会拦截用户发送过来的SQL语句,对SQL语句做一些特定的分析:如分片分析、路由分析、读写分离分析、缓存分析等,然后将此SQL发往后端的真实数据库,并将返回的结果做适当的处理,最终再返回给用户。
因此,mycat中存在一些逻辑XX性的概念,如逻辑库,逻辑表。
逻辑库(schema)
存在在mycat里面的虚拟库,我们可以通过直接操作逻辑库,而具体的分片、分表还是分库,由我们配置后,交给mycat自动处理。
逻辑表(table)
存在在mycat里面的虚拟表【简单了解下,后面讲用的时候再细讲】
分片表
分片表,是指那些原有的很大数据的表,需要切分到多个数据库的表,这样,每个分片都有一部分数据,所有分片构成了完整的数据
ER表
子表的记录与所关联的父表记录存放在同一个数据分片上,即子表依赖于父表,通过表分组(Table Group)保证数据Join不会跨库操作。
表分组(Table Group)是解决跨分片数据join的一种很好的思路,也是数据切分规划的重要一条规则
全局表
例如字典表,每一个数据分片节点上有保存了一份字典表数据
数据冗余是解决跨分片数据join的一种很好的思路,也是数据切分规划的另外一条重要规则
分片节点(dataNode)
数据切分后,一个大表被分到不同的分片数据库上面,每个表分片所在的数据库就是分片节点。
在dataNode中可以指定对应的dataHost
节点主机(dataHost)
dataHost,就可以指定我们真实的物理主机的信息。当然,做mycat高可用时,也可以指定某个mycat节点作为“真实主机”。
数据切分后,每个分片节点(dataNode)不一定都会独占一台机器,同一机器上面可以有多个分片数据库,这样一个或多个分片节点(dataNode)所在的机器就是节点主机(dataHost),为了规避单节点主机并发数限制,尽量将读写压力高的分片节点(dataNode)均衡的放在不同的节点主机(dataHost)
分片规则(rule)
前面讲了数据切分,一个大表被分成若干个分片表,就需要一定的规则,这样按照某种业务规则把数据分到某个分片的规则就是分片规则。
如:取模、按天/月分区、固定hash、一致性hash等。
全局序列号(sequence)
数据切分后,原有的关系数据库中的主键约束在分布式条件下将无法使用,因此需要引入外部机制保证数据唯一性标识,这种保证全局性的数据唯一标识的机制就是全局序列号(sequence)。
mycat中有几种实现全局序列号的方式,后面会具体讲。
接下来看看mycat的基础使用:
下载 源码地址:
mycat源码地址
打开后配置启动:
Mycat(一)——基本概念和使用
文章图片

VM参数:
-DMYCAT_HOME=${换成源码路径}\src\main -XX:MaxDirectMemorySize=512M

首先先简单演示下,不做任何分表分库的操作:
server.xml中添加一个访问mycat逻辑库schemas的用户:
123456 mycatDB

该配置信息为:添加一个name为cat的用户,密码为123456,对应的逻辑库为mycatDB
接着在schema.xml配置:
scheme标签中就是一个逻辑库的配置。
  • scheme:
    name:逻辑库的名字
    sqlMaxLimit=“100” :查询时不会进行分表,会添加limit分页
    dataNode:指定数据节点,与下面的dataNode标签的name对应。
  • dataNode
    一个数据节点。
    name:数据节点的名字(唯一)
    dataHost:与下面的dataHost标签的name对应
    database:物理库的名字
  • dataHost
    一个数据host
    在里面的writeHost,url和user、password为我们实际物理库的连接信息。
  • table:
    table标签共有九个属性:
    • name:对应Mysql中的表名
    • dataNode:逻辑表所在的分片,该属性值需要和dataNode标签的name属性对应,
    • rule:逻辑表使用的分片规则名称,规则在conf/rule.xml中配置,该属性值必须与 tableRule标签中的name属性对应
    • ruleRequired:是否绑定分片规则,如果为true的话,就一定要配置rule,否则会报错
    • primaryKey:逻辑表对应真实表的主键
      type:逻辑表类型,分为全局表和普通表
    • autoIncrement:是否启用自增主键,对应Mysql自增主键,默认时禁用的
    • subTable:分表
    • needAddLimit:是否允许自动添加schema标签中设置的limit,默认为true
name="mycatDB" checkSQLschema="true" sqlMaxLimit="100" dataNode="localdn">
select user()

配置完成后我们启动mycat工程。
接着搭建一个Springboot工程,我们可以直接连接mycat的逻辑库:
spring.druid.jdbcUrl=jdbc:mysql://localhost:8066/mycatDB?useCompression=true spring.druid.username=cat spring.druid.password=123456 spring.druid.driver-class-name=com.mysql.jdbc.Driver

mycat端口号默认为8066,mycatDB就是我们配置的逻辑库的名字,下面的用户名和密码就是逻辑库配置的用户名和密码。
接着写一个单元测试:
@Test public void test1() { Area area = new Area (); area.setAreaCode("wml"); area.setAreaName("wml"); area.setState(1); commonMapper.addArea(area); }

向consult库中的一个表中插入一条数据。
Mycat(一)——基本概念和使用
文章图片

插入成功。
分表 scheme.xml
name="mycatDB" checkSQLschema="true" dataNode="localdn">
select user()

table标签中有两个属性说明下:
  • subTables
    指定子表,该属性指定主表的子表,t_order$1-3就是t_order1、t_order2、t_order3的缩写。当然也可以用逗号分隔多个表
  • rule:
    指定分片规则,该值与rule.xml中的tableRule的name属性一致:
order_id mod-long

columns指定分片操作的列。
algorithm指定分片规则,与rule.xml中的function标签的name属性一致。
3

count中指定dataNode的个数
接着测试一下:
首先准备三个分表:
CREATE TABLE `t_order1` ( `order_id` int(11) NOT NULL, `content` varchar(255) DEFAULT NULL, PRIMARY KEY (`order_id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1; --另外两个t_order2和t_order3一样的,换一个表名即可。

测试插入:
public void test() { for (int i = 0; i < 1000; i++) { Order order = new Order(); order.setOrderId(i); order.setContent("wml" + i); orderMapper.addOrder(order); } }@Insert("insert into t_order(order_id,content) values(#{order_id},#{order_content})") int addOrder(Order order);

Mycat(一)——基本概念和使用
文章图片

可以看到成功插入到三张表中。
再测试查询:
@Test public void test() { Order order= orderMapper.querOrderById(877); System.out.println(order); }

我们根据id查询,id为877,按照规则,877%3=1,mycat应该从t_order2进行查询。
启动后查看mycat日志:
2020-08-06 22:00:40,661 [DEBUG][$_NIOREACTOR-0-RW] SQLRouteCache add cache ,key:mycatDBselect * from t_order where order_id=877 value:select * from t_order where order_id=877, route={ 1 -> localdn{SELECT * FROM t_order2 WHERE order_id = 877} }(io.mycat.cache.impl.EnchachePool:EnchachePool.java:60) 2020-08-06 22:00:40,661 [DEBUG][$_NIOREACTOR-0-RW] ServerConnection [id=36, schema=mycatDB, host=127.0.0.1, user=cat,txIsolation=3, autocommit=true, schema=mycatDB, executeSql=select * from t_order where order_id=877]select * from t_order where order_id=877, route={ 1 -> localdn{SELECT * FROM t_order2 WHERE order_id = 877} } rrs(io.mycat.server.NonBlockingSession:NonBlockingSession.java:126)

可以看到,会根据id进行hash,直接从第二张表查询。在这之前,会先从缓存中进行查询,缓存没有再从数据库查询。
而如果直接select * from ,就会进行全表查询,发出三个查询语句分别查询三个库进行汇总。
【Mycat(一)——基本概念和使用】或者可以直接在本地数据库工具连接mycat:
Mycat(一)——基本概念和使用
文章图片

    推荐阅读