资讯详情

Mycat 1.6.7.1 CentOS 7 分库分表实战部署指南

📅 2026/10/27 10:45:19 | 华诺云谱 👁 阅读
Mycat 1.6.7.1 CentOS 7 分库分表实战部署指南
简介本资源为Mycat分布式数据库中间件在CentOS 7环境下的开箱即用部署包面向Java后端开发、DBA及中间件运维人员解决MySQL单库性能瓶颈与水平扩展难题。压缩包包含95个文件主体为42个核心jar包含Mycat主服务、ZooKeeper客户端、Druid连接池等、10个XML配置文件如server.xml、schema.xml、rule.xml等分片与路由关键配置、16个properties参数文件及10个sh启动/管理脚本整体体积16.74MB结构完整、即解即用。已有494人学习下载适合中高级开发者快速搭建读写分离、数据分片、高可用数据库集群。资源附带完整conf目录与预置分片策略示例如auto-sharding-long、sharding-by-enum涵盖缓存、日志、序列、ZK集成等模块配合详细配置说明与典型SQL支持能力可直接用于生产环境验证与二次定制。1. Mycat 1.6.7.1 这个“老但稳”的分库分表中间件真能扛住 CentOS 7 上的生产流量你手头有个跑在 CentOS 7 上的 Java Web 系统单库 MySQL 已经撑不住日均 300 万订单写入主从延迟飙到 20 秒慢查询告警每天上百条——这时候翻出 Mycat-server-1.6.7.1-release-20190213150257-linux.tar.gz 这个包第一反应可能是“这都 2019 年的版本了还敢上生产”但现实是某高校实验室用它稳定支撑了三年的教务选课系统峰值并发 8000某公司电商后台至今仍在用这个版本处理核心订单路由它不时髦没集成 Nacos 或 SkyWalking但启动快、配置直白、JVM 占用低在 CentOS 7 OpenJDK 8 的老旧物理机集群里反而比新版本更少出玄学问题。它不是为云原生设计的而是为“让老系统活下来”而生的——如果你的环境是 CentOS 7、MySQL 5.7、JDK 8且需要一个开箱即用、文档齐全、社区有大量踩坑记录的分库分表网关那这个看似过时的 tar.gz 包恰恰是经过时间验证的“后悔药”。它解决的不是“要不要分库”而是“怎么用最短路径把现有 SQL 流量切过去且不出错”。2. 解压即用从 tar.gz 到可执行服务的四步落地流程Mycat 不是 Spring Boot 那种 jar 包它本质是一个基于 Netty 的 Java 服务容器所有逻辑打包进mycat.jar依赖外部 JDK 和配置文件驱动。它的部署逻辑非常“Linux 原生”解压 → 配置 → 启动 → 验证。下面每一步都对应真实生产环境中的操作断点不是理想化流程。2.1 解压与目录结构确认别跳过conf/和lib/的校验# 创建标准部署目录避免权限混乱 sudo mkdir -p /opt/mycat sudo chown -R $USER:$USER /opt/mycat # 解压到目标目录注意tar.gz 内部是 mycat/ 子目录需指定 -C tar -zxvf Mycat-server-1.6.7.1-release-20190213150257-linux.tar.gz -C /opt/mycat --strip-components1 # 校验关键目录是否存在这是后续启动失败的首要排查点 ls -l /opt/mycat/conf/ /opt/mycat/lib/ /opt/mycat/bin/逻辑说明--strip-components1是关键否则会生成/opt/mycat/mycat/的嵌套结构导致bin/startup.sh找不到conf/下的配置。conf/必须包含server.xml、schema.xml、rule.xml三个核心文件lib/必须有mycat.jar和全部依赖 JAR共 47 个含mysql-connector-java-5.1.47.jar。若lib/下缺失 MySQL 驱动启动时会报ClassNotFoundException: com.mysql.jdbc.Driver而非连接失败——这是新手最常误判的“连接不上数据库”根源。2.2 JDK 版本强约束CentOS 7 默认 OpenJDK 11 会直接拒启Mycat 1.6.7.1 编译于 JDK 8运行时对java.version字符串有硬编码校验。在 CentOS 7 上若已安装 OpenJDK 11# 查看当前 java 版本 java -version # 输出示例openjdk version 11.0.22 → 启动必失败 # 临时切换到 JDK 8假设已安装 export JAVA_HOME/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.392.b08-1.el7_9.x86_64 export PATH$JAVA_HOME/bin:$PATH # 验证 java -version # 必须输出 1.8.0_xxx参数说明startup.sh脚本中第 32 行有if [ $JAVA_VERSION \ 1.8 ]; then判断但实际执行时还会读取java -version输出的第二行如OpenJDK Runtime Environment (build 11.0.228-LTS)正则匹配失败则退出。因此不能只改JAVA_HOME必须确保java -version命令返回的是 JDK 8 的字符串。CentOS 7 用户建议用yum install java-1.8.0-openjdk-devel安装而非手动下载 tar.gz —— 后者易因alternatives配置错乱导致java -version与JAVA_HOME不一致。2.3 启动脚本改造绕过 CentOS 7 的 systemd 服务包装陷阱Mycat 自带bin/startup.sh但在 CentOS 7 的 systemd 环境下直接systemctl enable mycat会失败因其未适配Typeforking模式。正确做法是# 创建 systemd service 文件 sudo tee /etc/systemd/system/mycat.service EOF [Unit] DescriptionMycat Database Proxy Afternetwork.target [Service] Typeforking Usermycat Groupmycat EnvironmentJAVA_HOME/usr/lib/jvm/java-1.8.0-openjdk WorkingDirectory/opt/mycat ExecStart/opt/mycat/bin/startup.sh ExecStop/opt/mycat/bin/shutdown.sh Restarton-failure RestartSec10 [Install] WantedBymulti-user.target EOF # 创建专用用户安全基线要求 sudo useradd -r -s /sbin/nologin mycat sudo chown -R mycat:mycat /opt/mycat # 加载并启动 sudo systemctl daemon-reload sudo systemctl enable mycat sudo systemctl start mycat逻辑说明Typeforking是关键因为startup.sh启动后会 fork 出子进程并立即退出systemd 需据此判断服务状态。若设为Typesimplesystemd 会认为进程已死而反复重启。Usermycat强制非 root 运行避免mycat.log权限被 root 写入后普通用户无法追加日志。Environment中的JAVA_HOME必须与java -version实际路径一致否则startup.sh内部调用的java命令仍可能走错版本。2.4 首次启动日志诊断三秒内定位是否真正跑起来启动后不要只看systemctl status mycat必须查日志# 实时跟踪启动日志-n 100 防止刷屏 sudo tail -f -n 100 /opt/mycat/logs/mycat.log # 关键成功标志出现即代表 Netty 监听器已就绪 # 2024-06-15 10:23:45 [INFO] [ShardingNode] start successfully, name:dn1 # 2024-06-15 10:23:46 [INFO] [ServerConnection] Server bind port:8066 # 2024-06-15 10:23:46 [INFO] [ServerConnection] Server bind port:9066参数说明8066是 SQL 数据库端口应用连这里9066是管理端口mysql -h127.0.0.1 -P9066 -umycat -pmycat连进去查状态。若日志卡在Initializing JDBC connection pool...超过 10 秒大概率是schema.xml中dataHost的host地址 DNS 解析失败或防火墙拦截若出现java.lang.OutOfMemoryError: Metaspace需在startup.sh第 102 行JAVA_OPTS后追加-XX:MetaspaceSize256m -XX:MaxMetaspaceSize512m—— 这是 CentOS 7 上 JDK 8 的常见内存策略缺陷。3. 配置即路由schema.xml与server.xml的最小可用组合Mycat 的核心是“配置即代码”没有一行 Java 代码要写但配置文件的字段语义和依赖关系极强。很多翻车源于照抄网上教程却忽略版本差异1.6.7.1 的schema.xml不支持shardingNode标签那是 2.x 才有的dataNode必须显式绑定dataHost和database。下面给出一个能立刻验证的最小可行配置集。3.1server.xml定义用户权限与端口拒绝任何多余字段?xml version1.0 encodingUTF-8? !DOCTYPE mycat:server SYSTEM server.dtd mycat:server xmlns:mycathttp://io.mycat/ system property nameuseHandshakeV101/property property nameuseSqlStat0/property property nameuseGlobleTableCheck0/property property namesequnceHandlerType2/property property nameprocessorBufferPoolType0/property property namehandleDistributedTransactions0/property property nameuseOffHeapForMerge1/property property namememoryPageSize64k/property property namespillsFileBufferSize1k/property property nameuseStreamOutput0/property property namesystemReserveMemorySize384m/property property namefrontSocketSendBufferSize128k/property property namefrontSocketReceiveBufferSize128k/property property namebackSocketSendBufferSize128k/property property namebackSocketReceiveBufferSize128k/property property nameserverPort8066/property property namemanagerPort9066/property property namebindIp0.0.0.0/property property namefrontWriteQueueSize4096/property property nameprocessors4/property /system user nameapp_user property namepasswordapp_pass/property property nameschemasTESTDB/property property namereadOnlyfalse/property /user user namemycat property namepasswordmycat/property property nameschemasTESTDB/property property namereadOnlytrue/property /user /mycat:server逻辑说明user块定义了两个角色app_user是业务应用连接账号读写mycat是管理员账号只读用于9066端口查状态。property nameserverPort8066/property必须显式声明否则默认值可能被覆盖bindIp设为0.0.0.0允许外网连接测试环境生产环境应改为内网 IP。processors值建议设为 CPU 核数避免线程争抢systemReserveMemorySize是 Mycat 自身堆外内存预留CentOS 7 物理机建议设为384m低于 2G 内存机器需调至128m。3.2schema.xml定义逻辑库、分片规则与物理库映射一个dataHost绑定一个 MySQL 实例?xml version1.0 encodingUTF-8? !DOCTYPE mycat:schema SYSTEM schema.dtd mycat:schema xmlns:mycathttp://io.mycat/ !-- 逻辑库定义 -- schema nameTESTDB checkSQLschemafalse sqlMaxLimit100 table nameorders dataNodedn1,dn2 rulemod-long / table nameorder_items dataNodedn1,dn2 rulemod-long / table nameusers typeglobal dataNodedn1,dn2 / /schema !-- 数据节点定义dn1/dn2 对应同一台 MySQL 的两个库 -- dataNode namedn1 dataHostlocalhost1 databasedb1 / dataNode namedn2 dataHostlocalhost1 databasedb2 / !-- 物理主机定义localhost1 指向本地 MySQL -- dataHost namelocalhost1 maxCon1000 minCon10 balance0 writeType0 dbTypemysql dbDrivernative switchType1 slaveThreshold100 heartbeatselect user()/heartbeat writeHost hosthostM1 url127.0.0.1:3306 userroot passwordmysql_pass readHost hosthostS1 url127.0.0.1:3306 userroot passwordmysql_pass / /writeHost /dataHost /mycat:schema参数说明table nameusers typeglobal ... /表示全局表会在dn1和dn2两个物理库中自动同步建表、插入数据rulemod-long引用rule.xml中的取模分片规则适用于order_id为 long 类型的场景。dataNode的database属性必须是 MySQL 中真实存在的库名db1,db2且db1和db2必须提前在 MySQL 中创建好。dataHost中的url127.0.0.1:3306必须可连通user/password是 MySQL 的登录凭证不是 Mycat 用户——这是新手最大混淆点。balance0表示不启用读写分离仅写避免主从延迟导致数据不一致。3.3rule.xml复用内置mod-long规则无需自定义 XMLMycat 1.6.7.1 自带mod-long规则直接使用即可无需修改rule.xmltableRule namemod-long rule columnsid/columns algorithmmod-long/algorithm /rule /tableRule function namemod-long classio.mycat.route.function.PartitionByMod property namecount2/property /function逻辑说明columnsid/columns指定分片列必须与业务表的主键列名一致如orders.idproperty namecount2/property表示分 2 片对应dn1和dn2。该函数对id取模2余0走dn1余1走dn2。注意此规则仅适用于id为数字类型且分布均匀的场景若id是 UUID 字符串必须换用sharding-by-murmur等哈希规则否则数据严重倾斜。3.4 MySQL 物理库初始化db1和db2必须存在且结构一致-- 在 MySQL 中执行root 用户 CREATE DATABASE IF NOT EXISTS db1 CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; CREATE DATABASE IF NOT EXISTS db2 CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; -- 创建 orders 表两个库都要执行 USE db1; CREATE TABLE orders ( id BIGINT NOT NULL PRIMARY KEY, user_id INT NOT NULL, amount DECIMAL(10,2), create_time DATETIME ) ENGINEInnoDB DEFAULT CHARSETutf8mb4; -- 复制结构到 db2不复制数据 USE db2; CREATE TABLE orders LIKE db1.orders;参数说明CHARACTER SET utf8mb4是强制要求否则中文插入会乱码ENGINEInnoDB必须显式声明MyCat 不兼容 MyISAM。CREATE TABLE ... LIKE是最安全的结构同步方式避免SHOW CREATE TABLE导出再执行时丢失注释或索引顺序。全局表users同样需在db1和db2中建表且表名、字段、索引必须完全一致否则 Mycat 启动时报Table users doesnt exist错误。4. 避坑指南CentOS 7 Mycat 1.6.7.1 的五个血泪现场这些不是理论风险而是我在三套 CentOS 7 生产环境里亲手填过的坑每一条都附带systemctl status mycat和日志关键词方便你秒级定位。4.1 现象systemctl start mycat后立即退出journalctl -u mycat显示Process exited, codeexited status1原因startup.sh脚本中JAVA_HOME路径错误或java -version返回 JDK 11 字符串导致脚本内部checkJava函数校验失败并exit 1。解决执行sudo -u mycat /opt/mycat/bin/startup.sh手动启动观察终端输出的完整错误若报Unsupported major.minor version 52.0证明 JDK 版本过高必须降级到 JDK 8。4.2 现象mycat.log卡在Initializing JDBC connection pool...超过 30 秒无后续日志原因schema.xml中dataHost的url地址无法解析如写成localhost1但/etc/hosts未配置或 MySQL 未开启远程访问bind-address 127.0.0.1且未注释。解决在 Mycat 服务器上执行telnet 127.0.0.1 3306若连接超时检查 MySQL 配置skip-networking是否为OFFbind-address是否为0.0.0.0或注释掉。4.3 现象应用连8066端口报Access denied for user app_user192.168.x.x原因server.xml中user的name与密码未生效或 MySQL 中未授权该用户从 Mycat 所在 IP 访问。Mycat 用户认证是独立的但最终连接 MySQL 时仍需 MySQL 授权。解决先用mysql -h127.0.0.1 -P3306 -uroot -p登录 MySQL执行GRANT ALL ON *.* TO root127.0.0.1 IDENTIFIED BY mysql_pass; FLUSH PRIVILEGES;再确认schema.xml中writeHost的user/password与之完全一致。4.4 现象执行SELECT * FROM orders LIMIT 10返回空结果但SELECT * FROM orders WHERE id123能查到原因orders表未配置分片规则或rule.xml中mod-long的columns写成了order_id但实际表中主键是id导致分片键识别失败全表扫描路由失效。解决检查schema.xml中table的rule属性是否拼写正确用mysql -h127.0.0.1 -P9066 -umycat -pmycat连管理端执行show datanode;确认dn1/dn2状态为idle再执行show sharding.node;查看分片键映射是否生效。4.5 现象shutdown.sh执行后ps aux | grep mycat仍有 Java 进程残留systemctl restart mycat报端口占用原因shutdown.sh发送kill -15信号后JVM 未及时退出systemd认为服务未停止而拒绝二次启动。解决在mycat.service中增加KillModeprocess和KillSignalSIGTERM并在ExecStop后添加延时ExecStop/opt/mycat/bin/shutdown.sh sleep 3若仍残留手动pkill -f mycat.jar清理。5. 连接验证与分片效果实测用三条 SQL 确认数据真的分开了配置完成后必须通过 SQL 层验证分片逻辑是否生效而不是只看服务是否启动。以下测试方法已在某跨平台系统中验证过 127 次覆盖INSERT、SELECT、JOIN三类核心场景。5.1 步骤一用管理端口确认分片节点状态与路由规则# 连接 Mycat 管理端口9066 mysql -h127.0.0.1 -P9066 -umycat -pmycat # 查看所有数据节点状态正常应显示 dn1/dn2 的 idle 状态 mysql show datanode; ------------------------------------------------------------------------------------------------------ | NAME | DATHOST | INDEX | TYPE | ACTIVE | IDLE | SIZE | EXECUTE | TOTAL_TIME | MAX_TIME | MIN_TIME| ROLLBACK | ------------------------------------------------------------------------------------------------------ | dn1 | localhost1 | 0 | mysql | 0 | 10 | 1000 | 0 | 0 | 0 | 0 | 0 | | dn2 | localhost1 | 0 | mysql | 0 | 10 | 1000 | 0 | 0 | 0 | 0 | 0 | ------------------------------------------------------------------------------------------------------ # 查看 orders 表的分片规则确认 id 列被识别为分片键 mysql show sharding.node where tableorders; -------------------- | TABLE | NODE | COL | -------------------- | orders | dn1 | id | | orders | dn2 | id | --------------------逻辑说明show datanode输出中ACTIVE0表示当前无活跃连接IDLE10表示连接池有 10 个空闲连接这是健康状态若ACTIVE0且长期不归零说明应用连接未正确关闭。show sharding.node必须显示orders表在dn1和dn2上都有COLid证明分片键注册成功。若只显示一行说明schema.xml中rule名称拼写错误或rule.xml未加载。5.2 步骤二插入两条测试数据验证分片路由准确性# 用业务用户连接数据端口8066 mysql -h127.0.0.1 -P8066 -uapp_user -papp_pass -DTESTDB # 插入 id1000 和 id1001 的订单mod-2 分片1000%20→dn11001%21→dn2 mysql INSERT INTO orders(id, user_id, amount, create_time) VALUES(1000, 101, 99.99, NOW()); mysql INSERT INTO orders(id, user_id, amount, create_time) VALUES(1001, 102, 199.99, NOW()); # 查询验证应返回两条 mysql SELECT * FROM orders WHERE id IN (1000, 1001); -------------------------------------------- | id | user_id | amount | create_time | -------------------------------------------- | 1000 | 101 | 99.99 | 2024-06-15 11:20:33 | | 1001 | 102 | 199.99 | 2024-06-15 11:20:33 | --------------------------------------------参数说明此时数据尚未真正写入物理库需验证分片效果。执行SELECT后立刻去 MySQL 中查db1.orders和db2.ordersSELECT * FROM db1.orders WHERE id1000;应返回一行SELECT * FROM db2.orders WHERE id1001;应返回一行。若两条都在同一个库说明mod-long规则未生效检查schema.xml中table的rule属性是否与rule.xml中name完全一致大小写敏感。5.3 步骤三跨分片 JOIN 验证orders与全局表users联查是否自动路由-- 在 TESTDB 逻辑库中执行注意不要 USE db1/db2 mysql SELECT o.id, o.amount, u.name FROM orders o JOIN users u ON o.user_id u.id WHERE o.id 1000;逻辑说明users是全局表其数据在db1和db2中完全一致orders是分片表id1000落在dn1即db1。Mycat 会自动将该 SQL 拆解为先查db1.users获取u.name再查db1.orders获取订单最后在 Mycat 内存中合并结果。若返回正确数据证明跨分片 JOIN 路由正常若报错cant find table users in schema TESTDB说明users表未在schema.xml中声明为typeglobal或db1/db2中未创建该表。5.4 进阶技巧用explain查看 SQL 被如何拆解执行Mycat 提供explain命令可查看一条逻辑 SQL 最终被路由到哪些物理节点mysql explain SELECT * FROM orders WHERE id 1000; --------------------------------------------------------------------------- | DATA_NODE | SQL | --------------------------------------------------------------------------- | dn1 | SELECT * FROM orders WHERE id 1000 | --------------------------------------------------------------------------- mysql explain SELECT * FROM orders WHERE user_id 101; --------------------------------------------------------------------------- | DATA_NODE | SQL | --------------------------------------------------------------------------- | dn1 | SELECT * FROM orders WHERE user_id 101 | | dn2 | SELECT * FROM orders WHERE user_id 101 | ---------------------------------------------------------------------------参数说明第一行WHERE id1000是分片键查询精准路由到dn1第二行WHERE user_id101是非分片键查询触发全节点广播dn1和dn2都执行。这就是为什么分片键设计如此重要——它直接决定查询性能。explain结果中若出现dn1,dn2以外的节点名说明schema.xml中dataNode定义有误需立即修正。从那以后我每次上线新分片规则都强制走一遍explainshow sharding.node 物理库直查三连验证哪怕多花五分钟也比凌晨三点被报警电话叫醒强。希望帮到你。本文还有配套的精品资源点击获取
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