写点什么

MyCat 应用实战:分布式数据库中间件的实践与优化(篇幅一)

作者:肖哥弹架构
  • 2025-06-10
    河北
  • 本文字数:7744 字

    阅读完需:约 25 分钟

MyCat应用实战:分布式数据库中间件的实践与优化(篇幅一)

本文将深入探讨 MyCat 的核心特性及其在实际应用中的最佳实践。我们将从 MyCat 的基本架构入手,逐步剖析其在分布式环境下的工作原理,包括数据分片、读写分离、缓存机制等关键功能。通过具体的实战案例,展示如何在不同的业务场景中运用 MyCat 优化数据库性能,提升系统的并发处理能力和数据一致性。同时,我们还将分享在部署和维护 MyCat 过程中积累的宝贵经验,帮助读者避免常见的坑点,确保系统稳定运行。


肖哥弹架构 跟大家“弹弹” 代码设计技巧,需要代码关注

欢迎 点赞,点赞,点赞。

关注公号 Solomon 肖哥弹架构获取更多精彩内容

历史热点文章

1、Mycat 客户端与服务端介绍

MyCat 本身是一个分布式数据库中间件,它主要作为一个服务端组件运行在服务器上,为客户端应用程序提供数据库访问服务。因此,MyCat 的架构可以分为以下两个主要部分:

1.1. MyCat 服务端

MyCat 服务端是 MyCat 的核心部分,它运行在服务器上,主要功能包括:


  • 接收客户端请求:通过 MySQL 协议接收来自客户端的 SQL 请求。

  • SQL 解析与路由:解析 SQL 语句,并根据配置的分片规则将请求路由到后端数据库。

  • 数据整合与返回:从后端数据库获取数据后,整合数据并返回给客户端。

  • 分布式事务管理:支持跨多个数据库实例的分布式事务。

  • 缓存管理:提供数据缓存功能,减少对后端数据库的直接访问。

  • 监控与管理:提供系统监控、日志记录和故障报警功能。

1.2. 客户端

客户端是指与 MyCat 服务端进行交互的应用程序。客户端可以是:


  • Web 应用:如基于 Java、PHP、Python 等语言开发的 Web 应用程序。

  • 命令行工具:如 MySQL 客户端工具(mysql 命令行工具)。

  • 数据库管理工具:如 Navicat、DBeaver 等数据库管理工具。


客户端通过 MySQL 协议与 MyCat 服务端进行通信,发送 SQL 请求并接收返回结果。客户端不需要安装任何 MyCat 特定的组件,只需要将 MyCat 服务端的 IP 地址和端口配置为数据库连接地址即可。

1.3 总结

  • MyCat 服务端:运行在服务器上,提供数据库中间件服务。

  • 客户端:与 MyCat 服务端进行交互的应用程序,通过 MySQL 协议发送请求并接收结果。

1.4 客户端与服务端交互流程图

图形说明

  1. 客户端应用程序

  2. 客户端应用程序通过 MySQL 协议向 MyCat 服务端发送 SQL 请求。

  3. 发送 SQL 请求

  4. 客户端发送 SQL 请求到 MyCat 服务端。

  5. MyCat 服务端

  6. MyCat 服务端接收客户端的请求。

  7. 前端连接器

  8. 处理客户端的连接请求,进行权限认证。

  9. SQL 解析器

  10. 解析 SQL 语句,提取关键信息(如表名、字段名、条件等)。

  11. SQL 路由器

  12. 根据分片规则和读写分离策略,决定将 SQL 发送到哪个数据库节点。

  13. SQL 节点

  14. 与后端数据库进行通信,发送 SQL 语句并接收返回结果。

  15. 后端数据库

  16. 执行 SQL 语句,并将结果返回给 MyCat 服务端。

  17. 返回查询结果

  18. 后端数据库将查询结果返回给 MyCat 服务端。

  19. 缓存层

  20. 检查缓存中是否已有结果:

  21. 如果缓存命中,直接返回结果给客户端。

  22. 如果缓存未命中,将查询结果缓存起来。

  23. 返回结果给客户端

  24. 将最终结果返回给客户端。

  25. 客户端接收结果

  26. 客户端应用程序接收 MyCat 服务端返回的结果。

