在过去两年里,外贸赋能中心的业务体量经历了多轮快速扩张,从最初支撑单一业务线的订单数据,逐步演变为承载客户画像、商品目录、报价体系、关务数据、物流轨迹等多维数据的核心平台。伴随业务边界不断拓宽,原有的 MySQL 分库分表架构开始频繁暴露出运维成本和扩展性方面的问题:数据迁移周期长、容量预估困难、大促或业务波峰时段容易出现连接打满和慢查询,研发团队需要投入大量精力处理底层数据路由和扩容节奏,业务侧却仍然感受不到查询性能的提升。
在重新审视整体数据架构的过程中,我们评估了多种技术方案,最终决定引入 TiDB 作为新的数据底座。选择 TiDB 的核心原因并不是因为它“新”或“热门”,而是因为它同时解决了我们在弹性扩展、MySQL 生态兼容、分布式事务和高可用方面最迫切的几个痛点。本文将以这次外贸赋能中心数据架构迭代为背景,完整拆解我们为什么选择 TiDB、如何规划部署、数据迁移怎么做、应用层如何平滑接入,以及弹性扩缩容和日常运维中的最佳实践。无论你是在做电商、外贸、金融还是物联网业务的数据底座选型,只要正面临 MySQL 扩容瓶颈或分布式数据库选型问题,这篇文章都值得你花十分钟读完。
1. 背景与核心概念
1.1 外贸赋能中心的数据业务特征
外贸赋能中心本质上是一个面向外贸业务全链路提供数据服务和业务支撑的平台。它的数据特征和普通互联网应用有明显区别。
第一,业务数据维度多、关系复杂。一个外贸订单往往关联供应商、采购商、货代、报关行、仓库、运输批次等多个参与方,数据模型天然具备多对多关系。传统做法是将这些关系通过大量的关联表和外键表达,但这在分布式数据库场景下容易成为性能瓶颈。
第二,读写模式存在明显的周期性波峰。外贸行业受海外市场节假日、大促活动、汇率波动等因素影响,业务流量往往在特定时间段内集中爆发。例如黑色星期五、圣诞备货季、海外仓补货周期等节点,查询和写入量可能是平时的 3 到 5 倍。这种流量特征要求底层数据架构必须具备快速的弹性伸缩能力,而不是提前数月做容量预估。
第三,数据一致性要求高。报价、库存、订单状态、关务申报等数据一旦出错,直接影响业务合规和资金安全。因此,像“分库分表后跨节点事务失效”这类问题在外贸场景中是绝对不可接受的。
第四,分析查询与事务处理并存。业务部门既要在交易链路上做高频的点查和短事务,又需要运营团队对历史订单、商品表现、区域销量做多维分析。传统架构通常需要把 OLTP 和 OLAP 拆成两套系统,再通过数据同步链路连接,链路越长,数据延迟和出错概率越高。
在这样的背景下,我们原有的 MySQL 分库分表方案虽然勉强支撑了业务发展,但已经出现明显吃力。分库分表方案中的数据路由规则、分布式主键、跨库查询、全局表管理等问题,每一项都在消耗研发资源,而且随着业务复杂度上升,问题会越来越严重。
1.2 什么是数据弹性,为什么外贸业务需要它
“数据弹性”这个词在数据库领域并没有一个绝对统一的标准定义。结合我们的实践,我把它理解为:数据库系统能够根据业务负载的变化,动态调整计算资源和存储资源,且整个过程不需要中断业务,也不需要人工介入大量数据迁移工作。
数据弹性包含两个维度:
- 垂直弹性:单机配置的升降级,例如 CPU、内存扩容。MySQL 的垂直扩容有一定作用,但存在硬件上限,且扩容期间往往需要重启实例。
- 水平弹性:通过增加或减少节点来线性提升系统整体能力。这是分布式数据库的核心能力,也是解决大数据量、高并发场景的根本手段。
外贸赋能中心的业务特征决定了它需要的是“水平弹性”。因为业务峰值通常难以精确预测,如果按照峰值容量采购硬件,日常运行会产生巨大浪费;如果按照平均值采购,峰值时段又会服务降级。TiDB 的分布式架构天然支持水平扩缩容,可以在业务低峰期缩容节省成本,在业务高峰期快速扩容保障稳定,这正是我们选择它作为新底座的关键原因。
这里也要澄清一个容易混淆的概念:数据弹性不是“自动伸缩”。自动伸缩通常指通过监控指标触发 K8s 或云平台的自动扩容动作,而 TiDB 提供的是“可以弹性伸缩的底层能力”——扩容和缩容的命令、数据再平衡的机制、对业务透明的影响范围。是否实现自动触发,还需要结合你自己的监控告警和运维平台来实现。
1.3 TiDB 在架构迭代中的定位
在引入 TiDB 之前,我们内部也做过一轮技术预研,对比了包括 ShardingSphere + MySQL、CockroachDB、OceanBase、TiDB 在内的多种方案。最终选择 TiDB,主要看中四点:
- MySQL 协议兼容:应用层可以最小化改造,DBA 和开发人员的学习成本低。
- 分布式事务支持:不需要像分库分表那样在业务层处理分布式事务问题。
- 原生水平扩展能力:通过增加 TiDB Server 节点和 TiKV 节点即可线性扩展,业务无感知。
- 混合负载能力:TiDB 和 TiFlash 的结合,让同一份数据既能做事务处理,又能跑分析查询,减少冗余数据链路。
在我们的新架构中,TiDB 承担的是“统一数据底座”的职责。订单、商品、客户、库存、报价等核心业务数据统一存放在 TiDB,应用层通过标准 MySQL 协议访问。部分非核心的日志数据和离线分析数据仍然保留在原有的大数据体系中,通过数据同步任务定时沉淀到数仓。这样的设计既让核心链路获得分布式能力,又不至于把所有类型的存储需求都堆在 TiDB 上。
2. 环境准备与版本说明
2.1 部署架构规划
TiDB 集群的部署架构和传统 MySQL 主从架构有很大区别。一个完整的 TiDB 集群至少包含以下三类组件:
- TiDB Server:负责 SQL 解析、优化、执行,是无状态计算节点,可以水平扩展。
- TiKV:负责分布式事务 KV 存储,数据自动分片为 Region,是存储节点。
- PD(Placement Driver):负责集群元信息管理、Region 调度、时间戳分配,是整个集群的“大脑”。
另外,如果业务需要 HTAP 能力,可以额外部署 TiFlash 列存节点,用于承载分析型查询。我们最初没有直接部署 TiFlash,是在上线后业务分析需求增加时才补充的,这里建议如果你已经有明确的 OLAP 需求,可以在规划阶段就把 TiFlash 纳入部署范围,避免后续增加节点时的数据同步压力。
2.2 版本与硬件建议
TiDB 的版本迭代速度较快,不同版本在部署方式和功能特性上存在差异。本文写作时的常见部署方式是使用 TiUP 工具,它支持一键部署、扩缩容、升级等操作。版本需要根据你的项目实际情况调整,本文示例以常见环境为例,重点演示配置思路。
硬件方面,结合外贸业务中等规模数据量的实际情况,建议按以下标准做初始规划:
| 组件 | 节点数 | 配置建议 | 说明 |
|---|---|---|---|
| TiDB Server | 2 或 3 | 16C32G | 无状态计算节点,可通过负载均衡对外提供服务 |
| TiKV | 3 | 16C64G + SSD | 至少 3 节点,建议 5 节点起步以获得更好稳定性 |
| PD | 3 | 8C16G | 奇数节点,建议 3 节点部署 |
| TiFlash(可选) | 1 或 2 | 16C64G + SSD | 根据分析查询需求决定 |
操作系统建议使用 CentOS 7.9、Rocky Linux 8 或 Ubuntu 20.04+,文件系统推荐 ext4 或 xfs,TiKV 节点必须使用 SSD。需要强调的是,TiKV 是 IO 敏感型组件,机械硬盘或低性能云盘会严重影响写入性能。
2.3 环境初始化
在正式部署前,需要对所有服务器做一些基础初始化操作,主要包括关闭防火墙或放通端口、配置时间同步、调整系统文件句柄数、关闭 swap 或合理配置 swappiness。
TiDB 集群需要放通以下端口:
- TiDB Server:4000(客户端连接)、10080(状态端口)
- TiKV:20160
- PD:2379(客户端)、2380(集群通信)
- TiFlash:3930(TCP 通信)、20170(复制监听)
初始化脚本的核心部分如下:
# 调整系统参数 cat >> /etc/sysctl.conf <<EOF fs.file-max = 1000000 net.core.somaxconn = 32768 net.ipv4.tcp_tw_reuse = 1 vm.swappiness = 0 EOF sysctl -p # 调整文件句柄数 cat >> /etc/security/limits.conf <<EOF * soft nofile 1048576 * hard nofile 1048576 root soft nofile 1048576 root hard nofile 1048576 EOF # 配置时间同步 yum install -y chrony systemctl enable chronyd systemctl start chronyd chronyc sources -v这些基础配置对于 TiDB 集群的长期稳定运行非常重要。文件句柄数不足会导致高并发下连接异常,swap 配置不当会引起 TiKV 性能抖动,时间不同步则会导致 PD 分配的时间戳出现偏差,从而引发分布式事务异常。
2.4 使用 TiUP 部署集群
TiUP 是 TiDB 官方提供的集群运维工具,类似于 Kubernetes 领域的 kubectl。通过 TiUP,可以完成集群部署、扩缩容、升级、销毁等操作。
首先在中控机上安装 TiUP:
curl --proto '=https' --tlsv1.2 -sSf https://tiup-mirrors.pingcap.com/install.sh | sh source ~/.bashrc然后编写集群拓扑文件,下面是一个最小拓扑示例:
# 文件路径:topology.yaml global: user: "tidb" ssh_port: 22 deploy_dir: "/tidb-deploy" data_dir: "/tidb-data" arch: "amd64" os: "linux" pd_servers: - host: 10.0.1.11 - host: 10.0.1.12 - host: 10.0.1.13 tidb_servers: - host: 10.0.1.21 - host: 10.0.1.22 tikv_servers: - host: 10.0.1.31 - host: 10.0.1.32 - host: 10.0.1.33 monitoring_servers: - host: 10.0.1.41 grafana_servers: - host: 10.0.1.41 alertmanager_servers: - host: 10.0.1.41执行部署命令:
tiup cluster deploy tidb-test v8.1.0 ./topology.yaml --user root -p tiup cluster start tidb-test tiup cluster display tidb-test部署完成后,可以通过 MySQL 客户端连接 TiDB 验证集群状态:
mysql -h 10.0.1.21 -P 4000 -u root -p登录后执行:
SHOW DATABASES; SELECT * FROM information_schema.cluster_info;如果能看到集群中所有组件的信息,说明 TiDB 集群已经成功运行。
3. 核心原理拆解:TiDB 的数据弹性从何而来
3.1 整体架构:计算与存储分离
理解 TiDB 的数据弹性,首先要理解它的架构设计。TiDB 采用了典型的计算与存储分离架构:TiDB Server 负责 SQL 层,TiKV 负责存储层,PD 负责调度管理。
这种架构带来的最直接好处是:计算节点和存储节点可以独立扩展。当业务并发升高时,增加 TiDB Server 节点即可提升 SQL 处理能力;当数据量增大或写入压力升高时,增加 TiKV 节点即可提升存储容量和写入吞吐。两者互不干扰,也不需要对现有节点做数据搬迁。
对比之下,MySQL 分库分表方案的水平扩展非常痛苦。每次扩容都需要重新评估数据分布规则,迁移大量数据,修改路由配置,风险很高。TiDB 的扩缩容操作对应用透明,数据自动重新平衡,这是质的区别。
3.2 Region:数据弹性的最小单元
TiKV 存储层并不是把数据简单地按行或按表存储,而是将数据划分为多个 Region。每个 Region 是数据的一个连续片段,默认容量约 96MB,内部按照 Key 范围有序排列。
当某个 Region 的数据量超过阈值时,它会自动分裂成两个更小的 Region;当集群中某个 TiKV 节点的负载明显高于其他节点时,PD 会自动将一部分 Region 调度到低负载节点。这套机制就是 TiDB 数据弹性的底层基础。
“Region 自动分裂 + 调度”听起来很抽象,我们可以类比一下:想象一个大仓库,货架之间空间分布不均,有些货架快满了,有些还很空。Region 分裂相当于把快满的货架拆成两个,调度相当于把货物搬到空货架上。整个过程不需要关仓库门,顾客随时可以进来取货。
实际业务中,我们不需要关心 Region 的具体数量和管理细节,但理解 Region 机制对下面几个决策很有帮助:
- 为什么 TiKV 节点建议至少 3 个?因为 Region 默认保存 3 个副本,少于 3 个节点会限制调度能力。
- 为什么 TiKV 扩容后性能不会立刻提升?因为数据从旧节点迁移到新节点需要时间,PD 会控制调度速度。
- 为什么小表也可能产生大量 Region?频繁写入的热点表也可能触发 Region 分裂,这对设计表结构有影响。
3.3 PD 调度:集群的自动化运维大脑
PD 是整个集群的调度中心,维护了 Region 的分布、副本状态、负载信息等元数据。它的调度决策决定了数据如何分布、副本如何摆放、负载如何均衡。
PD 支持的主要调度策略包括:
- 副本调度:保证每个 Region 的副本数量满足配置要求,例如 3 副本。
- 负载均衡:将读写压力从高负载节点转移到低负载节点。
- 热点调度:识别热点 Region 并打散,避免单个 TiKV 节点成为瓶颈。
- 缩容调度:当节点下线时,将该节点的 Region 迁移到其他节点。
这些调度策略是自动执行的,但作为 DBA 或运维工程师,可以通过 PD 的调度参数控制调度速度,避免在业务高峰期大量迁移数据影响性能。例如,可以在业务低谷期适当调大调度并发数,加快数据再平衡速度;在业务高峰期调小调度并发数,减少对在线业务的影响。
# 查看当前调度参数 tiup ctl pd config show # 调整调度并发,这里以调整 store limit 为例 tiup ctl pd store limit # 设置节点级别的调度限流 tiup ctl pd store limit all 50这里需要提醒的是,调度参数调整要谨慎,建议在测试环境验证后再修改生产配置。
3.4 与 MySQL 生态的兼容性
TiDB 最吸引 MySQL 团队的一点就是生态兼容性。它支持 MySQL 协议,兼容绝大部分 MySQL 语法,这意味着已有的 MySQL 驱动、ORM 框架、监控工具都能直接使用。
具体来说:
- 连接方式:使用 MySQL 客户端、JDBC、Go MySQL Driver、Python PyMySQL 等都可以直接连接 TiDB。
- SQL 语法:支持大部分 MySQL DDL、DML 语法,包括事务、索引、视图、存储过程(部分支持)。
- 数据迁移:官方提供 DM(Data Migration)工具,可以将 MySQL/MariaDB 数据平滑迁移到 TiDB。
- 数据同步:TiDB Binlog 可以将 TiDB 的数据变更实时同步到下游 MySQL、Kafka 等系统。
这让外贸赋能中心的应用改造工作量大为降低。原本基于 MySQL 的 MyBatis、MyBatis-Plus、Spring Data JPA 等框架几乎不需要修改 SQL,只需要调整数据源连接配置。当然,也有一些 MySQL 特性 TiDB 并不完全支持,例如外键约束的支持力度有限,全文索引实现方式不同,分区表语法和 MySQL 有差异。这些问题我们在实战改造时要注意规避。
4. 完整实战案例:从 MySQL 迁移到 TiDB 全流程
4.1 迁移前评估与容量规划
在正式启动迁移前,我们花了大约两周时间做迁移评估。这部分工作如果省略,后面大概率会踩坑。
评估内容主要包括以下几个方面:
- 实例清单梳理:统计所有需要迁移的 MySQL 实例、库表数量、数据总量、每日新增数据量。
- 访问方式盘点:梳理应用连接 MySQL 的方式,包括连接池配置、读写分离逻辑、依赖的 SQL 特性。
- 特殊 SQL 审计:找出含有 MySQL 特有语法、存储过程、触发器的 SQL,评估改造方案。
- 容量规划:根据业务增长预估 TiDB 集群需要的存储容量和 QPS 能力,推算 TiKV 节点数量。
容量规划方面,我们使用的经验公式是:
- 单 TiKV 节点的有效存储约为磁盘容量的一半(考虑 3 副本、RocksDB 压缩、空间预留)。
- 例如单节点 2TB SSD,3 节点集群的有效存储约为 2TB × 3 / 3 = 2TB(约一半预留)。
- 估算时建议预留未来 12 个月的增长空间,同时留出 20% 的余量。
以一个数据量为 5TB、日增约 20GB 的业务为例,12 个月后数据量约为 12TB,加上余量按照 15TB 规划,需要 TiKV 有效存储不低于 15TB。单节点有效存储约 1TB,则需要至少 15 个 TiKV 节点的存储空间,但考虑到写入吞吐和热点问题,实际部署建议不少于 5 个 TiKV 节点,再结合数据量选择更高容量的磁盘。
4.2 使用 DM 完成全量 + 增量数据迁移
TiDB 官方提供了 DM(Data Migration)工具,专门用于从 MySQL 迁移数据到 TiDB。它支持全量数据导入和增量 Binlog 同步,可以在业务不停机的情况下完成迁移。
DM 的核心组件是 DM-worker 和 DM-master。DM-worker 负责执行数据迁移任务,DM-master 负责管理调度。我们需要在一台服务器上部署 DM 集群,然后配置迁移任务。
配置文件分为两部分:source(数据源配置)和 task(迁移任务配置)。
数据源配置:
# 文件路径:mysql-source.yaml source-id: "mysql-source-01" from: host: "10.0.2.10" port: 3306 user: "dm_user" password: "xxxxxx" enable: - "relay"迁移任务配置:
# 文件路径:dm-task.yaml name: "full-incremental-task" task-mode: "all" # all 表示全量 + 增量 is-sharding: false target-database: host: "10.0.1.21" port: 4000 user: "root" password: "xxxxxx" mysql-instances: - source-id: "mysql-source-01" block-allow-list: "business-tables" route-rules: [] block-allow-list: business-tables: do-dbs: ["order_db", "product_db", "customer_db"]启动 DM 集群并创建迁移任务:
tiup dm deploy dm-test v8.1.0 ./dm-topology.yaml --user root -p tiup dm start dm-test tiup dmctl --master-addr 10.0.1.51:8261 operate-source create mysql-source.yaml tiup dmctl --master-addr 10.0.1.51:8261 start-task dm-task.yaml在迁移过程中,可以通过 dmctl 查看任务状态:
tiup dmctl --master-addr 10.0.1.51:8261 query-status full-incremental-task当全量数据导入完成且增量同步延迟接近 0 时,就可以进行应用切换。切换时只需要把应用的数据库连接地址从 MySQL 改到 TiDB,然后观察业务运行情况,确认无误后再停止 DM 增量同步任务。
4.3 应用层接入与读写路径改造
应用接入 TiDB 的改动比我们预想的要小得多。因为我们使用 Spring Boot + MyBatis-Plus 技术栈,只需要修改数据源配置文件。
改造前:
spring: datasource: url: jdbc:mysql://10.0.2.10:3306/order_db?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai username: order_app password: xxxxxx driver-class-name: com.mysql.cj.jdbc.Driver改造后:
spring: datasource: url: jdbc:mysql://10.0.1.21:4000/order_db?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true username: order_app password: xxxxxx driver-class-name: com.mysql.cj.jdbc.Driver这里需要注意一个关键配置:rewriteBatchedStatements=true。这个参数原本在 MySQL 中用于优化批量插入性能,在 TiDB 中同样重要。如果关闭,MyBatis-Plus 的批量插入会被拆成单条执行,性能会差很多。
另一个需要关注的改造点是分布式事务场景。如果你原来依赖 MySQL 的本地事务,切换到 TiDB 后本地事务依然有效。但如果你原来在分库分表中间件上使用了分布式事务(如 Seata),迁移到 TiDB 后可以考虑直接使用 TiDB 的分布式事务能力,省掉中间件层的复杂度。
4.4 弹性扩缩容实操演练
TiDB 的弹性扩缩容是架构迭代中重要的验证环节。我们在测试环境做了多次演练,确保后续生产扩容时可以顺利进行。
增加 TiDB Server 节点:
tiup cluster scale-out tidb-test ./scale-out-tidb.yaml其中 scale-out-tidb.yaml 的内容:
tidb_servers: - host: 10.0.1.23 ssh_port: 22 port: 4000 status_port: 10080 deploy_dir: "/tidb-deploy/tidb-4000" log_dir: "/tidb-deploy/tidb-4000/log"增加 TiKV 节点:
tikv_servers: - host: 10.0.1.34 ssh_port: 22 port: 20160 status_port: 20180 deploy_dir: "/tidb-deploy/tikv-20160" data_dir: "/tidb-data/tikv-20160" log_dir: "/tidb-deploy/tikv-20160/log"执行扩容命令:
tiup cluster scale-out tidb-test ./scale-out-tikv.yaml扩容后,可以通过 Grafana 或 PD 监控页面观察 Region 的调度情况。你会发现新节点加入后,数据并不会立即全部迁移过来,而是由 PD 控制调度速度逐步均衡。这个过程可能需要几小时甚至几天,具体取决于数据量和调度参数设置。
缩容操作类似:
tiup cluster scale-in tidb-test --node 10.0.1.34执行缩容命令后,PD 会先将该节点上的 Region 迁移到其他节点,然后才下线节点。这个过程对业务是透明的,但需要注意确保集群剩余节点的容量足以承接数据。
4.5 业务验证与监控体系搭建
集群部署和数据迁移完成后,不能马上宣布上线完成。我们制定了完整的业务验证清单,核心验证点包括:
- 功能验证:核心业务链路(订单创建、查询、更新、关务申报)跑通,数据正确。
- 性能验证:对比迁移前后常见查询的响应时间,确认没有出现明显的性能回退。
- 容量验证:模拟未来 12 个月数据量增长,观察集群水位。
- 高可用验证:随机重启一个 TiKV 节点,确认业务无感知。
- 容灾演练:模拟单机房故障,验证跨机房容灾能力(如果有多机房部署)。
监控体系方面,TiDB 默认部署了 Prometheus + Grafana 监控方案。我们在 Grafana 上重点关注的指标包括:
- QPS、TPS、延迟:判断整体负载。
- TiKV CPU、内存、磁盘 IO:判断存储节点健康状态。
- Region 数量与分布:判断数据均衡程度。
- 热点 Region 监控:识别读写热点。
- 慢查询日志:定位 SQL 性能问题。
- 集群错误日志:提前发现隐患。
这些监控指标我们配置了对应的告警规则,告警渠道接入了企业微信机器人,确保问题发生时能第一时间通知值班人员。
5. 常见问题与排查思路
在 TiDB 落地过程中,我们遇到了一些问题,也收集了社区里其他团队常踩的坑。下面整理成表格,方便你按图索骥。
| 问题现象 | 常见原因 | 解决思路 |
|---|---|---|
| 应用连接 TiDB 偶尔超时 | 连接池配置过小或 TiDB Server 节点负载不均 | 检查 TiDB Server 负载,调大连接池上限,确保负载均衡器配置正确 |
| 批量写入速度慢 | 缺少 rewriteBatchedStatements 参数 | 在 JDBC URL 中增加 rewriteBatchedStatements=true |
| 扩缩容后性能没有即刻提升 | Region 正在迁移,数据尚未均衡 | 观察 Region 调度进度,等待调度完成,必要时调大调度并发 |
| 单个 SQL 查询特别慢 | 缺少合适的索引,或产生大范围扫表 | 使用 EXPLAIN 分析执行计划,优化 SQL 或添加索引 |
| 磁盘占用增长过快 | TiKV 的 Region 副本比例高或数据膨胀 | 检查副本数配置,合理设置 region 大小和压缩策略 |
| 跨域或跨机房读取延迟高 | 数据副本分布在异地 | 合理规划副本放置策略,必要时使用标签和隔离级别 |
下面挑两个典型问题展开说明。
问题一:批量插入性能远低于 MySQL
我们刚接入 TiDB 时,发现批量导入数据的耗时比 MySQL 高了近一倍,排查后发现是 JDBC 连接串没有配置批处理参数。TiDB 本身对批量写入是支持的,但应用驱动默认可能把批量操作拆成单条执行。添加rewriteBatchedStatements=true后,写入性能提升约 3 倍。这个问题非常隐蔽,建议所有接入 TiDB 的 JDBC 应用都默认配置该参数。
问题二:缩容节点长时间处于下线中状态
执行缩容命令后,节点状态长时间显示为下线中。原因通常是该节点上有大量的 Region 需要迁移,而 PD 为了提高业务稳定性,对调度速度设置了限制。解决办法是:如果业务处于低峰期,可以适当调大迁移并发,例如使用tiup ctl pd config set max-snapshot-count 64临时调大快照迁移速率。但要注意,调度完成后建议恢复默认值,避免影响正常业务的磁盘 IO。
6. 最佳实践与工程建议
6.1 容量规划要“先算后建”
TiDB 集群建设最忌讳边跑边加资源。虽然 TiDB 支持在线扩容,但如果初始节点太少,数据重分布需要很长时间,期间可能影响业务。建议在项目初期就根据数据增长曲线、业务峰值 QPS、备份恢复时间等指标,综合计算 TiKV 节点数量和磁盘配置。这里的原则是:TiKV 节点宁可多部署一两个,也不要卡着最小规模上线。
6.2 表结构设计与 SQL 规范
TiDB 虽然兼容 MySQL,但分布式场景下的表结构设计有一些额外注意点:
- 尽量避免使用过于宽泛的表结构,列数过多会影响存储和传输效率。
- 主键最好使用自增整数或雪花 ID,避免随机字符串做主键,因为随机主键容易导致热点写入。
- 合理设计分区表。TiDB 对分区表的支持与 MySQL 存在差异,需要在测试环境充分验证。
- 外键约束尽量在应用层实现,减少分布式事务的复杂度。
- 对高频查询字段建立二级索引,同时注意索引数量和写入性能的平衡。
SQL 规范方面,我们要特别强调执行计划分析。TiDB 提供 EXPLAIN 语句,可以方便地查看 SQL 执行计划,识别全表扫描、索引失效等问题。上线前应该对核心 SQL 逐个做执行计划审查。
6.3 监控告警与值班机制
数据底座稳定运行不能靠“人肉盯着”。我们建议建立三级监控告警机制:
- 第一级:基础设施监控。包括服务器 CPU、内存、磁盘、网络,使用 Prometheus + Node Exporter 实现。
- 第二级:数据库组件监控。包括 TiDB Server、TiKV、PD 的运行指标,使用 TiDB 自带监控组件。
- 第三级:业务链路监控。包括核心 API 的响应时间、错误率、数据库慢查询次数,使用 SkyWalking 或自研监控系统实现。
告警规则要分层通知,例如“集群节点宕机”通知全体 DBA 和研发负责人,“单个 SQL 慢查询次数增加”通知相关应用负责人。避免所有告警都推送给所有人,造成告警疲劳。
6.4 变更管理与灰度发布
数据库架构迭代中,变更管理是最高风险环节。我们的实践是建立严格的变更审批流程:
- 所有 DDL 变更必须先在测试环境执行,观察执行计划变化和锁等待情况。
- 生产 DDL 尽量在业务低峰期执行,使用
pt-online-schema-change这类工具也存在一定限制,最好使用 TiDB 原生支持的在线 DDL。 - 应用切换实行灰度发布,先切 5% 流量验证,再逐步扩大到 100%。
- 每次变更前准备回滚方案,包括回滚 SQL、备份文件、数据同步链路等。
6.5 权限与安全控制
TiDB 的权限管理体系与 MySQL 类似,支持用户、角色、库表级权限控制。我们在生产环境遵循最小权限原则:
- 应用账号只授予业务库的 SELECT、INSERT、UPDATE、DELETE 权限,不授予 DDL 权限。
- DDL 操作通过独立的运维账号执行,操作留痕。
- 开启 TiDB 的审计日志功能,记录重要操作。
- 数据库连接必须使用 TLS 加密传输,防止数据在网络上被窃取。
需要特别提醒的是,在未获得合法授权的情况下,任何数据库变更、数据导出和权限调整都是不被允许的。所有操作都应在公司审批流程内进行,并在测试环境中完成验证。
7. 总结与下一步
这次外贸赋能中心数据架构迭代,核心成果是完成了从 MySQL 分库分表到 TiDB 分布式架构的平滑切换。我们获得了几个明确收益:扩缩容不再需要业务停机、数据自动均衡不再依赖人工迁移、分布式事务由数据库原生支持、分析查询与事务处理可以共享同一份数据。对业务团队来说,最直接的感受是“能扛住大促了”,对研发团队来说,“不用再写分库分表的业务代码了”。
如果你正在考虑引入 TiDB,建议先做三件事:第一,梳理清楚现有 MySQL 上依赖了哪些特殊特性,评估兼容成本;第二,在真实数据量和真实业务流量下做性能测试,不要只依赖官方文档上的 Benchmark;第三,规划好数据迁移和回滚方案,确保每一步都可逆。
希望这篇文章能为你提供一些参考。文中涉及的部署命令和配置示例,在实际环境里要根据你的版本和网络规划做调整。如果后续你在 TiDB 落地过程中遇到问题,欢迎在评论区交流。