TongRDS实战:从零构建MySQL高可用集群与读写分离架构
1. 项目概述从单点到集群的数据库管理跃迁最近在折腾一个内部数据中台项目数据库选型上遇到了点麻烦。我们团队之前一直用某款开源数据库但随着业务量上来高可用和弹性扩展的需求越来越迫切手动搭建和维护主从复制、读写分离这套东西不仅运维成本高出问题时切换也手忙脚乱。正好听圈内朋友聊起国产的分布式关系型数据库中间件其中TongRDS被提到的频率不低它主打的就是对MySQL生态的透明兼容和自动化集群管理听起来像是能解决我们痛点的那把钥匙。于是我决定花点时间从零开始走一遍TongRDS的安装和集群模式配置把整个过程和踩过的坑记录下来。如果你也在寻找一种能简化MySQL集群管理、提升数据库服务可靠性的方案那么这篇基于实战的总结或许能给你提供一个清晰的参考路线图。简单来说TongRDS可以理解为一个“数据库集群的智能调度管家”。它本身不存储数据而是站在应用和底层多个MySQL数据库实例之间负责SQL的解析、路由、分发以及结果集的合并。对于应用程序而言连接TongRDS就像连接一个单一的MySQL数据库完全无需感知背后是单实例还是一主多从的复杂集群。这对于那些希望快速获得分库分表、读写分离、故障自动切换等能力但又不想大规模重构应用代码的团队来说吸引力很大。本次实践的目标很明确在一组测试服务器上完成TongRDS基础服务的安装并配置一个最小化的高可用集群模式验证其核心功能。2. 环境规划与前期准备2.1 硬件与网络架构设计在真正动手安装之前合理的环境规划是避免后续一堆麻烦事的基础。我这次用了三台虚拟机来模拟生产环境配置均为4核CPU、8GB内存、100GB SSD硬盘操作系统统一为CentOS 7.9。这三台机器将扮演不同的角色TongRDS管理节点10.0.0.10这是整个集群的大脑负责存储集群的元数据如分片规则、数据源信息、路由规则等并提供Web管理界面。理论上它也可以和某个数据节点部署在一起但为了高可用和职责清晰我强烈建议将其独立部署。MySQL主节点10.0.0.11作为某个数据分片Shard的写入节点承担所有的写操作和部分读操作。MySQL从节点10.0.0.12作为上述主节点的同步副本通过MySQL原生的主从复制Replication同步数据承担读操作实现读写分离和故障备份。网络方面确保这三台机器之间防火墙规则开放能够互相通过IP地址访问特别是需要开放TongRDS服务端口默认8066用于应用连接9066用于管理以及MySQL服务端口默认3306。可以使用telnet或nc命令预先测试连通性。注意生产环境中管理节点和数据节点应部署在不同的物理机或云主机上以避免硬件故障导致“大脑”和“数据”同时丢失。网络延迟也需要重点评估尽量保证集群内节点处于同一个低延迟的网络区域如同一个可用区。2.2 软件依赖与系统配置TongRDS的运行依赖于Java环境。我选择安装OpenJDK 8因为这是经过广泛验证的稳定版本。在三台机器上统一执行以下步骤# 1. 检查是否已安装旧版本Java java -version # 2. 安装OpenJDK 8 yum install -y java-1.8.0-openjdk java-1.8.0-openjdk-devel # 3. 验证安装 java -version # 应输出类似openjdk version 1.8.0_392接下来是MySQL的安装与基础配置。在10.0.0.11和10.0.0.12上我们需要安装MySQL 5.7或8.0。这里以MySQL 5.7为例# 1. 下载并安装MySQL Yum仓库 wget https://dev.mysql.com/get/mysql57-community-release-el7-11.noarch.rpm rpm -ivh mysql57-community-release-el7-11.noarch.rpm # 2. 安装MySQL服务器 yum install -y mysql-community-server # 3. 启动MySQL并设置开机自启 systemctl start mysqld systemctl enable mysqld # 4. 获取初始临时密码 grep temporary password /var/log/mysqld.log # 5. 运行安全配置向导修改root密码并完成基础设置 mysql_secure_installation在运行安全配置向导时除了设置强密码务必确保允许远程连接根据提示选择因为TongRDS节点需要通过网络访问MySQL。2.3 配置MySQL主从复制这是构建TongRDS读写分离集群的底层基础。原理是主库10.0.0.11将数据变更写入二进制日志binlog从库10.0.0.12读取这些日志并重放从而实现数据同步。在主库10.0.0.11上的操作编辑MySQL配置文件/etc/my.cnf在[mysqld]段落下添加server-id 11 # 唯一ID主从不能相同 log-bin mysql-bin # 开启二进制日志 binlog-format ROW # 推荐使用ROW格式数据一致性更好 expire_logs_days 7 # 日志保留天数重启MySQL服务systemctl restart mysqld。登录MySQL创建用于复制的账号并授权CREATE USER repl10.0.0.% IDENTIFIED BY YourStrongPassword123!; GRANT REPLICATION SLAVE ON *.* TO repl10.0.0.%; FLUSH PRIVILEGES;查看主库状态记录下File和Position的值后面配置从库会用到SHOW MASTER STATUS;在从库10.0.0.12上的操作编辑MySQL配置文件/etc/my.cnf添加server-id 12 relay-log mysql-relay-bin read_only 1 # 设置从库为只读防止误写重启MySQL服务。登录MySQL配置主从复制链路CHANGE MASTER TO MASTER_HOST10.0.0.11, MASTER_USERrepl, MASTER_PASSWORDYourStrongPassword123!, MASTER_LOG_FILEmysql-bin.000001, -- 替换为SHOW MASTER STATUS查到的File MASTER_LOG_POS154; -- 替换为SHOW MASTER STATUS查到的Position START SLAVE;检查从库复制状态确保Slave_IO_Running和Slave_SQL_Running都是YesSHOW SLAVE STATUS\G至此一个基础的MySQL一主一从复制环境就搭建完成了。这是TongRDS后端数据存储的高可用基础。3. TongRDS核心组件安装详解3.1 获取安装包与目录规划TongRDS的安装包通常可以从其官方网站或指定的社区渠道获得。我下载的是tongrds-server-x.x.x.tar.gz这样的压缩包。将安装包上传到管理节点10.0.0.10的/opt目录下。在解压前先规划好目录结构是个好习惯。我倾向于将软件安装在/usr/local下将数据、日志等放在/data下这样便于管理和备份。# 在管理节点上操作 cd /opt tar -zxvf tongrds-server-x.x.x.tar.gz -C /usr/local/ cd /usr/local ln -s tongrds-server-x.x.x tongrds # 创建软链接方便版本管理和路径引用 mkdir -p /data/tongrds/logs /data/tongrds/data # 创建数据和日志目录解压后的目录通常包含以下关键内容bin/启动、停止等管理脚本。conf/所有配置文件存放处这是接下来要重点修改的地方。lib/运行所需的Jar包。logs/初始可能为空日志文件目录我们可以将其指向刚才创建的/data/tongrds/logs。3.2 核心配置文件解析与定制TongRDS的配置主要集中在conf/目录下的几个文件中。我们需要根据我们的集群规划来修改它们。1.server.xml- 定义TongRDS服务本身这个文件定义了TongRDS运行的系统参数。关键配置项包括system property nameserverPort8066/property !-- 应用连接端口 -- property namemanagerPort9066/property !-- 管理端口 -- property namebindIp0.0.0.0/property !-- 监听所有IP -- property namecharsetutf8mb4/property !-- 连接字符集 -- !-- 指定数据目录和日志目录指向我们规划的路径 -- property namedataDir/data/tongrds/data/property property namelogDir/data/tongrds/logs/property /system2.schema.xml- 定义逻辑库、表、数据节点与分片规则这是最核心的配置文件它描述了TongRDS的逻辑视图和物理存储的映射关系。我们需要定义一个逻辑库schema并关联到我们的物理MySQL主从节点。?xml version1.0 encodingUTF-8? !DOCTYPE dble:schema SYSTEM schema.dtd dble:schema xmlns:dblehttp://dble.cloud/ !-- 1. 定义一个逻辑库应用将连接这个库 -- schema nametest_db checkSQLschematrue sqlMaxLimit100 !-- 2. 定义逻辑表这里先定义一个不分片的表 -- table nameuser primaryKeyid dataNodedn1 / !-- 后续可以在这里添加分片表并指定分片规则rule -- /schema !-- 3. 定义数据节点dataNode它是逻辑分片和物理数据库的桥梁 -- dataNode namedn1 dataHosthost1 databasephysical_db / !-- 4. 定义数据主机dataHost描述一组提供相同服务的物理MySQL实例如主从 -- dataHost namehost1 maxCon100 minCon10 balance1 writeType0 dbTypemysql dbDriverjdbc switchType2 slaveThreshold100 !-- 心跳检测SQL用于判断数据库是否存活 -- heartbeatselect user()/heartbeat !-- 写实例主库 -- writeHost hostmaster1 urljdbc:mysql://10.0.0.11:3306 usertongrds_user passwordSecurePass456! !-- 读实例从库 -- readHost hostslave1 urljdbc:mysql://10.0.0.12:3306 usertongrds_user passwordSecurePass456!/ /writeHost !-- 可以配置另一个writeHost作为备用主库实现高可用 -- /dataHost /dble:schema关键参数解析balance负载均衡模式。0不开启读写分离。1所有读操作随机发送到所有readHost和备用的writeHost。2所有读操作随机发送到所有readHost。3所有读操作只发送到writeHost即主库。 我们设置为1意味着在正常情况下写走主库读会随机分发到从库或主库当从库不可用时。switchType主从切换模式。-1不自动切换。1基于心跳自动切换推荐。2基于MySQL主从同步状态自动切换更精确但需要MySQL Grant权限。 我们设置为2可以更精准地判断从库的复制延迟。slaveThreshold从库延迟阈值单位秒。当主从延迟超过此值时该从库将被视为不可用不会接收读请求。3.rule.xml- 定义分片算法可选如果业务表需要水平分片分库分表就需要在此文件定义分片规则。例如按用户ID的哈希值分到4个数据节点上。由于我们初次配置以集群高可用为主暂不涉及复杂分片此文件可以保持默认或简单了解。4. 创建数据库与用户在配置文件中我们指定了连接用户tongrds_user。需要分别在主库10.0.0.11和从库10.0.0.12上创建这个用户和逻辑库。-- 在主库上执行操作会自动复制到从库 CREATE DATABASE IF NOT EXISTS physical_db DEFAULT CHARSET utf8mb4 COLLATE utf8mb4_general_ci; CREATE USER tongrds_user10.0.0.% IDENTIFIED BY SecurePass456!; GRANT ALL PRIVILEGES ON physical_db.* TO tongrds_user10.0.0.%; FLUSH PRIVILEGES;3.3 服务启动与初始验证所有配置文件修改无误后就可以启动TongRDS服务了。cd /usr/local/tongrds/bin ./startup.sh # 或 ./dble start查看启动日志确认没有错误tail -f /data/tongrds/logs/wrapper.log # 看到类似 “Server startup successfully. port:8066” 的日志即表示启动成功。基础功能验证连接测试使用MySQL客户端直接连接TongRDS注意端口是8066。mysql -h10.0.0.10 -P8066 -utongrds_user -pSecurePass456!能成功登录并看到test_db这个逻辑库说明TongRDS服务运行正常。管理界面访问TongRDS提供了一个Web管理界面端口9066。在浏览器访问http://10.0.0.10:9066使用默认管理员账号通常在conf/user.xml中配置默认为root/123456登录。在这里可以直观地查看数据源状态、连接数、慢查询等比命令行更友好。4. 集群模式配置与高可用验证4.1 读写分离功能验证现在我们已经有了一个“看起来”是单点但背后实则是主从集群的数据库服务。接下来验证读写分离是否生效。在TongRDS的逻辑库test_db中创建一张测试表。USE test_db; CREATE TABLE test_read_write ( id INT PRIMARY KEY AUTO_INCREMENT, data VARCHAR(100), create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP );验证写操作执行插入语句数据应该被写入主库10.0.0.11。INSERT INTO test_read_write (data) VALUES (Write test from TongRDS);登录主库的physical_db库确认数据已存在。验证读操作这是关键。由于我们配置了balance”1″读请求会随机发往从库或主库。为了观察我们可以临时打开TongRDS的SQL日志在log4j2.xml中配置或者更直接地在从库10.0.0.12上开启MySQL的通用查询日志。-- 在从库MySQL中执行 SET GLOBAL general_log ON; SET GLOBAL log_output TABLE; -- 日志存到mysql.general_log表然后从应用端或通过TongRDS连接执行多次查询SELECT * FROM test_read_write;之后查看从库的mysql.general_log表如果能看到这些SELECT语句的记录就证明读写分离成功读请求被路由到了从库。4.2 模拟故障与自动切换高可用的核心价值在于应对故障。我们来模拟主库宕机看TongRDS能否自动将写流量切换到从库提升为主。初始状态在TongRDS管理界面或通过SHOW DATASOURCE;命令在TongRDS的管理端口9066连接后执行查看数据源状态host1的writeHost应为master1状态为up。制造故障在主库10.0.0.11上粗暴地停止MySQL服务。systemctl stop mysqld观察切换心跳检测TongRDS会通过配置的heartbeatSQL持续检测writeHost。默认几秒内检测失败就会触发故障判断。自动切换由于我们配置了switchType”2″TongRDS会检查readHostslave1的复制状态。如果slave1的Slave_IO_Running和Slave_SQL_Running都是Yes且延迟在阈值内它就会将slave1提升为新的writeHost。再次执行SHOW DATASOURCE;你会看到master1的状态变为down而slave1的状态可能变为write或up具体状态名取决于版本。此时新的写操作将会发往10.0.0.12。恢复与回切将原主库10.0.0.11的MySQL服务恢复并将其配置为当前新主库10.0.0.12的从库。在TongRDS中原主库会作为readHost重新加入集群。一些更高级的配置或管理命令可以支持在旧主库恢复后手动或自动将其切换回写库角色。实操心得自动切换在生产环境中是一把双刃剑。它带来了高可用但也可能因为网络抖动等短暂问题导致不必要的切换脑裂风险。因此合理设置心跳超时时间heartbeatTimeout、切换触发条件switchType和延迟阈值slaveThreshold至关重要。建议在测试环境中充分模拟各种故障场景观察系统的行为是否符合预期。4.3 集群扩展性思考我们目前配置的是最基本的一主一从集群。TongRDS的强大之处在于它可以轻松扩展这个模式一主多从在同一个writeHost下添加多个readHost标签即可轻松扩展读能力应对读多写少的场景。多数据分片Sharding在schema.xml中定义多个dataNode和dataHost并为表配置分片规则在rule.xml中定义即可实现数据的水平拆分。例如将用户表按ID范围分到4个不同的主从集群上。管理节点高可用当前的TongRDS管理节点10.0.0.10是单点。生产环境需要考虑其高可用可以采用ZooKeeper来管理TongRDS集群的元数据实现多个TongRDS实例的协调和主备切换。5. 生产环境部署注意事项与优化建议经过测试环境的折腾把TongRDS搬到生产环境有几个坑需要提前绕开一些优化点也值得关注。5.1 安全加固配置清单安全无小事尤其是数据库中间件这种核心组件。修改默认密码安装后第一件事就是修改Web管理界面user.xml和连接后端MySQL的账号密码。不要使用任何默认密码或弱密码。网络访问控制在防火墙层面严格限制对TongRDS端口8066 9066的访问。只允许应用服务器IP段连接8066端口只允许运维管理终端IP访问9066管理端口。权限最小化为TongRDS连接后端MySQL创建的账号如tongrds_user只需授予其业务库的SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER等必要权限避免使用ALL PRIVILEGES。加密连接如果条件允许配置TongRDS与应用程序之间、TongRDS与MySQL之间的SSL/TLS加密连接防止数据在传输过程中被窃听。审计日志开启TongRDS的SQL审计日志记录所有经过的SQL语句便于事后审计和安全分析。注意日志文件的权限和定期归档避免磁盘被撑满。5.2 性能调优关键参数默认配置适合起步但压测和上线前需要根据实际硬件和业务模式进行调优。连接池配置server.xml 或 schema.xmlmaxCon/minCon每个dataHost的最大和最小连接数。设置太小会导致连接不足太大则浪费资源。建议初始值可以设为maxCon200minCon20再根据监控观察实际使用峰值进行调整。processorExecutor业务处理线程数。通常设置为CPU核心数的2-4倍。JVM参数调整wrapper.conf 或 startup脚本-Xmx/-Xms堆内存大小。建议设置为系统可用内存的60%-70%且-Xmx和-Xms设成相同值避免运行时动态调整引发GC停顿。例如8G内存的机器可以设置-Xms4g -Xmx4g。-XX:UseG1GC启用G1垃圾收集器通常比默认的Parallel GC在延迟上表现更好适合对响应时间敏感的服务。MySQL侧优化TongRDS的性能瓶颈最终会落到MySQL上。确保MySQL本身配置合理如innodb_buffer_pool_size、连接数等并且主从复制的延迟要控制在可接受范围内。5.3 监控与运维体系搭建“无监控不运维”。对于TongRDS集群需要建立立体化的监控。TongRDS自身监控管理界面定期查看连接数、QPS、响应时间、数据源状态等。JMX如果TongRDS开启了JMX可以接入Prometheus Grafana定制更丰富的监控仪表盘。日志监控重点监控wrapper.log服务状态和slow.log慢查询日志。使用ELK或LokiGranfana收集分析慢查询找出性能瓶颈。底层MySQL监控使用Percona Monitoring and Management (PMM)、Prometheus mysqld_exporter 等工具监控MySQL的CPU、内存、IO、复制延迟、锁等待等关键指标。告警基于上述监控数据设置关键告警如TongRDS服务宕机、MySQL主从复制中断、复制延迟超过阈值、连接数耗尽、慢查询比例过高等。5.4 备份与恢复策略TongRDS本身不存储业务数据数据都在后端的MySQL节点上。因此备份恢复策略主要针对MySQL。物理备份对于大数据量物理备份如Percona XtraBackup效率更高。可以在每个从库上定期进行全量备份和增量备份。逻辑备份对于数据量不大或需要跨版本迁移的情况可以使用mysqldump。重要提示由于数据可能被分片你需要从TongRDS的逻辑库视角导出或者分别从每个物理分片导出后再合并。从TongRDS导出更简单但可能因为数据路由导致导出过程较慢。恢复演练定期进行恢复演练至关重要。模拟某个数据节点完全损坏从备份中恢复数据并重新接入TongRDS集群确保整个流程是通畅的。6. 常见问题与故障排查实录在实际操作和后期维护中总会遇到一些意想不到的问题。我把这次搭建和后续测试中遇到的一些典型问题及解决方法整理出来希望能帮你节省时间。6.1 安装启动类问题问题1启动TongRDS时日志报错Address already in use。原因8066或9066端口被其他进程占用。排查使用netstat -tlnp | grep :8066命令查看占用端口的进程。解决停止冲突进程或修改server.xml中的serverPort/managerPort为其他端口。问题2连接TongRDS成功但执行任何SQL都报错Unknown database ‘test_db’。原因schema.xml中配置的逻辑库名test_db在TongRDS中未正确加载或者配置有误。排查检查schema.xml文件语法是否正确特别是标签闭合和属性值引号。登录TongRDS管理端口9066执行show schema;命令看是否列出了test_db。查看TongRDS启动日志是否有加载schema相关的错误。解决修正schema.xml配置并重启TongRDS服务。重启后再次检查show schema;。6.2 集群与复制类问题问题3读写分离不生效所有查询都走到了主库。原因配置文件中balance参数设置为0或3。事务内的所有读操作。默认情况下为了保持事务内的读一致性在一个写事务显式或隐式中所有的读操作也会被路由到写库。从库readHost状态为downTongRDS无法向其路由读请求。排查与解决确认balance”1″。检查业务代码是否在查询前开启了事务如Transactional。对于不要求强一致性的读可以尝试将查询放在事务外或使用TongRDS提供的Hint语法强制走从库如/*!dble:balance2*/ SELECT ...。在TongRDS管理界面或通过show datasource;命令检查所有readHost的状态是否为up。问题4主库宕机后自动切换失败或切换时间过长。原因心跳检测间隔heartbeatPeriod或超时时间heartbeatTimeout设置过长。switchType设置不当。例如设置为-1不切换。从库复制延迟过大超过了slaveThreshold阈值被认为不健康无法提升为主。排查与解决适当调小心跳间隔如1000毫秒和超时时间如5000毫秒但要注意避免因网络抖动导致的误切换。确认switchType”1″或”2″。监控从库的复制延迟SHOW SLAVE STATUS中的Seconds_Behind_Master确保其保持在阈值以下。优化主从复制的网络和MySQL配置以减少延迟。6.3 性能与SQL类问题问题5通过TongRDS执行查询比直连MySQL慢很多。原因额外的网络跳转SQL需要经过TongRDS解析和转发增加了一轮网络延迟。结果集合并对于分片表TongRDS需要从多个节点获取数据并在内存中合并、排序如果数据量大或SQL复杂开销显著。慢查询SQL本身效率低下在TongRDS和MySQL两层都被记录为慢查询。排查与解决这是引入中间件的固有开销需评估是否在可接受范围内。确保TongRDS与MySQL之间的网络质量。检查是否为分片表查询。优化分片查询尽量避免全分片扫描如不带分片键的条件。使用EXPLAIN命令查看TongRDS的路由计划。分析TongRDS的slow.log和MySQL的慢查询日志找到真正的慢SQL并进行优化如添加索引、重构查询。问题6某些特定SQL语句如存储过程调用、LOCK TABLE执行报错或不支持。原因TongRDS并非100%兼容所有MySQL语法和功能尤其是一些服务端功能如存储过程、自定义函数、某些全局锁和跨分片的复杂操作如跨分片事务的强一致性、全局自增序列的严格连续。解决查阅TongRDS的官方文档确认其功能支持列表。对于不支持的SQL考虑业务改造。例如将存储过程逻辑移到应用层避免使用需要全局锁的操作。对于必须使用但TongRDS不支持的功能可以考虑将该表设置为非分片表全局表或者通过Hint强制将SQL下发到某个特定数据节点执行。整个流程走下来TongRDS确实大大简化了MySQL集群的管理复杂度让应用层可以像使用单点数据库一样使用一个高可用的集群。它的价值在数据量和访问量增长到一定阶段后会更加凸显。不过它也引入了新的组件和复杂性对运维人员的要求从单纯的MySQL DBA提升到了需要对中间件原理、网络、JVM都有一定了解的层面。我的建议是在上生产之前务必在测试环境完成完整的故障演练、压力测试和恢复流程验证摸清它的脾气制定好应急预案这样才能在真正出问题时心里不慌。