ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

TiDB生产环境部署实战:从拓扑规划到高可用配置与运维

TiDB生产环境部署实战:从拓扑规划到高可用配置与运维 TiDB部署这件事说难不难说简单也不简单。作为兼容MySQL协议的分布式关系型数据库TiDB的部署重点不在“装软件”而在“怎么把PD、TiKV、TiDB Server这几个角色按生产标准摆好”。网上搜“Tidb部署”能找到一堆安装教程但大多数只告诉你跑几条命令遇到拓扑规划、故障域设计、高可用配置时就一笔带过。我前前后后在不同环境虚拟机、物理机、公有云里处理过不少TiDB集群深知真正的坑往往不是TiUP执行失败而是部署前就埋下的副本数不够、label没打、PD节点部署在同一机柜、时钟没有同步……这些到了线上跑几个月才会慢慢爆出来。这篇文章我不打算照抄官方文档而是按实际落地顺序讲清楚从选型规划、环境检查、TiUP部署、高可用设计到验证运维这一整套逻辑。你可能是DBA、运维工程师也可能是准备从MySQL往分布式架构迁移的架构师只要目标是“能稳定跑生产”这篇内容应该能帮你少走不少弯路。每个关键步骤我都会解释为什么这么做并附上我实测过的一些参数和踩坑记录方便你直接抄作业。1. TiDB部署前的架构与选型思路1.1 先搞清楚TiDB的三个核心角色再动手很多第一次部署TiDB的人上来就想找一条命令把集群装完结果遇到问题后无从下手。TiDB不是单机数据库它天生被拆成了几个组件每个组件都有完全不同的职责和故障特性不理解这些部署规划就无从谈起。TiDB Server无状态SQL层负责解析SQL、生成执行计划、处理事务。它不存数据所以可以随便横向扩前面挂负载均衡就行。部署时通常会把多个TiDB实例放在同一层避免单点。TiKV真正的数据存储引擎数据按Region分片打散在多个TiKV节点上。它是整个集群里最“重”的组件CPU、内存、磁盘性能基本都由它决定。PD元数据管理和调度中心负责存储整个集群的元信息、分配全局事务IDTSO、调度Region的Leader和副本位置。PD虽然是中心化角色但它本身通过Raft协议做多节点副本一般部署3个或5个奇数节点。这三个角色的资源消耗差别很大TiKV吃磁盘和内存TiDB Server吃CPU和连接数PD则对低延迟网络和磁盘IOPS比较敏感但资源占用相对小。所以在硬件选型时不要给所有节点配一模一样的规格至少不要把PD和重负载的TiKV混布在同一台物理机或同一块磁盘上否则PD的调度请求和TiKV的数据落盘抢IO容易出现抖动。1.2 版本选型与拓扑规划生产环境别追新TiDB的版本迭代很快网上热词和教程里经常出现最新版但生产环境部署一定要选LTS长期支持版本。我一般会去官网看Release Notes选择当前处于LTS状态的大版本然后再挑该大版本里最新的patch版本。新功能可以放到测试环境玩生产环境别当小白鼠。拓扑规划是整个部署中最容易拍脑袋的环节。以一个小型生产集群为例如果预算和机器数量有限我建议至少准备6台机器角色数量建议规格说明TiDB Server28C16GSSD无状态可后续扩容PD38C16GSSD奇数避免脑裂最好跨机柜TiKV316C64GNVMe SSD数据节点三个是最低要求你可能会问PD能不能复用TiDB或TiKV的机器官方支持混合部署但我不建议在生产环境这么干尤其不要把PD和TiKV放在一起。PD对网络和磁盘IO是有隐含要求的TiKV的高负载有可能导致PD调度变慢进而影响Region的平衡和故障恢复。如果你只是测试环境或者资源受限混合部署也得把PD和TiKV用不同的数据目录和磁盘隔离开。另外部署前就要考虑“节点分布在哪个故障域”。这里的故障域可以是机柜、机房也可以是公有云的可用区。如果全部节点放在同一个机柜一旦机柜断电整个集群就没了。TiDB的容灾能力依赖于Raft的副本分布拓扑设计时就得把故障域信息通过label告诉PD否则PD只会把副本随机打散到不同节点做不到跨机柜/跨机房容灾。这个细节我会在后面的高可用部分展开讲。2. 环境准备与TiUP集群部署实操2.1 硬件与系统基础检查清单在跑任何TiUP命令之前先花半小时把操作系统层面检查一遍。TiDB对基础环境的要求比较明确缺少任何一项后续都可能出现诡异问题。首先是NTP时钟同步。TiDB依赖PD的TSO来分配全局事务ID如果节点间时钟漂移过大事务时间戳会出现乱序轻则慢查询重则数据一致性问题。所有节点必须统一使用同一台NTP服务器并且建议开启时间同步服务让时钟偏差保持在100ms以内。这个通常被人忽略但排查问题时的嫌疑值很高。其次是swap和文件系统。安装前一般建议关闭swap至少把swappiness调低。TiDB的存储引擎依赖操作系统的Page Cache如果频繁换页性能会变得极不稳定。文件系统建议用ext4或xfs挂载参数里开启nobarrier不一定合适但至少要保证IO调度器为noop或noneSSD场景下不要用cfq。然后是文件描述符和进程限制。TiKV单实例会打开大量文件默认的ulimit根本不够。部署前需要把/etc/security/limits.conf里* soft nofile和* hard nofile调大建议至少1000000同时把vm.max_map_count提高一些。否则运行一段时间后你会突然发现TiKV日志里出现“too many open files”或者mmap失败那时候再处理就要重启实例了。最后是磁盘性能的快速验证。用fio简单测一下随机写和延迟重点关注fsync的延迟和IOPS。TiKV的Raft日志同步非常依赖单次fsync的延迟如果磁盘是普通机械盘那基本上不用考虑跑生产。我见过有人在云主机上把数据目录放到云盘但云盘的突发IO能力不稳定导致TiKV的写入延迟经常飙到几十毫秒。这类问题前期不好发现只有在高并发时才会暴露。2.2 安装TiUP并初始化集群TiUP是TiDB官方提供的包管理器现在的集群部署基本都是用它完成。它可以帮助你安装部署工具、下载组件、分发配置、启动服务。安装很简单curl --proto https --tlsv1.2 -sSf https://tiup-mirrors.pingcap.com/install.sh | sh安装完成后source ~/.bashrc确认tiup命令可用。注意TiUP在部署集群时会通过SSH连接目标机器所以你需要准备一个中控机通常就是你的运维跳板机从这台机器能免密SSH登录到所有目标节点。我之前吃过一个亏中控机用了root用户直接连结果部署出来的进程都是root启动的后面回收权限、日常巡检都很难受。更规范的做法是创建一个专用的tidb用户让TiUP通过这个用户来管理集群目标节点上的数据目录也归这个用户所有。接下来写拓扑文件topology.yaml。下面是我常用的一个最小高可用拓扑模板global: user: tidb ssh_port: 22 deploy_dir: /tidb-deploy data_dir: /tidb-data # arch: amd64 pd_servers: - host: 10.0.1.11 - host: 10.0.1.12 - host: 10.0.1.13 tidb_servers: - host: 10.0.1.14 - host: 10.0.1.15 tikv_servers: - host: 10.0.1.21 port: 20160 status_port: 20180 - host: 10.0.1.22 port: 20160 status_port: 20180 - host: 10.0.1.23 port: 20160 status_port: 20180 monitoring_servers: - host: 10.0.1.30 grafana_servers: - host: 10.0.1.30 alertmanager_servers: - host: 10.0.1.30如果你没有独立的中控机也可以挑一台目标机器来跑TiUP但建议把TiUP自己的部署目录和数据目录分开。拓扑文件里deploy_dir是程序安装目录data_dir才是真正存放数据的目录这两个不能放在同一块盘上否则日志和数据互相挤占磁盘空间。配置写好之后执行tiup cluster check topology.yaml tiup cluster deploy cluster-name version topology.yaml -p tiup cluster start cluster-name部署期间需要输入SSH密码如果配置了免密就不需要TiUP会自动完成包分发、配置生成和服务启动。命令里的cluster-name可以任意取一般用tidb-prod这种可辨识的名字。进入启动状态后可以用tiup cluster display cluster-name查看所有组件的状态每一个都是Up才算正常。2.3 部署后的组件状态确认很多人启动完成之后就急着连MySQL验证SQL这是不对的。我会先做一次静态检查通过tiup cluster display确认所有节点进程状态。检查PD的健康接口curl http://pd_ip:2379/pd/api/v1/health返回的health字段应该都是true。确认TiKV的store状态curl http://pd_ip:2379/pd/api/v1/stores每个store的state_name应该是Up。用MySQL客户端连接TiDBmysql -h tidb_ip -P 4000 -u root执行select version();。这里要特别提醒一下端口。TiDB Server默认端口是4000PD是2379/2380client和peerTiKV是20160/20180。云环境下安全组或防火墙只开放必要端口原则没毛病但PD的peer端口2380用于节点间Raft通信TiKV的peer端口20160也必须在所有TiKV节点之间互通。如果中间有防火墙只开了4000那集群虽然能启动但Region之间的复制会一直处于异常状态。3. 高可用与数据安全部署设计3.1 用label实现跨机柜、跨机房容灾部署起来了不代表就能上生产最容易被忽略的高可用设计就是“副本怎么摆放”。TiDB的TiKV数据默认3副本PD会尽量把不同副本放在不同的TiKV节点上但它本身不知道机柜和机房的概念。要让副本真正隔离故障域必须通过label来声明物理位置。在topology.yaml里可以给每个TiKV节点打标签比如tikv_servers: - host: 10.0.1.21 config: server.labels: zone: z0 rack: r0 host: h21 - host: 10.0.1.22 config: server.labels: zone: z0 rack: r1 host: h22 - host: 10.0.1.23 config: server.labels: zone: z1 rack: r0 host: h23同时还需要在PD配置里声明调度时看哪些labelpd_servers: - host: 10.0.1.11 config: replication.location-labels: [zone, rack, host]location-labels的顺序是有讲究的。数组里靠前的label表示更大的故障域PD在调度副本时会优先让同一份数据的多个副本分布到不同的zone其次再是不同的rack最后才是不同的host。如果你的故障域只到机柜那数组就写[rack, host]就行如果是同城三机房就必须写成[zone, rack, host]这样的三级划分。我见过一个实际案例某团队在两个机房部署了3个TiKV节点其中一个机房只有1个节点另一个机房有2个节点。这个拓扑在外行看来没什么问题但节点数一共就3个3副本刚好分布在2个机房PD确实完成了容灾。问题是当唯一节点的机房整体断电剩余2个节点只有2个副本Raft无法选出Leader整个集群直接不可用。要避免这种“看着HA其实单点”的情况副本数最好比最大故障域内的节点数至少多1并且每个故障域内的副本数不能超过一半对3副本而言。3.2 Raft副本调度与数据安全参数TiDB的底层一致性依赖Raft协议。默认情况下每个Region有3个副本其中一个副本是Leader负责处理读写。当某个TiKV节点故障PD检测到之后会发起补副本调度在另一个健康的TiKV上新建一个副本。这个过程是自动的但速度受很多参数影响比如region-schedule-limit、store-limit等。生产环境如果节点很多可以适当调大调度并发让故障后恢复更快。但调大并发也有风险因为新建副本会占用CPU、磁盘带宽如果集群本身压力很大反而会让性能进一步恶化。我的建议是初期保持默认等对集群行为有把握了再针对性调整。可以通过tiup cluster edit-config修改参数然后tiup cluster reload动态加载。副本数也不是越大越好。默认的3副本在多数场景下够用了如果追求更高的容灾能力比如防止单机房故障就需要用5副本。但5副本意味着写入时要复制到4个follower网络开销和磁盘占用都会明显上升。多副本集群的写入延迟一般比3副本高尤其是跨机房场景。所以副本数这个决策必须结合业务容忍的RTO/RPO和网络延迟来权衡不要盲目加副本。3.3 备份与恢复体系建设别等数据丢了再想部署TiDB很多人关注的是高可用却忽略备份。Raft复制只防节点故障不防人为误操作和逻辑损坏——drop table一样会被复制到所有副本。所以在部署规划阶段我就建议把备份工具br的目标架构定下来。BR是TiDB官方推荐的备份工具支持全量备份和增量备份。全量备份是把快照导到外部存储本地磁盘、NFS、S3等增量备份则是基于binlog或日志备份做PITR恢复到时间点。常见的做法是每天做一次全量备份到异地存储同时开启log backup这样能把误操作恢复到一个具体的时间点。执行全量备份的命令大概是这样tiup br backup full --pd ${PD_ADDR}:2379 --storage s3://backup-bucket/tidb-backup?endpointhttp://s3.local:9000 --send-credentials-to-tikvtrue这里要强调两点一是备份存储尽量不要放在TiKV同一台机器的本地磁盘上否则机器故障时备份也没了二是备份任务本身要纳入监控每天确认备份成功、产物大小是否正常不要只看脚本有没有跑完。我遇到过备份一直失败但因为没人看调度日志直到需要恢复才发现最近的可用备份是三个月前的尴尬情况。备份是“买了不用”的保险但不代表买了就不用检查。恢复流程也要定期演练。TiDB的恢复步骤不复杂但必须保证恢复用的机器资源和原集群兼容且BR恢复前要清空目标集群的数据。不要在生产环境恢复至少要在测试环境完整跑一遍全量增量恢复并验证应用启动后数据完整性。这样的演练做一次你心里就有底了。4. 部署后的验证、监控与日常运维4.1 基础健康检查与性能压测集群起来之后不要急着接业务流量。我会先做一轮健康检查和基准压测确认部署配置没有硬伤。健康检查我习惯看几个方向tiup cluster display确认所有节点正常。用tidb-lightning或sysbench做一次小规模写入观察写入是否有明显延迟抖动。查看TiKV详情面板中的99.99% Duration如果在空载情况下就超过几十毫秒基本可以断定硬件或系统配置有问题。检查PD调度面板确认没有大量pending peers或miss peers长时间不消。性能压测更推荐用官方生态的go-tpc它内置了tpc-c、tpc-h等常见负载。部署好后可以用它快速跑一个短时压测tiup install go-tpc tiup go-tpc tpcc -H 10.0.1.14 -P 4000 -D tpcc_test -T 16 --time 1m prepare tiup go-tpc tpcc -H 10.0.1.14 -P 4000 -D tpcc_test -T 16 --time 5m run压测的主要目的不是跑一个好看的分数而是观察CPU、内存、磁盘IO的均衡度。比如压测时如果某个TiKV节点的CPU明显高于其他节点说明Region分布不平衡可能需要做一次tiup ctl:pd store rebalance或者检查热点Region。这种问题越早发现越好因为线上流量一进来各种热点会被放大。4.2 监控系统与告警规则落地TiUP部署时会自动装好Prometheus、Grafana和Alertmanager。默认Grafana端口是3000账号密码是admin/admin。很多人以为监控装好就完事了其实默认面板只是基础真正要花心思的是“告警规则能不能在业务受损前通知到人”。TiDB内置的告警规则很多但不同环境阈值不一样你要做的是筛选和调整。我常用的告警项大概是这些告警项触发条件说明TiKV leader数量下降leader数小于副本数的一半可能表示节点异常或Region不可用TiKV 磁盘使用率超过80%持续10分钟高磁盘占用会影响性能和调度PD etcd写入延迟超过50ms持续5分钟说明PD网络或磁盘有问题TiDB 活跃连接数超过设定值如2000可能需要扩容TiDB实例Backup任务失败BR返回错误需要立即处理否则数据恢复风险这些告警要配置到Alertmanager的receivers里可以接入钉钉、企业微信、邮件。告警消息要带集群名和IP方便值班人员快速定位。我建议把告警分两个级别warning和critical。warning可以日汇总critical必须实时推送。不要什么指标都设成critical否则值班人员会麻木真正的故障反而没人处理。4.3 日常运维操作要点扩容、升级、参数调整TiDB部署完之后日常操作最多的就是扩容和参数调整。扩容TiDB节点很简单在拓扑文件里加一行host然后tiup cluster scale-out cluster-name topology.yaml扩容TiKV同样如此但要注意扩容之后不会立刻均衡PD需要时间把现有Region的一部分调度到新节点上。这个过程中磁盘IO和网络都会有额外开销建议在业务低峰期扩容。扩容TiKV时先确认新节点的性能和存储规格最好与现有节点一致否则均衡策略会变得很别扭——比如一个128G内存的新节点和若干个32G的旧节点在打散Region时容易形成新的不均衡。升级TiDB版本是另一个高频操作。用TiUP做滚动升级很方便tiup cluster upgrade cluster-name new-version --transfer-timeout 120升级过程中TiUP会先迁移PD leader再逐个重启TiKV和TiDB实例。这里务必注意升级前先看Release Notes确认是否有配置不兼容的变更并且做好全量备份。TiDB支持跨大版本升级但不建议连续跨多个版本最好按LTS版本路径一步步走。参数调整方面TiDB大部分配置都可以在线热更新但有些参数比如server.labels修改后需要重启实例才能生效。用tiup cluster edit-config改完配置后reload会自动判断是否需要重启。运维规范上我要求所有配置变更都要走评审和reload后的观察不能随手改生产集群特别是涉及副本数、调度并发这类全局参数。5. 常见部署问题与排查实录5.1 启动失败与端口占用TiUP部署时最常见的报错就是端口被占或配置文件路径不对。tiup cluster deploy会检查端口占用但并不总会给出清晰的中文提示。如果遇到failed to start ...先别急着看日志可以直接ss -lnp | grep port确认本机端口。有一次我部署PD时报etcd failed to start查了很久才发现是PD 2380端口被监控agent占了。这类问题其实很好避免部署前用tiup cluster check topology.yaml做端口冲突检查它会扫描所有目标节点的端口占用情况。多花一分钟跑检查比启动失败后翻日志省事得多。另一个经常踩的坑是SSH免密配置范围不对。TiUP的中控机需要能免密登录所有目标节点且目标节点的tidb用户需要有对部署目录的完全权限。如果目标节点用root登录后再切换用户和通过tidb用户直连是有区别的可能导致文件属主混乱和后续重启失败。5.2 TiKV启动后内存和磁盘异常TiKV默认会使用机器大部分内存作为块缓存所以你会看到TiKV进程内存占用特别高这倒不一定是泄漏。如果担心影响同机其他进程可以在TiKV配置里设置storage.block-cache.capacity比如限制为系统内存的30%。但这个调整会直接影响读性能对于纯OLTP场景最好还是给TiKV独享机器。磁盘异常最常见的问题是数据目录空间不够。TiKV的数据盘满了会拒绝写入即使PD和TiDB还活着客户端也会报raftstore-full或者server-is-busy。预防的关键是监控磁盘使用率并在部署时把data_dir放在独立分区。如果已经满了需要紧急清理binlog和日志或临时扩容数据盘。我记得有次线上TiKV磁盘使用率到92%调度几乎停滞花了整个下午才把空间腾出来从那以后我对磁盘水位告警的阈值就设得很保守80%就开始报警。5.3 常见问题速查表下面这张表是我在实际部署和运维过程中整理出来的高频问题。你可以直接截图放在运维手册里遇到问题时先对一遍。现象可能原因建议处理PD启动失败2380端口冲突、数据目录残留检查端口和/pd目录必要时清空旧数据确认非生产TiKV启动后一直未注册到PD网络不通、安全组未放行20160端口用ping和telnet检查节点间连通性集群可连接但写入报错Region不可用多为某TiKV节点宕机查看PD页面中的miss peers确认宕机节点能否恢复读写延迟间歇性飙升磁盘IO抖动、NTP不同步、GC压力大检查fio结果确认时间同步观察TiKV详情面板的GC指标扩容后数据不均衡调度限制、新增节点label错误用pd-ctl查看store状态检查location-labels是否一致备份失败存储权限不对、BR版本和集群版本不匹配确认存储访问权限升级BR到与集群一致的最新版5.4 实用建议部署节奏与试运行策略在我看来TiDB部署不是“启动成功”就结束了真正完成部署的标志是监控告警能跑通、备份恢复有演练、扩容缩容有预案。务实一点的做法是分三步走先在测试环境完整演练一遍部署和压测再在预发环境跑两周业务流量观察监控指标最后才动生产。一切顺利的话生产部署反而不是最费时间的环节。另外TiDB集群的日常健康巡检一定要制度化。我要求运维同事每周看一次集群概览面板重点关注三个数字TiKV节点状态、Region的missing peers数量、数据盘使用率。这三个指标任何一个异常都值得深入排查。大部分集群故障都不是突然发生的而是在出现苗头时被忽略等到量变引起质变才暴露出来。我在多次部署和迁移过程中养成了一个习惯每做完一次重要操作就在自己的笔记里记录当时的拓扑文件、参数变更和操作后的监控截图。TiDB是一个分布式的复杂系统单靠记忆很容易漏掉细节尤其当你同时维护多个集群时一份准确、及时更新的部署文档比任何自动化工具都更能救命。如果你正准备部署自己的第一个生产集群希望这篇文章能帮你理顺思路少踩几个我当年踩过的坑。
返回列表