• java
  • java8
  • java开发

一篇秒懂mycat

banner

前言

哈喽,大家好,最近换了工作,为了更快的熟悉新环境,大部分精力都在学习公司的项目业务以及技术,所以公众号更新就少了(非常感谢各位依旧关注),但是我又学到了一些新的技术哈哈~~,又整理了一遍分享给各位。

什么是mycat

它是阿里开源的一个数据库中间件,专门为大数据量的项目做分库分表用的。有如下特点:

  • 一个彻底开源的,面向企业应用开发的大数据库集群
  • 支持事务、ACID、可以替代MySQL的加强版数据库
  • 一个可以视为MySQL集群的企业级数据库,用来替代昂贵的Oracle集群
  • 一个融合内存缓存技术、NoSQL技术、HDFS大数据的新型SQL Server
  • 结合传统数据库和新型分布式数据仓库的新一代企业级数据库产品
  • 一个新颖的数据库中间件产品

官网地址: http://www.mycat.org.cn/

mycat权威指南: http://www.mycat.org.cn/document/mycat-definitive-guide.pdf

mycat架构

话不多说,一张mycat架构图就能让你知道mycat的角色以及作用。

mycat1.6版本架构如下:

由图可知,mycat位于数据库和应用层(APP)之间,它的角色就是帮我们管理数据库集群,而提供应用统一访问数据库接口。

垂直分库

垂直分库通俗来说就是按照功能划分,将不同的数据放在不同的数据库中。

水平分表

水平分表通俗来说就是某表数据量太大了,那么我们很自然地想到是加多一个表来存储数据,这样查询速度才会更快。那么水平分表就是表结构是一样的,只不过存的数据不一样而已。

逻辑库和逻辑表

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

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

mycat基本配置

当我们数据量特别大的时候需要分库分表的时候,那么我们可以考虑使用mycat。那么mycat具体如何做到分库分表的呢?接下来就要学习mycat的三大配置文件进行灵活配置就可以实现分库分表啦啦啦。。。

mycat主要的三大配置文件: server.xml、schema.xml、rule.xml

这三个配置文件位于mycat的安装目录的conf目录中。

server.xml

该文件几乎包含了所有 mycat 需要的系统配置信息。其中包括对外(应用)访问端口,编码,连接超时时间,最大连接数,事务级别,用户密码以及逻辑库等信息。

详细可以阅读下面的配置:


