1 前言
转转是PingCAP最早的一批用户之一,见证了TiDB的发展,自身也沉淀了不少经验。
从1.0 GA开始测试,到2.0 GA正式投产,然后升级到了2.1,后来又升级到4.0.13,最后建设自动化平台。
其实转转DBA团队初建以来就开始投入一定的资源进行平台建设,一步一步实现自动化运维,希望一切需求都能实现工单化、一切操作都能实现平台化,进而降低人力成本。
本文就想来分享一下TiDB实现自动化的历程。从遇到问题开始,到解决问题,以及平台做成什么样,也是对过去的工作做一个总结和梳理。
2 运维痛点
(1)转转现有集群30多套,早期都是2.1.[5,7,8,17]版本,近500个TiKV节点,总共差不多一百台机器供TiKV使用,集群新建、扩容、迁移都需要人工找机器。也因为缺少一个上帝的视角去管理集群,没法做到资源的合理分配,导致日常工作中有很大一部分时间都是在做迁移,都是重复工作,效率很低。
(2)2.1版本的运维工作都是基于Ansible进行。如扩容、下线、启停、修改配置等日常操作,有时候会碰到Ansible执行超时的情况。批量操作集群时,根本不知道到哪个节点了,这情况经常能遇到,在reload集群配置文件的时候遇到的概率就非常大,要多崩溃有多崩溃。
(3)2.1版本的TiDB自身有很多问题,执行计划失效、读写热点问题(不能快速定位问题)、TiDB大查询OOM、乐观事务、监控不完善、以及已知/未知的问题,就连集群状态都无法快速获取,当然备份也很痛苦,这对运维人员的工作加大了难度,也提升了人力成本。
4.0 使用悲观事务需要满足一定的要求,具体请参考官方文档。
(4)机器资源使用不平衡,存在部分机器内存剩余较多但是磁盘不足,还有部分机器内存不足,但是磁盘剩余很多。导致的结果是老板觉得机器投入已经很大,但是DBA实际使用中发现机器还是不够用。
(5)告警噪音比较多,存在重复告警,互相冲刷问题,严重浪费告警资源,对排查问题也带来很不友好的体验。
3 解决痛点
3.1 元数据管理
将所有节点信息保存到表里,定期采集节点状态及资源使用情况。
过去都是依靠Ansible的配置文件进行管理,管理视角基本是停留在集群都有哪些节点,连一台机器都有哪些实例都不清楚,更别谈资源管理了。
现在将所有组件保存到一个表中,定期采集组件服务状态,内存磁盘占有量等信息。这样就有了一个全局的视角进行管理,也很方便的查阅集群状态。
后续基于这份元数据进行项目成本核算。
还有一个收益就是,组件信息的采集,可以很好的控制单个TiKV的容量,不会再出现单个集群容量一直增长,然后触发机器的磁盘告警DBA才感知到。有了这个采集的数据后,可以设置一个TiKV容量上限,比如500GB,达到这个阈值就发送告警给DBA准备扩容。这样能很好的避免因机器磁盘告警而接收大量告警信息(单机多实例),也能提供一个很好的缓冲时间让DBA来处理。
总结起来就是,能很好的将机器/集群/组件管理起来,能合理有效的进行资源调度,也为实现自动化提供了基础数据。
3.2 机器资源管理
将所有机器信息保存到表里,定期采集硬件资源使用情况。这么做能获得如下两点收益:
- 第一是对已有环境进行rebalance。有了元数据信息,就可以很好的展开rebalance工作了。最终收益很明显,既提高了资源利用率,还降低了15%的机器资源。
- 第二是能合理有效的进行资源调度,为实现自动化提供了基础数据。(同元数据管理)
元数据管理和机器资源管理,这两部分工作既降低了成本也提升了工作效率同时也是监控的兜底策略,会基于这两个数据表进行监控:(1)进程是否正常。(2)机器是否正常。
3.3 全面升级
将所有2.1集群升到4.0.13。
为了更好的管理集群,在升级前还做了一些规范化。第一是端口规划,因为TiDB组件太多,一个集群至少需要6种组件,涉及到十多个端口,所以做了端口规划,端口采用2+3的格式,前两位表示组件名,后三位表示集群编号。即:前两位一样表示同一类组件,后三位一样表示同一个集群。这样就可以很好的实现规范化管理。
比如有一个001编号的集群,集群信息如下:
角色 | 数量 | 端口 | 部署目录 | 域名 | 备注 |
---|---|---|---|---|---|
pd | 3 | 13001/14001 | /path/pd-13001 | tdb.13001.com | dashboard的域名 |
tidb | 3 | 15001/16001 | /path/tidb-15001 | tdb.15001.com | 对外服务的域名 |
tikv | 3 | 17001/18001 | /path/tikv-17001 | ||
alertmanager | 1 | 21001 | /path/alertmanager-21001 | tdb.21001.com | alertmanager的域名 |
prometheus | 1 | 19001 | /path/prometheus-19001 | tdb.19001.com | prometheus的域名 |
grafana | 1 | 20001 | /path/grafana-20001 | tdb.20001.com | grafana的域名 |
exporter | n | 11001/12001 | /path/monitor-11001 | 每个机器都会部署 |
- 我们每个集群的监控告警都是独立的组件,原因是在使用Alertmanager过程中发现有时候A集群的告警信息的instance的值是B集群的instance,为了避免出现这种问题,我们每个集群的监控告警组件都是独立的。
- 另外我们会提供5个域名,分别对应到TiDB对外服务,Dashboard,Grafana,Prometheus,Alertmanager。
- 仅需要提供集群编号,就可以快速获取各组件的端口号及域名,看到部署目录就可以知道是哪个集群的哪个组件。
- 需要注意的是,如果将Dashboard暴露给业务使用(业务很喜欢访问慢查询平台),建议是创建独立的账户,因该平台强制要求使用root,所以可以针对PD组件的几个机器单独创建root账号,这个root的密码跟DBA使用的root进行区别。可以避免管理员账户泄露的问题,但是带来新的问题就是账户管理变得复杂了。
全部完成升级后。整体性能提升30%-50%,解决了抽数带来的影响,升级以后暂时没有收到因抽数导致影响到业务的反馈,在升级前几乎每两个月都会有至少一次因为抽数导致业务受影响。
3.4 告警改造
支持短信、语音告警,并实现告警收敛、抑制,告警升级。大大降低告警条数(条数至少能降低60%),节约告警资源。
收敛和抑制目的是降噪。
告警升级主要是为了降低告警成本,升级分如下几个维度:
- 第一:介质升级。邮件 --> 企业微信 --> 短信 --> 电话(同一个告警项发送超过3次就向上升级一个介质,具体可以根据需求定义)。
- 第二:接收人升级。一级 --> 二级 --> leader。
- 第三:按照时间升级。工作时间通过邮件/企业微信发送告警,工作时间之外通过短信/电话发送告警。
4 实现自动化
分布式集群有很多优点,但是对DBA来说也增加了运维复杂度,有些集群几十上百个节点,全靠人工去管理运维无疑是很痛苦。
转转现在基本完成了自动化,收益也很明显,这部分主要是想分享一下注意事项或者遇到的问题,仅供参考。
4.1 需求工单化
这部分主要是在平台通过工单的方式实现了业务的日常的需求,降低了沟通成本,实现了业务需求审计,还能减少DBA的工作量。
目前支持如下工单类型。
(1)集群部署工单
在4.0版本中,部署一个新集群比较麻烦的是拓扑文件的生成,倒不是有多复杂,而是因为一个集群的组件太多,每种组件对硬件的要求又有些区别。
比如Grafana,Alertmanager这种不需要IO,PD,TiKV,TiFlash对IO又要求比较高,另外还需要根据服务的重要程度进行合理的规划,重要的服务单独部署或者尽可能的减少节点数,需要考虑的点参考维度有点多。
以上只是针对部署集群需要关注的点,还有一些额外的考虑点,或者说操作细节。总结起来如下:
- 为各个角色选择合适的机器,完成拓扑文件,然后部署集群。
- 初始化集群,创建业务用户,业务域名。
- 配置Grafana,Prometheus,Alertmanager,Dashboard等平台,创建必要的用户,以及Grafana,Dashboard权限控制,以及功能验证测试等。
- 集群信息入库,将必要的信息同步到业务侧。
所以实现工单化,不仅轻松解决资源调度问题,提升机器资源利用率,还可以大大提升效率,避免操作出错或者遗漏。尤其是功能验证,万一业务上线以后才发现问题,影响面就比较大了。
通过sic判断集群重要等级,预估QPS,TPS作为辅助参考项,最终根据评分为其分配合理的机器进行集群部署。
(2)数据恢复工单
这类需求在工作中倒不是很多,但是一旦遇到就会比较紧急。实现这类工单后,不仅可以降低沟通成本,降低故障的影响时间,也能降低人力成本。
目前支持两个维度的数据恢复。
- 一种是基于快照,如果恢复需求的时间点在GC时间之内的,就直接通过快照进行数据恢复,所以这类需求恢复速度较快。
- 一种是基于备份文件,如果恢复的时间点位不在GC时间之内的,就只能选择最接近该时间点的备份文件来恢复了。
目前这两类维度都支持整库(一个工单仅限单库),单表或者多表。基于快照的还支持带特定条件,基于备份文件的不支持带条件。所以相对来说基于快照的复杂一些,特别是多表需要恢复到某一个时间点,且是带条件恢复(单表部分数据)。
比如一个订单,涉及多个表,需要将多个表某些订单号的数据恢复到特定时间点。
由此可见,基于快照的恢复是比较灵活的,用户可以选单库,或者单表,还可以选择多表,由于我们并不知道用户需要恢复几张表,所以带查询条件的逻辑应该是动态的,即当用户选择了某个表,就会弹出改表的查询条件输入框,有几个表就有几个输入框,根据提示输入到对应的表即可,如下图所示。
(3)TiCDC工单
转转公司有一种特殊业务需求,需要将业务的数据抽取到大数据平台,主要是给业务提供经营数据分析、用户行为和画像资产沉淀以及一些趋势预测。
如果是MySQL直接做一个专门提供数据抽取的从库就行了,但是TiDB不行,虽然可以暴露一个TiDB节点给大数据进行数据抽取,但是本质上还是对同一组TiKV进行操作,所以抽数操作很容易引起业务的抖动。
现在我们提供了两种方案给业务进行选择,优先可以选择TiCDC,如果TiCDC不能满足的情况下可以使用TiFlash。
对于已经存在cdc任务,只需更新配置即可,另外需要注意下游如果是kafka的话,数据包的大小,要求跟kafka的最大值配置一致,否则可能会报错,尤其是TiDB端扩大表结构的场景。
对我们来说,TiCDC需求真的太需要实现工单化了。那些需要抽数的业务,几乎新增一个表就需要更新TiCDC的任务,之前都是邮件沟通,如今实现工单后,对业务,对大数据团队,又或者是DBA都是十分方便的,降低了三方的沟通成本,提升工作效率。
(4)TiFlash工单
需求同TiCDC工单。
从成本上考虑,TiCDC不需要额外的存储空间,所以更优,也更受欢迎。但是存在一定的风险,比如TiCDC到下游的同步链路出现问题(上游TiDB业务进行调整可能会导致同步中断),那么下游就会无法获取增量数据。
TiFlash则不会有这个问题,但是需要牺牲一定的存储空间,业务成本会有所提升,需要业务自己去权衡。
4.2 操作平台化
这部分主要是在平台通过页面操作实现了日常的管理,降低了运维成本,实现了操作审计,还能避免一定的人为操作失误。
(1)节点管理
这部分涉及节点的启动、关闭、重启、下线、维护等。节点启停、重启流程比较简单,这里不做过多介绍。
只有当节点处于关闭状态才会有启动选项。另外需要注意的是,重启操作已经改成reload,这样对业务的影响相对小一些。前提是要评估好restart是否等价于reload(没有变更配置基本不会有什么问题)。
下线和维护操作需要注意如下几个事项:
- 下线的目标节点是否是该角色的最后一个节点,或者是否满足raft协议的最低要求,如果是则不能直接下线,需要人工介入。
- 维护操作主要是需要联动一下告警静默,因为维护操作本身是计划内操作,对于不必要的告警可以提前规避掉。
对于PD,TiKV等组件对数量是有要求的,PD,TiKV最少要求两个,所以当集群只剩两个节点的时候是不允许下线的,需要DBA介入操作,当然还有DM-worker,TiFlash等组件也是有最低数量要求,需要根据实际情况进行判断。
(2)扩容管理
扩容分两种情况,一种是主动扩容,一种是自动扩容。这个小结是介绍主动扩容,至于自动扩容后文会介绍。
扩容功能比较灵活,支持多角色同时扩容,节点个数可配置,目标地址也可配置,如下图所示:
未指定地址的话就由系统默认分配合理的目标地址。
(3)下线管理
下线要求是串行操作,即一个集群在同一个时间只能有一个节点被下线,等待下线后才能下线第二个节点。另外,如果是存储节点(TiKV,TiFlash,Pump),需要等待数据迁移完毕后,执行完集群调整(prune)操作才算下线完成。
需要考虑一下异常节点的下线,即机器宕机不可恢复的情况,所以我们增加了一个强制下线的选项来处理此类异常场景。
(4)告警管理
告警跟运维工作息息相关,一个好的告警管理平台不仅能提升运维的效率,还能提升工作舒适度及生活质量。
我们的告警管理平台现在功能比较简单,后续会慢慢丰富。
- 支持预先配置告警静默,比如将对某个集群进行维护,可以先将该集群的告警进行静默。
静默时间最长不允许超过24小时,默认是2小时,这样可以避免因遗忘导致该告警项被长时间静默。
- 支持针对已经告警的项进行静默。这部分逻辑是将所有告警项展示出来,供用户选择。
如下是正在告警列表展示页
支持一键静默,即:正在告警的项全部静默。
如下是静默规则列表展示页,正在运行的静默规则支持删除及禁用,禁用状态的允许重新启用。
(5)慢查询告警
这个功能是统计单位时间内慢查询条目增长量,当达到告警阈值就会触发告警,用户可以设置统计的时间范围,以及慢查询阈值,还有告警阈值。
集群的慢查询阈值大于用户定义的规则的慢查询最小阈值,会将集群的慢查询阈值设置为该阈值。如集群慢查询阈值是300ms,用户定义告警阈值是200ms,这时候会将集群的慢查询阈值设置为200ms。
如下是规则列表展示页,支持规则禁用及删除,禁用后可以重新启用。
4.3 其他辅助功能
(1)进程监控
因线上机器基本都是单机多实例,有时候会出现因为某个实例而影响了整个机器的性能,在没有进程级别的监控下,对我们排查定位问题十分痛苦,为解决这一个痛点,我们开发了进程维度的监控系统,这样可以很好的协助运维人员排查定位机器资源跑满等问题。
进程级别的资源监控,包括但是不限于CPU, 内存, 磁盘IO, 网络流量,功能还在继续丰富。具体实现可以参考这个文章 https://mp.weixin.qq.com/s?__biz=MzIwMjk1ODMzMw==&mid=2247487654&idx=1&sn=0722b7e216cb2f887eea2d8f874faa88&chksm=96d7e434a1a06d22b2a52a87b4bcc8a2fbc52218802ceefa6f243a0bb71a0ea02fd521c67395#rd
会记录每个进程的资源使用情况,其中网络数据是做了限制,只有达到阈值才会采集,所以会出现空白页情况。另外网络传输数据会记录源端到目的端信息。
(2)趋势监控
随着时间的推移,业务数据也在不断的增长。那么问题来了,这个增长是否符合预期?按照这个增量,磁盘空间能支持多长时间?为了解决这两个问题,我们采取了趋势分析的方案,提前监控,分析增长趋势,对于增长异常的集群会和业务进行沟通确认,对于磁盘空间临近告警线会提前迁移。
- 增量告警,当数据目录在三日内连续单日增长超过20GB,每个月增量超过200GB就会发送告警给业务,请业务进行确认。
- 全量告警,当数据目录达到告警阈值就给DBA发送告警。
(3)自动运维
- 自适应迁移
当机器准备达到内存告警阈值,磁盘告警阈值,就自动迁移。
- 自适应扩容
当单个TiKV容量达到800GB就自动进行扩容。
不管是自适应迁移还是扩容,都可以减少DBA的工作量,也能在一定程度上减少告警量。对于扩容,既控制了单个TiKV的大小,对于系统性能也会有一定的提升。
单节点TiKV太大,不利于管理。在节点下线的场景下会拉长数据迁移的时间,在节点离线的场景下,会拉长生成新副本的时间。
5 写在最后
本文介绍了TiDB在转转公司的发展历程,从调研测试到投产使用,从命令行运维到自动化平台管理,将业务日常需求基本实现了工单化,DBA日常管理维护的操作基本都实现了平台化。
一切自动化的前提是先实现规范化。
我们一步一步走过来,遇到了很多问题,也解决了很多问题,但各自环境不同,需求也不同,还可能碰上其他未知的问题,本文所有内容仅供参考。