上一篇
分布式数据存储中间件mycat的核心流程
- 行业动态
- 2025-05-10
- 4
客户端请求经Mycat解析,按规则路由至数据库节点执行,结果聚合后返回,完成分布式
分布式数据存储中间件MyCat核心流程详解
MyCat架构
MyCat作为一款开源的数据库中间层组件,主要解决大规模数据存储场景下的分库分表、读写分离、高可用性等问题,其核心架构包含以下模块:
- 前端连接池:管理客户端连接,支持MySQL协议兼容。
- SQL解析引擎:负责解析SQL语句,提取关键信息。
- 路由计算模块:根据分库分表规则确定目标数据库节点。
- 执行引擎:协调多个数据库节点执行SQL,处理事务一致性。
- 结果归并模块:合并不同节点的返回结果,形成最终数据集。
- 后端数据节点:实际存储数据的MySQL或其他关系型数据库实例。
核心流程分解
MyCat处理SQL请求的核心流程可分为5个阶段,具体如下:
阶段 | 功能描述 | 关键技术点 |
---|---|---|
SQL解析 | 词法分析、语法校验、语义分析 | 基于Druid解析器扩展,支持标准SQL及特定语法 |
路由计算 | 确定目标数据库节点 | 分片规则匹配、全局表识别、读写分离策略 |
执行计划生成 | 构建分布式执行路径 | 单节点/多节点执行、事务拆分、序列处理 |
SQL执行 | 与数据库节点交互 | 连接复用、负载均衡、异常重试机制 |
结果合并 | 数据聚合与排序 | 多结果集归并、字段对齐、游标管理 |
阶段1:SQL解析(深度解析)
- 词法分析:将原始SQL分解为Token流,识别关键字、表名、字段等元素
- 语法校验:验证SQL是否符合MySQL语法规范,支持SELECT/INSERT/UPDATE/DELETE等操作
- 语义分析:
- 识别涉及的表类型(全局表/分表/ER表)
- 提取WHERE条件中的分片键
- 解析JOIN关系及子查询
- 路由标记:为后续阶段标注需要路由计算的关键信息
阶段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;
- 解析发现user_id是分片键
- 计算hash(1001)%4=3 → 路由到dn4节点
- 单节点执行后直接返回结果
场景2:全局表关联查询
SELECT a., b.name FROM user a JOIN department b ON a.dept_id = b.id;
- 识别user为分表,department为全局表
- 并行查询所有user分片 + 单独查询department表
- 结果集做笛卡尔积后过滤,最终合并输出
场景3:跨库事务处理
START TRANSACTION; UPDATE account SET balance = balance 100 WHERE id = 1; UPDATE account SET balance = balance + 100 WHERE id = 2; COMMIT;
- 解析事务边界,生成全局事务ID
- 将更新拆分到两个分片节点
- 使用两阶段提交保证原子性:
- 准备阶段:各节点预执行并锁定
- 提交阶段:所有节点确认后统一提交
性能优化机制
- 缓存加速:
- SQL路由结果缓存(可配置TTL)
- 热门数据节点连接池预热
- 批量处理:
- 合并相邻相同路由的SQL请求
- 参数化查询复用执行计划
- 智能路由:
- 动态统计节点负载,调整分发策略
- 热点数据自动迁移提示
- 索引下推:
- 将过滤条件尽可能下发至各节点
- 减少网络传输和归并计算量
FAQs
Q1:MyCat如何实现全局自增主键?
A1:通过内置序列生成器(SequenceHandler)实现分布式ID生成,支持两种模式:
- 文件型:使用本地文件记录当前值,集群中需保证文件同步
- 数据库型:依赖配置的中心库表存储序列状态,适合高可用场景
每次插入操作时,MyCat会集中获取序列值,避免各节点ID冲突。
Q2:读写分离出现数据延迟怎么办?
A2:解决方案包括:
- 调整binlog同步策略:将主从复制模式改为并行复制提升速度
- 配置延迟阈值检测:当从库延迟超过设定值时自动切换为全主库模式
- 业务层面改造:对实时性要求高的操作强制路由到主库
- 监控告警:通过MyCat自带的监控系统实时查看