2. Linux 环境下安装 MyCat

2.1 安装环境准备

  • 操作系统:CentOS 6/7/8、Ubuntu 等主流 Linux 发行版。

  • Java 环境:确保已安装 JDK 1.8 或以上版本。

  • MySQL 数据库:已安装并运行 MySQL 5.5 或更高版本。

2.2 安装步骤

  1. 安装依赖


    yum install -y wget tar java-1.8.0-openjdk-devel
复制代码


或使用以下命令安装 OpenJDK(Ubuntu 系统):
复制代码


    sudo apt update    sudo apt install openjdk-8-jdk
复制代码


  1. 下载并解压 MyCat


    wget -O mycat.tar.gz http://dl.mycat.io/1.6.7-201610281010-mycat-community-server.tar.gz    tar -zxvf mycat.tar.gz -C /usr/local/
复制代码


  1. 配置环境变量


    echo 'export MYCAT_HOME=/usr/local/mycat' >> /etc/profile    echo 'export PATH=$PATH:$MYCAT_HOME/bin' >> /etc/profile    source /etc/profile
复制代码


  1. 启动 MyCat


    sh $MYCAT_HOME/bin/mycat.sh start
复制代码


  1. 验证安装

  2. 查看 MyCat 是否启动:

  3. ./mycat start 启动

  4. ./mycat stop 停止

  5. ./mycat restart 重启

  6. ./mycat status 查看 mycat 的启动状态

3. MyCat 服务配置

MyCat 服务端的配置主要涉及以下几个关键配置文件:server.xmlschema.xmlrule.xml。这些文件共同定义了 MyCat 的运行参数、数据库连接信息、分片规则、用户权限、数据节点配置、心跳检测、SQL 路由策略、缓存策略、线程池配置、日志配置、字符集配置、全局表配置、直连表配置、复杂分片规则配置、系统参数、线程池大小、日志级别、字符集支持、全局表同步策略、直连表路由策略、分片函数实现、分片键选择、分片算法配置、数据节点的读写分离策略、数据节点的负载均衡策略、数据节点的故障转移策略、数据节点的连接池配置、数据节点的心跳检测语句、数据节点的心跳检测间隔、数据节点的心跳检测超时时间、数据节点的连接初始化语句、数据节点的连接关闭语句、数据节点的连接测试语句、数据节点的连接测试间隔、数据节点的连接测试超时时间、数据节点的连接最大空闲时间、数据节点的连接最小空闲时间、数据节点的连接最大等待时间等 以下是详细的配置步骤和说明:

3.1. server.xml

server.xml 文件用于配置 MyCat 的服务参数和连接信息。


  • 系统参数配置


    <system>        <property name="sequnceHandlerType">2</property>    </system>
复制代码


  • 用户配置


    <user name="root">        <property name="password">123456</property>        <property name="schemas">testdb</property>    </user>    <user name="app">        <property name="password">password</property>        <property name="schemas">testdb</property>        <property name="readOnly">true</property>    </user>
复制代码


  • 数据节点配置


    <dataHost name="dn1" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="native">        <heartbeat>select user()</heartbeat>        <writeHost host="host1" url="jdbc:mysql://host1:3306/db1" user="root" password="123456"/>    </dataHost>    <dataHost name="dn2" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="native">        <heartbeat>select user()</heartbeat>        <writeHost host="host2" url="jdbc:mysql://host2:3306/db1" user="root" password="123456"/>    </dataHost>
复制代码


  • 系统参数配置


    <system>        <property name="sequnceHandlerType">2</property>        <property name="useSqlStat">true</property>        <property name="useGlobleTableCheck">true</property>    </system>
复制代码


  • 线程池配置


    <threadPool size="16" maxQueueSize="1024"/>
复制代码


  • 日志配置


    <logger name="mycat" level="INFO" file="logs/mycat.log"/>
复制代码

3.2. schema.xml

