恒美微站
首页
关于我们
建站服务
主题模板
案例展示
资讯中心
联系我们
Mycat 1.6.7.1 分库分表实战:配置、分片规则与避坑指南
首页
资讯中心
/
Mycat 1.6.7.1 分库分表实战:配置、分片规则与避坑指南
Mycat 1.6.7.1 分库分表实战:配置、分片规则与避坑指南
发布时间:2026/10/9 20:14:21
简介本资源为Mycat 1.6.7.1版本的Linux发行包面向在CentOS7环境下搭建分布式数据库集群的运维与后端开发人员用于解决大数据场景下的水平扩展、读写分离与负载均衡问题。压缩包共95个文件约16.74MB以42个jar依赖库、16个properties配置、10个xml配置及4个sh脚本为主另含so本地库与wrapper启动组件覆盖服务运行、分片规则与连接池等核心模块。资源内含server.xml、schema.xml、rule.xml等关键配置及多种分片算法定义文件可帮助读者理解数据节点划分、哈希与范围分片策略、数据源连接配置及服务启停脚本的使用方式。目前已有494人学习下载适合需要快速部署Mycat中间件、研究分片与读写分离实现细节的开发者参考。1. 拿到 Mycat-server-1.6.7.1 这个包先搞清楚它到底解决什么问题如果你手上正好有一个Mycat-server-1.6.7.1-release-20190213150257-linux.tar.gz大概率是遇到了这样的场景后端几套 MySQL 实例业务代码里散落着一堆分库分表逻辑改一次路由规则要动好几处代码运维想加一个只读节点还得让开发配合发版。Mycat 这类数据库中间件的价值就在这——它把自己伪装成一个 MySQL 服务端应用连它就像连一个普通 MySQL分库分表、读写分离、路由规则全部下沉到中间件层配置。这个 1.6.7.1 版本属于 Mycat 1.6 系列里比较成熟的一支release 时间戳是 2019 年初基于 JDK 1.7 运行配置以 XML 为主核心是schema.xml、server.xml、rule.xml三件套。它适合谁适合那些数据库已经出现单表数据量膨胀、读写压力集中但又不想大改业务代码的团队。不适合谁不适合刚起步、单库单表还跑得飞快的项目中间件本身会带来额外的连接开销和排错复杂度属于典型的规模到了才值得上的东西。这一篇不讲空泛概念就顺着这个 tar.gz 包从解压、配置、启动一路讲到分片规则怎么设、踩坑怎么排让你能真正把它跑起来并理解每个参数在干什么。2. 解压与目录结构先认清这个包里有什么2.1 解压命令与目录布局拿到 tar.gz 第一步永远是先看结构再动手别急着改配置。用下面命令解压并查看顶层目录# 解压到当前目录会生成 mycat 目录 tar -zxvf Mycat-server-1.6.7.1-release-20190213150257-linux.tar.gz # 进入目录看结构 cd mycat ls -l解压后你会看到几个关键目录bin放启动脚本conf放全部配置文件lib放依赖 jarlogs放运行日志。这里有个血泪经验不要在生产机上直接解压到有中文或空格的路径Mycat 的启动脚本对路径里的特殊字符处理并不健壮路径带空格会导致 classpath 拼接出错启动直接报找不到主类。2.2 三个核心配置文件的分工在动手改之前必须先把三个文件各自的职责分清楚否则改错文件会浪费大量时间配置文件职责改动频率server.xml定义 Mycat 对外暴露的用户、密码、逻辑库名、端口低schema.xml定义逻辑库、逻辑表、数据节点、真实物理库连接高rule.xml定义分片算法和分片字段中server.xml里最容易被忽略的是system标签下的sequnceHandlerType它决定全局序列号的生成方式默认是本地文件方式分布式环境下必须改成数据库方式否则多节点会生成重复 ID。这个坑后面会细说。2.3 环境依赖检查Mycat 1.6.7.1 依赖 JDK启动前先确认版本java -version # 需要 1.7 及以上推荐 1.8如果机器上有多个 JDK务必在bin/mycat脚本里显式指定JAVA_HOME不要依赖系统默认。我一般会在脚本开头加一行export JAVA_HOME/your/jdk/path避免因为环境变量漂移导致启动时好时坏这种问题排查起来最费劲。3. 配置一个能跑通的分库分表最小实例3.1 server.xml定义逻辑库和访问账号先配置对外访问入口。打开conf/server.xml找到user标签部分改成你自己的账号user nameapp_user defaultAccounttrue !-- 应用连接 Mycat 时使用的密码 -- property namepasswordapp_pass_123/property !-- 该账号能访问的逻辑库对应 schema.xml 里的 schema name -- property nameschemasorder_db/property !-- 是否只读false 表示可读写 -- property namereadOnlyfalse/property /user这里的schemas值order_db必须和后面schema.xml里schema nameorder_db完全一致大小写敏感。参数说明name是登录用户名password是登录密码readOnly控制该账号是否只能读。逻辑说明Mycat 用这套账号体系拦截应用连接应用端配置的 JDBC 连接串里写的库名就是这里的order_db而不是真实物理库名。3.2 schema.xml把逻辑表映射到真实分片这是整个配置里最核心的文件。假设我们要把订单表t_order按用户 ID 分成两个库、每个库两张表schema nameorder_db checkSQLschemafalse sqlMaxLimit100 !-- 逻辑表dataNode 指向下面的分片节点 -- table namet_order dataNodedn1,dn2 rulemod-long / /schema !-- 定义两个数据节点分别指向不同的物理库 -- dataNode namedn1 dataHosthost1 databaseorder_db_0 / dataNode namedn2 dataHosthost2 databaseorder_db_1 / !-- 物理库连接信息 -- dataHost namehost1 maxCon100 minCon10 balance0 writeType0 dbTypemysql dbDrivernative switchType1 heartbeatselect user()/heartbeat writeHost hosthostM1 urljdbc:mysql://127.0.0.1:3306/order_db_0 userroot passwordroot_pass /writeHost /dataHost dataHost namehost2 maxCon100 minCon10 balance0 writeType0 dbTypemysql dbDrivernative switchType1 heartbeatselect user()/heartbeat writeHost hosthostM2 urljdbc:mysql://127.0.0.1:3307/order_db_1 userroot passwordroot_pass /writeHost /dataHost关键参数逐个说sqlMaxLimit100是防止应用不带 limit 查询时把全表拉回来生产环境建议设成 100 到 1000 之间balance0表示不开启读写分离所有请求走写库如果配了从库要改成 1 或 2switchType1表示写库宕机自动切换配合heartbeat心跳检测使用。逻辑说明应用看到的是order_db.t_order一张表实际数据被mod-long规则分散到两个物理库的t_order表里路由对应用完全透明。3.3 rule.xml分片算法的选择与参数mod-long是内置规则直接引用即可但你要理解它的分片字段从哪来tableRule namemod-long rule !-- 分片字段必须是表里真实存在的列 -- columnsuser_id/columns algorithmmod-long/algorithm /rule /tableRule function namemod-long classio.mycat.route.function.PartitionByMod !-- 分片数量必须等于 dataNode 的数量 -- property namecount2/property /function这里有个必须记住的约束count的值必须和table标签里dataNode列出的节点数量一致写 2 个节点就填 2填 3 会导致部分数据路由到不存在的节点插入直接失败。columns指定的user_id必须是查询条件里会带上的字段否则跨分片查询会退化成全节点扫描性能反而比单库差。3.4 启动与连接验证配置改完启动服务# 启动-start 表示后台启动 ./bin/mycat start # 查看状态 ./bin/mycat status # 实时看日志启动失败第一时间看这里 tail -f logs/wrapper.log启动成功后用 MySQL 客户端连 Mycat 的默认端口 8066mysql -h127.0.0.1 -P8066 -uapp_user -papp_pass_123连上后执行show databases;应该能看到order_db再use order_db; show tables;能看到t_order。此时插入一条数据去两个物理库里分别查就能验证分片是否生效。如果连不上先看logs/wrapper.log里的报错九成是配置文件的 XML 格式错误或端口被占用。4. 分片规则与全局序列决定系统能不能长期跑下去4.1 常用分片算法对比与选型mod-long只是入门真实业务里分片字段和算法选错后期扩容会非常痛苦。常见算法对比如下算法适用场景扩容难度数据倾斜风险mod-long数据量均匀、分片数固定高扩容需重分布低范围分片 range按时间或 ID 区间低追加节点即可中热点集中一致性哈希节点频繁增减低低枚举分片按地区、类型等有限枚举低取决于枚举分布我一般会这样选如果业务能接受按时间归档用范围分片最省心扩容就是加节点如果分片字段是用户 ID 且分布均匀mod-long够用如果节点数会动态变化一致性哈希更稳。选型时一定要问自己一句半年后数据翻倍我加一个节点要不要停机迁移这个问题的答案决定了你选哪个算法。4.2 全局序列号的三种方案分库分表后自增主键不再全局唯一必须用全局序列。Mycat 提供三种方式在server.xml的system里通过sequnceHandlerType切换system !-- 0本地文件 1数据库 2时间戳 -- property namesequnceHandlerType1/property /system本地文件方式0性能最好但多节点会重复只适合单节点数据库方式1需要提前在某个库建一张序列表Mycat 通过数据库锁保证唯一适合分布式时间戳方式2实现简单但高并发下可能重复。生产环境我基本只用数据库方式虽然多一次数据库交互但唯一性有保障。建表语句大致如下CREATE TABLE MYCAT_SEQUENCE ( name VARCHAR(50) NOT NULL, current_value INT NOT NULL, increment INT NOT NULL DEFAULT 1, PRIMARY KEY (name) ) ENGINEInnoDB;建好后插入一行初始记录并在schema.xml里配置sequenceHandlerType对应的数据节点Mycat 启动时会去读这张表。4.3 ER 分片与父子表绑定订单和订单明细这类有强关联的表如果各自按不同字段分片join 会变成跨库操作性能极差。Mycat 的 ER 分片通过childTable把子表绑定到父表的分片规则上table namet_order dataNodedn1,dn2 rulemod-long !-- 子表跟随父表分片join 时能下推到同一节点 -- childTable namet_order_item joinKeyorder_id parentKeyorder_id / /tablejoinKey是子表里的外键列parentKey是父表里的对应列。绑定后同一个订单的明细一定落在和订单相同的物理节点上join 就能在单库内完成。这个配置能省掉大量跨库查询是分片设计里性价比很高的一步。5. 避坑与排查那些让新手卡半天的真实问题5.1 启动报 Cannot find class 或端口占用现象执行./bin/mycat start后status显示未启动wrapper.log里报找不到主类或端口被占用。原因通常是JAVA_HOME没配好或者 8066、9066 端口已被其他进程占用。解决先在bin/mycat里显式写死JAVA_HOME再用netstat -tlnp | grep 8066查端口占用杀掉冲突进程或改server.xml里的端口。5.2 插入数据报 cant find datanode现象应用插入时报找不到数据节点。原因多半是rule.xml里count的值和schema.xml里dataNode数量不一致或者分片字段的值算出来的下标超出了节点范围。解决核对两处数量是否相等并确认分片字段没有 null 值——null 值参与取模会得到意外结果。5.3 跨分片查询返回结果不全现象不带分片字段的查询返回的数据比预期少。原因Mycat 默认只把查询路由到部分节点或者sqlMaxLimit截断了结果。解决确认查询条件是否包含分片字段如果不包含要么接受全节点扫描的性能代价要么在业务层强制带上分片字段。sqlMaxLimit设得太小也会导致结果被截断按业务实际需要调整。5.4 主键重复导致插入失败现象多节点环境下插入报主键冲突。原因用了本地文件方式的全局序列或者根本没配全局序列各节点各自自增。解决把sequnceHandlerType改成 1建好序列表确保所有节点共用同一个序列源。这个坑在单机测试时不会暴露一上多节点就翻车属于典型的测试环境好好的生产就出事。5.5 连接数暴涨拖垮数据库现象Mycat 运行一段时间后物理库连接被打满。原因dataHost里maxCon设得过大或者应用端连接池和 Mycat 连接池叠加放大。解决maxCon按物理库实际承受能力设置一般单库不超过 100同时应用端连接池要相应调小因为应用连的是 MycatMycat 再连物理库两层连接池会相乘。这个参数关系一定要算清楚否则数据库会被连接数压垮。6. 进阶技巧让 Mycat 在生产环境稳得住跑通只是第一步真正让 Mycat 在生产环境长期稳定靠的是几件不起眼但很关键的事。第一件是慢查询日志的开启与定期分析在server.xml里把sqlMaxLimit和慢查询阈值配好定期看logs/mycat.log里执行时间超过阈值的 SQL这些往往就是没带分片字段的全节点扫描是性能杀手。第二件是压测验证分片均匀度上线前用真实数据分布跑一遍统计每个物理节点的数据量和 QPS如果某个节点明显偏高说明分片字段选得不好趁数据量小赶紧换。第三件是配置文件的版本管理。schema.xml和rule.xml一旦上线任何改动都要走版本控制因为这两个文件直接决定数据路由改错一个字符就可能导致数据写错库。我习惯在每次改动前先备份改完用diff对比确认只动了预期的地方再重启。第四件是灰度扩容的节奏加节点时不要一次性把流量切过去先让新节点承接少量分片观察稳定后再逐步迁移避免一次性重分布把数据库压垮。还有一个容易被忽略的点Mycat 本身不存储数据它只是路由层所以它自己的高可用也要考虑。单点 Mycat 挂了整个应用就连不上数据库常见做法是前面挂一个负载均衡起两个 Mycat 实例应用连负载均衡地址。这样即使一个 Mycat 实例出问题另一个还能顶上。这套组合下来Mycat 才算真正具备生产可用性而不是一个能跑通的玩具。我自己踩过最深的一个坑是早期图省事用了本地文件方式的全局序列单机测试一切正常上线加到两个节点后开始零星报主键冲突排查了大半天才定位到序列号生成方式。从那以后凡是涉及分布式唯一性的配置我都会在测试阶段就用多节点环境验证绝不相信单机测试的结果。希望这些经验能帮你少走一段弯路帮到你。本文还有配套的精品资源点击获取