当前位置:首页 > 行业动态 > 正文

分布式数据存储中间件mycat的核心流程

客户端请求经Mycat解析,按规则路由至数据库节点执行,结果聚合后返回,完成分布式

分布式数据存储中间件MyCat核心流程详解

MyCat架构

MyCat作为一款开源的数据库中间层组件,主要解决大规模数据存储场景下的分库分表、读写分离、高可用性等问题,其核心架构包含以下模块:

  • 前端连接池:管理客户端连接,支持MySQL协议兼容。
  • SQL解析引擎:负责解析SQL语句,提取关键信息。
  • 路由计算模块:根据分库分表规则确定目标数据库节点。
  • 执行引擎:协调多个数据库节点执行SQL,处理事务一致性。
  • 结果归并模块:合并不同节点的返回结果,形成最终数据集。
  • 后端数据节点:实际存储数据的MySQL或其他关系型数据库实例。

核心流程分解

MyCat处理SQL请求的核心流程可分为5个阶段,具体如下:

阶段 功能描述 关键技术点
SQL解析 词法分析、语法校验、语义分析 基于Druid解析器扩展,支持标准SQL及特定语法
路由计算 确定目标数据库节点 分片规则匹配、全局表识别、读写分离策略
执行计划生成 构建分布式执行路径 单节点/多节点执行、事务拆分、序列处理
SQL执行 与数据库节点交互 连接复用、负载均衡、异常重试机制
结果合并 数据聚合与排序 多结果集归并、字段对齐、游标管理

阶段1:SQL解析(深度解析)

  1. 词法分析:将原始SQL分解为Token流,识别关键字、表名、字段等元素
  2. 语法校验:验证SQL是否符合MySQL语法规范,支持SELECT/INSERT/UPDATE/DELETE等操作
  3. 语义分析
    • 识别涉及的表类型(全局表/分表/ER表)
    • 提取WHERE条件中的分片键
    • 解析JOIN关系及子查询
  4. 路由标记:为后续阶段标注需要路由计算的关键信息

阶段2:路由计算(核心逻辑)

根据配置文件中的分片规则(schema.xml)进行路由决策:

<table name="order" dataNode="dn1,dn2" rule="shard-id^b" />
  • 分片规则类型
    • 哈希分片:shard-id^b表示按字段取模
    • 范围分片:date<'2023-01-01'指定时间范围
    • 自定义函数:调用Java方法进行复杂计算
  • 特殊表处理
    • 全局表:所有分片都查询,结果去重合并
    • ER分片:通过主外键关系推导关联表路由
  • 读写分离策略
    • 读操作:随机选择读节点(可配置权重)
    • 写操作:强制路由到主库节点

阶段3:执行计划生成

根据路由结果生成分布式执行计划:

  • 单节点执行:简单查询直接下发至目标节点
  • 多节点并行
    • 创建线程池管理并发任务
    • 维护事务ID保证跨节点一致性
    • 处理分布式锁(如自增主键)
  • 特殊处理
    • 跨库COUNT()优化为并行统计后累加
    • ORDER BY转换为各节点预排序+归并排序
    • LIMIT n偏移量计算优化

阶段4:SQL执行(底层交互)

  • 连接管理
    • 使用NIO连接器复用物理连接
    • 维护连接状态池(活跃/空闲/失效)
  • 协议转换
    • 将MyCat协议转换为目标数据库协议
    • 处理数据库方言差异(如Oracle/MySQL差异)
  • 异常处理
    • 网络超时自动重试(可配置次数)
    • 主从数据不一致告警
    • 死锁检测与回滚

阶段5:结果合并(性能关键)

  • 数据对齐
    • 字段映射:统一不同表的列名/类型
    • 结果过滤:应用WHERE条件的剩余判断
  • 归并算法
    • 排序归并:对ORDER BY字段建立优先队列
    • 流式处理:边接收边输出,减少内存占用
  • 元数据合成
    • 合并Affected Rows数量
    • 生成统一游标控制
    • 处理last_insert_id()全局序列

典型场景处理示例

场景1:分表查询(订单表按用户ID分片)

SELECT  FROM order WHERE user_id = 1001;
  1. 解析发现user_id是分片键
  2. 计算hash(1001)%4=3 → 路由到dn4节点
  3. 单节点执行后直接返回结果

场景2:全局表关联查询

SELECT a., b.name FROM user a JOIN department b ON a.dept_id = b.id;
  1. 识别user为分表,department为全局表
  2. 并行查询所有user分片 + 单独查询department表
  3. 结果集做笛卡尔积后过滤,最终合并输出

场景3:跨库事务处理

START TRANSACTION;
UPDATE account SET balance = balance 100 WHERE id = 1;
UPDATE account SET balance = balance + 100 WHERE id = 2;
COMMIT;
  1. 解析事务边界,生成全局事务ID
  2. 将更新拆分到两个分片节点
  3. 使用两阶段提交保证原子性:
    • 准备阶段:各节点预执行并锁定
    • 提交阶段:所有节点确认后统一提交

性能优化机制

  1. 缓存加速
    • SQL路由结果缓存(可配置TTL)
    • 热门数据节点连接池预热
  2. 批量处理
    • 合并相邻相同路由的SQL请求
    • 参数化查询复用执行计划
  3. 智能路由
    • 动态统计节点负载,调整分发策略
    • 热点数据自动迁移提示
  4. 索引下推
    • 将过滤条件尽可能下发至各节点
    • 减少网络传输和归并计算量

FAQs

Q1:MyCat如何实现全局自增主键?
A1:通过内置序列生成器(SequenceHandler)实现分布式ID生成,支持两种模式:

  • 文件型:使用本地文件记录当前值,集群中需保证文件同步
  • 数据库型:依赖配置的中心库表存储序列状态,适合高可用场景
    每次插入操作时,MyCat会集中获取序列值,避免各节点ID冲突。

Q2:读写分离出现数据延迟怎么办?
A2:解决方案包括:

  1. 调整binlog同步策略:将主从复制模式改为并行复制提升速度
  2. 配置延迟阈值检测:当从库延迟超过设定值时自动切换为全主库模式
  3. 业务层面改造:对实时性要求高的操作强制路由到主库
  4. 监控告警:通过MyCat自带的监控系统实时查看
0