schema.xml 文件用于定义逻辑数据库、逻辑表以及分片规则。


  • 逻辑数据库配置


    <schema name="testdb" checkSQLschema="false" sqlMaxLimit="100">
复制代码


  • 逻辑表配置


    <table name="tb_user" dataNode="dn1,dn2" rule="rule1"/>
复制代码


  • 分片规则配置


    <rule name="rule1" column="id">        <function name="mod-long" class="io.mycat.route.function.PartitionByLong">            <property name="count">2</property>        </function>    </rule>
复制代码


  • 全局表配置


    <globalTable name="tb_config" dataNode="dn1"/>
复制代码


  • 直连表配置


    <directTable name="tb_log" dataNode="dn1"/>
复制代码

3.3. rule.xml

rule.xml 文件用于定义分片函数和分片规则。


  • 分片函数配置


    <function name="mod-long" class="io.mycat.route.function.PartitionByLong">        <property name="count">2</property>    </function>
复制代码


  • 分片规则配置


    <rule name="rule1" column="id">        <function name="mod-long" class="io.mycat.route.function.PartitionByLong">            <property name="count">2</property>        </function>    </rule>
复制代码


  • 复杂分片规则配置


    <rule name="rule2" column="id,city">        <function name="mod-long" class="io.mycat.route.function.PartitionByLong">            <property name="count">2</property>        </function>        <function name="mod-string" class="io.mycat.route.function.PartitionByString">            <property name="count">2</property>        </function>    </rule>
复制代码

配置步骤

  1. 编辑 server.xml 文件

  2. 配置系统参数、用户信息和数据节点信息。

  3. 编辑 schema.xml 文件

  4. 定义逻辑数据库、逻辑表和分片规则。

  5. 编辑 rule.xml 文件

  6. 定义分片函数和分片规则。

  7. 启动 MyCat


    sh $MYCAT_HOME/bin/mycat.sh start
复制代码


  1. 验证配置

  2. 使用 MySQL 客户端工具连接 MyCat,执行 SQL 语句验证配置是否生效。

注意事项

  • 字符集配置:在 server.xml 中配置字符集,确保数据一致性。

  • 权限配置:通过 server.xml 中的 user 标签配置用户权限。

  • 高可用配置:使用 Keepalived 或 HAProxy 配置高可用。

  • 缓存配置:在 server.xml 中配置缓存策略,优化查询性能。

  • 日志配置:在 server.xml 中配置日志级别和日志文件路径,便于问题排查。

4、完整配置

4.1 server.xml 完整配置

server.xml 配置文件


<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE mycat:server SYSTEM "server.dtd"><mycat:server xmlns:mycat="http://io.mycat/">    <!-- 系统参数配置 -->    <system>        <!-- 序列号生成器类型,1 表示使s用数据库生成,2 表示使用内存生成 -->        <property name="sequnceHandlerType">2</property>        <!-- 是否启用 SQL 统计 -->        <property name="useSqlStat">true</property>        <!-- 是否启用全局表检查 -->        <property name="useGlobleTableCheck">true</property>        <!-- 字符集配置 -->        <property name="charset">utf8</property>    </system>
<!-- 用户配置 --> <user name="root"> <!-- 用户密码 --> <property name="password">123456</property> <!-- 用户可以访问的逻辑数据库 --> <property name="schemas">testdb</property> <!-- 是否只读 --> <property name="readOnly">false</property> </user> <user name="app"> <property name="password">password</property> <property name="schemas">testdb</property> <property name="readOnly">true</property> </user>
<!-- 数据节点配置 --> <dataHost name="dn1" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="native"> <!-- 心跳检测语句 --> <heartbeat>select user()</heartbeat> <!-- 写入节点配置 --> <writeHost host="host1" url="jdbc:mysql://host1:3306/db1" user="root" password="123456"/> </dataHost> <dataHost name="dn2" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="native"> <heartbeat>select user()</heartbeat> <writeHost host="host2" url="jdbc:mysql://host2:3306/db1" user="root" password="123456"/> </dataHost> <!-- 线程池配置 --> <threadPool size="16" maxQueueSize="1024"/> <!-- 日志配置 --> <logger name="mycat" level="INFO" file="logs/mycat.log"/></mycat:server>
复制代码