<!DOCTYPE mycat:server SYSTEM "server.dtd">
<mycat:server xmlns:mycat="http://io.mycat/">
    <system>
        <property name="serverPort">8066</property> <!-- mycat 服务端口-->
        <property name="managerPort">9066</property><!-- mycat 管理端口-->
        <property name="nonePasswordLogin">0</property>
        <property name="bindIp">0.0.0.0</property>
        <property name="frontWriteQueueSize">2048</property>
        <property name="charset">utf8</property><!-- 配置该属性的时候一定要保证mycat的字符集和mysql 的字符集是一致的 --> 
        <property name="txIsolation">2</property> <!-- 前端连接的初始化事务隔离级别,只在初始化的时候使用,后续会根据客户端传递过来的属性对后端[数据库](http://msd.misuland.com/pd/3148108429789238586)连接进行同步。默认为 REPEATED_READ,设置值为数字默认 3。  READ_UNCOMMITTED = 1;  READ_COMMITTED = 2;  REPEATED_READ = 3;  SERIALIZABLE = 4;-->
        <property name="processors">8</property><!-- 处理线程数量,默认是cpu数量-->
        <property name="idleTimeout">1800000</property><!-- mycat访问mysql,多长时间无反应断开连接-->
        <property name="useSqlStat">0</property> <!-- 1为开启实时统计、0为关闭 -->
        <property name="useGlobleTableCheck">0</property> <!-- 1为开启全局表一致性检测、0为关闭 -->
        <property name="sqlExecuteTimeout">300</property><!-- SQL 执行超时的时间,Mycat 会检查连接上最后一次执行 SQL 的时间,若超过这个时间则会直接关闭这连接。默认时间为 300 秒,单位秒。-->
        <property name="sequnceHandlerType">1</property>  <!-- 用来指定Mycat全局序列类型,0为本地文件,1为数据库方式,2为时间戳列方式,默认使用本地文件方式,文件方式主要用于测试--> 
        <property name="defaultMaxLimit">100</property><!-- mycat 默认返回的结果集大小-->
        <property name="maxPacketSize">104857600</property><!-- 指定 Mysql 协议可以携带的数据最大长度。默认 16M。-->
    </system>
  <!--表示mycat的登录用户名-->
    <user name="root">
 <!--表示mycat的登录密码,密码加密:java -cp Mycat-server-xxx.jar io.mycat.util.DecryptUtil 0:user:password 
      <property name="usingDecrypt">1</property> -->
        <property name="password">123456</property>
<!--表示mycat的逻辑数据库名称,可以自定义-->
        <property name="schemas">shop_db</property>
    </user>
</mycat:server>
复制代码

更多关于server.xml的配置可参考以下文章:

http://suo.im/6lJTHF http://suo.im/6lJTK5 http://suo.im/6613kS

schema.xml

作为MyCat中重要的配置文件之一,它主要管理着MyCat的逻辑库、表、分片规则、DataNode以及DataHost。弄懂这些配置,是正确使用MyCat的前提。这里就一层层对该文件进行解析。

标签解析:

  • schema:配置逻辑库,与server.xml中的逻辑库要对应。
  • table:配置逻辑表,包含主键,自增在,位于哪个节点等。
  • dataNode :配置逻辑库与物理库的对应关系
  • dataHost :配置连接数据库主机信息。

更多详细可以参考配置文件说明:

<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
<!-- 定义逻辑库,name属性是指逻辑库,sqlMaxLimit限制返回的行数,checkSQLschema默认是false,判断是否检查发给mycat的sql是否包含库名 -->
    <schema name="shop_db" checkSQLschema="false" sqlMaxLimit="100">
 <!-- 定义逻辑表,name属性定义逻辑表名称,dataNode表示数据所属逻辑节点,primaryKey定义逻辑表的主键,type表示逻辑表的类型,global为全局表,autoIncrement是指自动递增-->
        <table name="region_info" dataNode="orddb,custdb,prodb" primaryKey="region_id" type="global"/>
        <table name="order_cart" dataNode="orddb" primaryKey="cart_id"/>
        <table name="order_customer_addr" dataNode="orddb" primaryKey="customer_addr_id"/>
        <table name="order_detail" dataNode="orddb" primaryKey="order_detail_id"/>
        <table name="order_master" dataNode="orddb01,orddb02,orddb03,orddb04" rule="order_master" primaryKey="order_id" autoIncrement="true"/>
        <table name="customer_balance_log" dataNode="custdb" primaryKey="balance_id"/>
        <table name="customer_inf" dataNode="custdb" primaryKey="customer_inf_id"/>
        <table name="customer_level_inf" dataNode="custdb" primaryKey="customer_level"/>
        <table name="customer_login" dataNode="custdb" primaryKey="customer_id"/>
        <table name="customer_login_log" dataNode="custdb" primaryKey="login_id"/>
        <table name="customer_point_log" dataNode="custdb" primaryKey="point_id"/>
        <table name="product_brand_info" dataNode="prodb" primaryKey="brand_id"/>
        <table name="product_category" dataNode="prodb" primaryKey="category_id"/>
        <table name="product_comment" dataNode="prodb" primaryKey="comment_id"/>
        <table name="product_info" dataNode="prodb" primaryKey="product_id"/>
        <table name="product_supplier_info" dataNode="prodb" primaryKey="supplier_id"/>
    </schema>
    <!-- 定义数据存储的物理位置,dataHost指逻辑主机,database为物理数据库的名称-->
    <dataNode name="orddb" dataHost="mysql10" database="order_db"/>
    <dataNode name="custdb" dataHost="mysql11" database="customer_db"/>
    <dataNode name="prodb" dataHost="mysql12" database="product_db"/>
    <dataNode name="orddb01" dataHost="mysql10" database="orddb01"/>
    <dataNode name="orddb02" dataHost="mysql10" database="orddb02"/>
    <dataNode name="orddb03" dataHost="mysql11" database="orddb01"/>
    <dataNode name="orddb04" dataHost="mysql12" database="orddb01"/>
    <dataNode name="mycat" dataHost="mysql10" database="mycat"/>

    <!-- 定义后端数据库主机信息;balance=3指所有的读操作都只发送到writeHost的readHost上;writeType=“0”, 所有写操作都发送到可用的writeHost上;switchType='1' 默认值,表示自动切换-->
    <dataHost balance="3" maxCon="1000" minCon="10" name="mysql10" writeType="0" switchType="1" dbType="mysql" dbDriver="native">
          <!--检查后端数据库是否可用 -->
        <heartbeat>select user()</heartbeat>
        <!-- writeHost指定写实例、readHost指定读实例-->
        <writeHost host="192.168.56.10" url="192.168.56.10:3306" password="123456" user="im_mycat"/>
    </dataHost>
    <dataHost balance="3" maxCon="1000" minCon="10" name="mysql11" writeType="0" switchType="1" dbType="mysql" dbDriver="native">
        <heartbeat>select user()</heartbeat>
        <writeHost host="192.168.56.11" url="192.168.56.11:3306" password="123456" user="im_mycat"/>
    </dataHost>
    <dataHost balance="3" maxCon="1000" minCon="10" name="mysql12" writeType="0" switchType="1" dbType="mysql" dbDriver="native">
        <heartbeat>select user()</heartbeat>
        <writeHost host="192.168.56.12" url="192.168.56.12:3306" password="123456" user="im_mycat"/>
    </dataHost>
</mycat:schema>

复制代码

关于更多ER图关系配置和其他参数意义。可参考以下文件或者《mycat权威指南》 https://blog.csdn.net/l1028386804/article/details/53385637 https://www.cnblogs.com/jihaibo/p/9051105.html https://www.cnblogs.com/ivictor/p/5131480.html

rule.xml

它的功能主要体现在以下两个方面:

  • 1、配置水平分片的分片规则
  • 2、配置分片规则所对应的分片函数
<!DOCTYPE mycat:rule SYSTEM "rule.dtd">
<mycat:rule xmlns:mycat="http://io.mycat/">
    <tableRule name="order_master"> <!-- 与schema.xml的table标签中的rule对应关系-->
        <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>
复制代码

其中的function的name必须是唯一的,以上就是hash取模4的分片算法。

常见的分片算法:

  • 简单取模-PartitionByMod
  • 哈希取模-PartitionByHashMod
  • 分片枚举-PartitionByFileMap
  • 字符串范围取模分片

更多可以参考文章: https://blog.csdn.net/l1028386804/article/details/53402552 https://www.cnblogs.com/kingsonfu/p/10627423.html

最后

mycat的基本知识到此结束,如果需要了解更多可以阅读官网提供的《mycat权威指南》,后续会对其操作进行详细的描述哦,下期再见!!!

更多关于Java的知识可以关注公众号【爱编码】

本文使用 mdnice 排版

内容来源于网络,如有侵权请联系客服删除