欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

MyCat简介

程序员文章站 2022-03-20 13:37:04
...

Mycat简介

1.功能介绍

Mycat是什么?从定义和分类来看,它是一个开源的分布式数据库系统,是一个实现了MySQL协议的的Server,前端用户可以把它看作是一个数据库代理,用MySQL客户端工具和命令行访问,而其后端可以用MySQL原生(Native)协议与多个MySQL服务器通信,也可以用JDBC协议与大多数主流数据库服务器通信,其核心功能是分表分库,即将一个大表水平分割为N个小表,存储在后端MySQL服务器里或者其他数据库里。

2.Mycat原理

Mycat的原理中最重要的一个动词是“拦截”,它拦截了用户发送过来的SQL语句,首先对SQL语句做了一些特定的分析:如分
片分析、路由分析、读写分离分析、缓存分析等,然后将此SQL发往后端的真实数据库,并将返回的结果做适当的处理,最终再
返回给用户。

3.应用场景

  • 单纯的读写分离,此时配置最为简单,支持读写分离,主从切换
  • 分表分库,对于超过1000万的表进行分片,最大支持1000亿的单表分片
  • 多租户应用,每个应用一个库,但应用程序只连接Mycat,从而不改造程序本身,实现多租户化
  • 报表系统,借助于Mycat的分表能力,处理大规模报表的统计
  • 替代Hbase,分析大数据
  • 作为海量数据实时查询的一种简单有效方案,比如100亿条频繁查询的记录需要在3秒内查询出来结果,除了基于主键的查询,还可能存在范围查询或其他属性查询,此时Mycat可能是最简单有效的选择

数据分片

1.垂直切分

一个数据库由很多表的构成,每个表对应着不同的业务,垂直切分是指按照业务将表进行分类,分布到不同的数据库上面,这样也就将数据或者说压力分担到不同的库上面

优点

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

缺点

  • 部分业务表无法join,只能通过接口方式解决,提高了系统复杂度。
  • 受每种业务不同的限制存在单库性能瓶颈,不易数据扩展跟性能提高。
  • 事务处理复杂
  • 由于垂直切分是按照业务的分类将表分散到不同的库,所以有些业务表会过于庞大,存在单库读写与存储瓶颈,所以就需要水平拆分来做解决

2.水平切分

相对于垂直拆分,水平拆分不是将表做分类,而是按照某个字段的某种规则来分散到多个库之中,每个表中包含一部分数据。简
单来说,我们可以将数据的水平切分理解为是按照数据行的切分,就是将表中的某些行切分到一个数据库,而另外的某些行又切
分到其他的数据库中

优点

  • 拆分规则抽象好,join操作基本可以数据库做。
  • 不存在单库大数据,高并发的性能瓶颈。
  • 应用端改造较少。
  • 提高了系统的稳定性跟负载能力

缺点

  • 拆分规则难以抽象。
  • 分片事务一致性难以解决。
  • 数据多次扩展难度跟维护量极大。
  • 跨库join性能较差

3.数据切分的原则

  • 第一原则:能不切分尽量不要切分。
  • 第二原则:如果要切分一定要选择合适的切分规则,提前规划好。
  • 第三原则:数据切分尽量通过数据冗余或表分组(Table Group)来降低跨库Join的可能。
  • 第四原则:由于数据库中间件对数据Join实现的优劣难以把握,而且实现高性能难度极大,业务读取尽量少使用多表Join。

Mycat中的基本概念

1.逻辑库

前面一节讲了数据库中间件,通常对实际应用来说,并不需要知道中间件的存在,业务开发人员只需要知道数据库的概念,所以
数据库中间件可以被看做是一个或多个数据库集群构成的逻辑库

<dataNode name="order_db" dataHost="mysql124" database="order_db"/>

2.逻辑表

2.1逻辑表

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

 <table name="order_customer_addr"   dataNode="order_db"primaryKey="customer_addr_id"/>

2.2分片表

分片表,是指那些原有的很大数据的表,需要切分到多个数据库的表,这样,每个分片都有一部分数据,所有分片构成了完整的
数据。

 <table name="order_master" dataNode="orderdb01,orderdb02,orderdb03,orderdb04" rule="order_master" primaryKey="order_id" autoIncrement="true"></table>

2.3 非分片表

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

<table name="shipping_info" dataNode="order_db" primaryKey="ship_id"/>

2.4 ER表

关系型数据库是基于实体关系模型(Entity-RelationshipModel)之上,通过其描述了真实世界中事物与关系,Mycat中的ER表即是来源于此。根据这一思路,提出了基于E-R关系的数据分片策略,子表的记录与所关联的父表记录存放在同一个数据分片上,即子表依赖于父表,通过表分组(TableGroup)保证数据Join不会跨库操作。

 <table name="order_master" dataNode="orderdb01,orderdb02,orderdb03,orderdb04" rule="order_master" primaryKey="order_id" autoIncrement="true">
  <childTable name="order_detail" joinKey="order_id" parentKey="order_id" primaryKey="order_detail_id" autoIncrement="true"/>
</table>

2.5全局表

一个真实的业务系统中,往往存在大量的类似字典表的表,这些表基本上很少变动

全局表特性

  • 变动不频繁
  • 数据量总体变化不大
  • 数据规模不大,很少有超过数十万条记录
<table name="region_info" dataNode="order_db,product_db,customer_db" primaryKey="region_id" type="global"/>

2.6 分片节点

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

<dataNode name="orderdb04" dataHost="mysql125" database="orderdb04"/>

2.7 节点主机

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

    <dataHost balance="3" maxCon="1000" minCon="10" name="mysql123" writeType="0" switchType="1" dbType="mysql" dbDriver="native">
        <heartbeat>select user()</heartbeat>
        <writeHost host="192.168.56.123" url="192.168.56.123:3306" password="123456" user="im_mycat"/>
    </dataHost>

2.8 分片规则

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

<!DOCTYPE mycat:rule SYSTEM "rule.dtd">
<mycat:rule xmlns:mycat="http://io.mycat/">
    <tableRule name="order_master">
        <rule>
            <columns>customer_id</columns>
            <algorithm>mod-long</algorithm>
        </rule>
    </tableRule>
    <function name="mod-long" class="io.mycat.route.function.PartitionByMod">
        <property name="count">4</property>
    </function>
</mycat:rule>

2.9 全局序列

数据切分后,原有的关系数据库中的主键约束在分布式条件下将无法使用,因此需要引入外部机制保证数据唯一性标识,这种保证全局性的数据唯一标识的机制就是全局***(sequence)

 <property name="sequnceHandlerType">0</property>
# sequnceHandlerType 配置为0 表示使用本地文件读取。
 <property name="sequnceHandlerType">1</property>
# sequnceHandlerType 配置为1 表示从数据库表中读取。
  <property name="sequnceHandlerType">2</property>
# sequnceHandlerType 配置为2表示时间戳方式。