配置项说明

  1. 系统参数配置

  2. sequnceHandlerType:序列号生成器类型,1 表示使用数据库生成,2 表示使用内存生成。

  3. useSqlStat:是否启用 SQL 统计。

  4. useGlobleTableCheck:是否启用全局表检查。

  5. charset:字符集配置,通常设置为 utf8

  6. 用户配置

  7. name:用户名。

  8. password:用户密码。

  9. schemas:用户可以访问的逻辑数据库。

  10. readOnly:是否只读,true 表示只读,false 表示可读写。

  11. 数据节点配置

  12. name:数据节点名称。

  13. maxCon:最大连接数。

  14. minCon:最小连接数。

  15. balance:负载均衡策略,0 表示不启用负载均衡,1 表示轮询,2 表示最小连接数。

  16. writeType:写入类型,0 表示主节点写入,1 表示从节点写入。

  17. dbType:数据库类型,如 mysql

  18. dbDriver:数据库驱动类型,如 native

  19. heartbeat:心跳检测语句,用于检测数据库连接是否有效。

  20. writeHost:写入节点配置,包括主机名、JDBC URL、用户名和密码。

  21. 线程池配置

  22. size:线程池大小。

  23. maxQueueSize:最大队列大小。

  24. 日志配置

  25. name:日志名称。

  26. level:日志级别,如 INFODEBUGERROR

  27. file:日志文件路径。

4.2 schema.xml 完整配置

schema.xml 配置文件


<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE mycat:schema SYSTEM "schema.dtd"><mycat:schema xmlns:mycat="http://io.mycat/">    <!-- 定义逻辑数据库 -->    <schema name="testdb" checkSQLschema="false" sqlMaxLimit="100">        <!-- 定义全局表,不进行分片 -->        <table name="t_global" dataNode="dn1" type="GLOBAL"/>        <!-- 定义分片表,根据分片规则进行分片 -->        <table name="t_order" dataNode="dn1,dn2" type="SHARDING" rule="rule1"/>        <!-- 定义直连表,直接路由到指定数据节点 -->        <table name="t_log" dataNode="dn1" type="DIRECT"/>    </schema>
<!-- 定义数据节点 --> <dataNode name="dn1" dataHost="host1" database="db1" writeType="0"/> <dataNode name="dn2" dataHost="host2" database="db2" writeType="1"/>
<!-- 定义数据源 --> <dataHost name="host1" host="192.168.1.1" port="3306" user="root" password="root" switchType="-1" heartbeat="select 1"> <writeHost host="host1_1" url="jdbc:mysql://192.168.1.1:3306/db1" user="root" password="root"/> </dataHost>
<dataHost name="host2" host="192.168.1.2" port="3306" user="root" password="root" switchType="-1" heartbeat="select 1"> <writeHost host="host2_1" url="jdbc:mysql://192.168.1.2:3306/db2" user="root" password="root"/> </dataHost>
<!-- 定义分片规则 --> <rule name="rule1"> <algorithm class="io.mycat.route.function.PartitionByLong"> <property name="count">2</property> </algorithm> </rule></mycat:schema>
复制代码

配置项说明

逻辑数据库配置
  • name:逻辑数据库的名称。

  • checkSQLschema:是否检查 SQL 语法,true 表示检查,false 表示不检查。

  • sqlMaxLimit:单条 SQL 的最大长度限制。

表配置
  • name:表的名称。

  • dataNode:表所属的数据节点,可以是单个数据节点或多个数据节点,用逗号分隔。

  • type:表的类型,GLOBAL 表示全局表,SHARDING 表示分片表,DIRECT 表示直连表。

  • rule:分片规则的名称,仅对 SHARDING 类型的表有效。

数据节点配置
  • name:数据节点的名称。

  • dataHost:数据源的名称。

  • database:数据库的名称。

  • writeType:写入类型,0 表示主节点写入,1 表示从节点写入。

数据源配置
  • name:数据源的名称。

  • host:数据源的主机地址。

  • port:数据源的端口号。

  • user:连接数据源的用户名。

  • password:连接数据源的密码。

  • switchType:切换类型,-1 表示不启用切换。

  • heartbeat:心跳检测语句,用于检测数据源的连接状态。

  • writeHost:写入节点的配置,包括主机名、JDBC URL、用户名和密码。

分片规则配置
  • name:分片规则的名称。

  • algorithm:分片算法的类名。

  • property:分片算法的属性,如 count 表示分片的数量。

示例说明

  1. 全局表

  2. t_global 表定义为全局表,数据会同步到所有数据节点。

  3. 分片表

  4. t_order 表定义为分片表,根据 rule1 分片规则进行分片,数据会分布在 dn1dn2 两个数据节点。

  5. 直连表

  6. t_log 表定义为直连表,直接路由到 dn1 数据节点。

  7. 分片规则

  8. rule1 使用 PartitionByLong 分片算法,将数据分为 2 个分片。

4.3 rule.xml 完整配置

rule.xml 配置文件:


<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE mycat:rule SYSTEM "rule.dtd"><mycat:rule xmlns:mycat="http://io.mycat/">
<!-- 定义分片规则 --> <tableRule name="auto-sharding-long"> <rule> <columns>order_id</columns> <algorithm>func1</algorithm> </rule> </tableRule>
<tableRule name="mod-long-2"> <rule> <columns>order_id</columns> <algorithm>mod-long-2</algorithm> </rule> </tableRule>
<tableRule name="range-long"> <rule> <columns>user_id</columns> <algorithm>range-long</algorithm> </rule> </tableRule>
<!-- 定义分片函数 --> <function name="func1" class="io.mycat.route.function.PartitionByLong"> <property name="partitionCount">2,1</property> <property name="partitionLength">256,512</property> </function>
<function name="mod-long-2" class="io.mycat.route.function.PartitionByMod"> <property name="count">4</property> </function>
<function name="range-long" class="io.mycat.route.function.AutoPartitionByLong"> <property name="mapFile">autopartition-long.txt</property> </function>
</mycat:rule>
复制代码
配置项说明

分片规则配置


  • name:分片规则的名称。

  • rule:定义具体的分片规则。

  • columns:指定分片列的名称。

  • algorithm:指定分片算法的名称,与 function 标签中的 name 属性相对应。


分片函数配置


  • name:分片函数的名称。

  • class:分片函数的类名。

  • property:分片函数的属性,具体属性根据分片函数的类名而定。


示例说明


  1. 自动分片规则

  2. auto-sharding-long:使用 PartitionByLong 分片函数,根据 order_id 进行分片,分片个数和长度分别为 2,1256,512

  3. 求模分片规则

  4. mod-long-2:使用 PartitionByMod 分片函数,根据 order_id 进行分片,分片个数为 4

  5. 范围分片规则

  6. range-long:使用 AutoPartitionByLong 分片函数,根据 user_id 进行分片,分片范围配置在 autopartition-long.txt 文件中。


分片函数属性说明


  • PartitionByLong

  • partitionCount:分片个数列表。

  • partitionLength:分片范围列表。

  • 约束:countlength 两个数组的长度必须一致,且 sum(count[i] * length[i]) = 1024

  • PartitionByMod

  • count:分片个数。

  • AutoPartitionByLong

  • mapFile:分片范围配置文件的路径。


分片范围配置文件示例 (autopartition-long.txt)


# range start-end ,data node index0-500000000=0500000001-1000000000=11000000001-1500000000=2
复制代码


发布于: 2025-06-10阅读数: 2
用户头像

智慧属心窍之锁 2019-05-27 加入

擅长于通信协议、微服务架构、框架设计、消息队列、服务治理、PAAS、SAAS、ACE\ACP、大模型

评论

发布
暂无评论
MyCat应用实战:分布式数据库中间件的实践与优化(篇幅一)_Java_肖哥弹架构_InfoQ写作社区