如何构建企业内的 TiDB 自运维体系 | 得物技术
1
前言
2
TiDB 架构
上图是我们目前的接入方式和整体架构。TiDB 的部署架构这里就不做赘述了,需要了解的同学可以参考官方文档。我们之所以采用 SLB 来做 TiDB 的负载均衡接入,就是为了简化接入成本与运维成本,访问流量的负载均衡以及节点扩缩容可以通过调整 SLB 解决。当然如果能够实现 SDK 负载均衡与故障剔除,结合配置中心的流量调度也是非常好的解决方案。得物 TiDB 部署均采用单机单实例部署,TiDB Server、PD 采用无本地 SSD 机型,TiKV 采用本地 SSD 机型。既兼顾了性能,又能降低成本。详细的机型选择会在后面的内容提到。
3
MySQL 与 TiDB 的对比
圈内一直流传着一句话,没有一种数据库是"银弹"。绝大部分用户选择 TiDB 就是为了弥补 MySQL 的不足,所以选型阶段对两者做些比较也是在所难免的。本文基于我们内部的现状和场景对两个产品我们关注的点进行了简要对比。对比的目的不是为了去印证那个数据库产品能力更强。而是想通过对比来帮助团队在合适的场景选择合适的产品。
扩展性
MySQL
MySQL 就自身扩展能力而言主要是来自于垂直扩容,但是这个会受限于机器的规格上限。水平扩容涉及业务改造和使用成本提升。改造为分库分表,对研发来说是一个费力度很高的方案。需要引入 Sharding 逻辑,改造完成后需要业务 SQL 必须带 Sharding Key 才能执行或者高效执行。所以并不是说做不到可扩展。
TiDB
由于 TiDB 是计算存储分离的架构,且有状态的存储层 TiKV 是分布式存储。所以单从上面定义的扩展性来说,确实对比 MySQL 有很大优势。集群处理能力和存储能力,可以通过扩容 TiDB Server、TiKV 简单实现。这里需要注意的是,TiKV 属于有状态服务,扩容会涉及到数据的 Reblance,过程中 TiKV(region 迁移) 和 PD(调度) 产生大量交互,为避免影响业务,扩缩容过程中需要关注集群情况,根据需求适当调整迁移力度。
性能
MySQL
关于 RT。MySQL 由于是单机数据库,所以对于点查或简单查询的 RT、热点更新的 RT 与 TPS ,相比分布式数据库有天然优势。数据获取链路短(单机数据库本地调用,分布式数据库涉及存算分离),且不用考虑分布式事务的冲突检测。所以总体的访问 RT 要低于 TiDB,具体数据这边就不罗列了,社区有不少性能压测的帖子。
关于聚合查询。互联网公司在 C 端基本不存在此类问题,也是不允许的。所以主要是场景在 B 端。解决方法一般是分为几种:1.提供专门的只读实例给 B 端提供查询能力;2.异构数据来解决(MySQL+ES、ADB 等等)。
关于优化器。MySQL 多年的积累,在优化器的稳定性虽然不如商用数据库那么可靠,偶尔也有走错索引的情况。一般只能通过修改 SQL、修改索引来解决,切记别用 force index 这种有坑的解决方案。但是总体来说我们遇到的 MySQL 走错索引的情况要远低于 TiDB。
TiDB
关于 RT。分布式数据库解决的更多是吞吐量和容量上的需求,比如点查或简单查询的 RT 无法像单机数据库那么短,但是可以通过节点扩容的方式提升 QPS 吞吐量。热点数据这里就不展开讲了,它本身也不是分布式数据库能解决的范畴。如果你的业务场景是一个对 RT 要求很高的场景,那么优先使用 MySQL。如果是高吞吐量需求优先,可以尝试使用 TiDB。
关于聚合查询。由于 TiDB 的存储节点 TiKV 不只是具备存储能力,TiKV 实现了coprocessor 框架来支持分布式计算的能力。所以理论上通过加机器就能扩展计算能力,从我们实际使用的场景来看也是如此,这部分的能力就要优于 MySQL。具体的效果在本文最后的章节会有体现。
关于优化器。这个是大家对 TiDB 一直以来吐槽的点之一,有时候统计信息健康度 90 以上的情况下,还是会走错索引,当然这里有一部分原因可能是条件过多和索引过多导致的。为了解决问题,核心服务上线的 SQL 就必须一一 Review。如果无法正确使用索引的就使用 SPM 绑定,虽然能解决,但是使用成本还是略高。希望官方继续加油。
资源成本
MySQL
如果是一个数据量小且查询模型比较简单的需求(比如:1-2TB,简单查询为主),那么肯定是 MySQL 成本较低。以我们 TiDB 基础配置为例,相比 MySQL 成本高出 27%(该成本是用高可用的 MySQL 对标3 TiDB、3 TiKV、3 PD 的 TiDB)。所以得物内部选型,单从资源成本角度考虑,还是首选 MySQL。
TiDB
如果是一个数据量较大且持续增长或查询模型比较复杂的需求(比如:3-5 TB 以上,多条件查询、聚合查询等)。一般该类型的业务都采用分库分表的解决方案。以得物一个分库分表的集群(10个写实例、10个读实例)为例,替换为 TiDB(6 TiDB、12 TiKV、3 PD),成本相比 MySQL 成本节省 58%。此例子只作为得物一个业务场景的替换结果,不代表所有场景。为了验证这个结论,本文后面的内容会讲到这个核心场景的实践。
运维成本
MySQL
MySQL 作为被使用最多的开源关系型数据库,从社区活跃度、产品成熟度、周边生态工具、解决方案积累等方面来看都是非常优先的产品。主从架构的 MySQL 维护成本极低,当主库异常或无法修复时,我们只需要切换即可。
另外得益于优秀的社区生态,运维工具、数据库接入组件、数据同步组件都有非常多的成熟工具,稍加改造就可以实现本地化适配。
TiDB
分布式的架构的设计没有像 MySQL 这样的主从,每个存储节点都是提供读写。当一个节点出问题的时候,会影响整个集群的访问。无法实现 MySQL 这样通过主从切换实现快速的故障隔离。
TiDB 由 3 个角色组成,当出现问题的时候无法快速定位问题(当然也是我们个人能力需要提升的点),比如当某个时间点的查询超过预期的时候,需要排查执行计划、各个节点的负载情况、各节点的网络情况。虽然提供了完善的监控,但是指标与节点过多需要一一排查才能有结论。不像 MySQL 出现查询超预期的问题,基本上通过几个核心指标就能判断出根因。
结构变更(DDL)
MySQL
这里以我们主要使用的 MySQL 5.7 为例,较大数据量的情况下 DDL 成本较高,为了规避锁表和主从延迟的问题,一般都是用工具去执行。我们通常使用的两个知名开源无锁 DDL 工具:Percona 开源的 pt-osc、Github 开源的 gh-ost。目前我们和大部分公司一样都在通过定制化开发的 gh-ost 来变更。但是用工具只是解决了前面提到的锁表和主从延迟问题,随着数据量规模上升,变更时长也逐步上升。另外工具的 Bug 也会带来数据丢失的风险。当然 MySQL 8.0 的特性 Instant Add Column 推出以后解决了加列的痛点,但是也只解决了一部分。
TiDB
TiDB 的 DDL 通过实现 Google F1 的在线异步 schema 变更算法,来完成在分布式场景下的无锁,在线 schema 变更。DDL 变更中除过 add index 以外其他都不需要做数据回填,修改完元信息即可,所以可以立即完成。而 add index 会做两件事情:1.修改 table 的元信息,把 indexInfo加入到 table 的元信息中去;2.把 table 中已有了的数据行,把 index columns的值全部回填到 index record中去。变更速度取决于表中的数据和系统负载。所以 TiDB 在 DDL 操作上解决了很多 MySQL 上的痛点,但是与 MySQL 相比,TiDB 的 DDL 还是有些不一样的地方的,也带来了一些限制:
不能在单条 ALTER TABLE 语句中完成多个操作。MySQL 下会把多个同一张表的 DDL 进行合并,然后使用 gh-ost 或者 pt-osc 工具一次性执行。TiDB 里只能一个个单独去执行;(6.2 已经支持了ALTER TABLE语句增删改多个列或索引) 不支持不同类型的索引 (HASH|BTREE|RTREE|FULLTEXT); 不支持添加 / 删除主键,除非开启了 alter-primary-key 配置项; 不支持将字段类型修改为其超集,例如不支持从 INTEGER 修改为 VARCHAR,或者从 TIMESTAMP 修改为 DATETIME,否则可能输出的错误信息 Unsupported modify column 更改 / 修改数据类型时,尚未支持“有损更改”,例如不支持从 BIGINT 更改为 INT; 更改 / 修改 DECIMAL 类型时,不支持更改精度 ; 更改 / 修改整数列时,不允许更改 UNSIGNED 属性 ;
产品流行度
MySQL
如果我们从 MySQL 1.0 开始算起至今已经有 26 年了。这期间几经周转,最终归到了 Oracle 旗下。版本也从 1.0 来到了 8.0。作为一个久经锤炼的数据,特别是作为互联网盛行时期依赖的主流数据库,不论是产品成熟度和社区活跃度都得到了极大的促进。MySQL 在 DB-Engines 的开源数据库中排名久居第一。
TiDB
TiDB 从 2015 年创立并开源至今已经 7 年,作为一个复杂的基础软件来说确实还比较年轻。依赖早期的 3 个创始人互联网背景出身,深知大家在关系型数据库上的痛点。所以 TiDB 推出后获得了不少用户的推崇,特别是互联网行业。社区在 TiDB 的发展中也起到了至关重要的作用,从打磨产品、需求提炼、落地场景总结等。目前 TiDB 在 DB-Engines 排名为 98,进一步证明了基础软件的难度以及作为一款国产数据库在国际化进程中还有很大的空间。从墨天轮中国数据库排行的情况,可以看到 TiDB 长期以来保持第一的位置。在 12 月跌落榜首,由 OceanBase 取代。
4
TiDB 在得物的运维体系落地及探索
4.1 选型
关于数据库选型,我们一向非常谨慎,会根据具体的业务情况来推荐合适的数据库。要避免陷入“手拿铁锤的人,看什么都像钉子”的误区。不是为了使用 TiDB 而使用,要去解决一些 MySQL 无法满足或者改造成本比较高的场景。关系型数据库我们还是优先推荐MySQL。能用分库分表能解决的问题尽量选择 MySQL。毕竟运维成本相对较低、数据库版本更加稳定、单点查询速度更快、单机QPS性能更高这些特性是分布式数据库无法满足的。以下是我们总结的关于选型的两个大方向。
适合接入的场景:
分库分表场景:上游 MySQL 分库分表,业务查询时无法使用到分片 磁盘使用大场景: CPU 和内存使用率低但磁盘容量达到 MySQL 瓶颈 分析 SQL 多场景:业务逻辑比较复杂,存在并发查询+分析查询 数据归档场景:数据冷热分离、定期归档、数据重要,不能丢失 日志流水场景:日志流水业务、单表较大、写入平稳、查询不多
不适合接入的场景:
数据抽取场景:下游存在大数据或者其他业务部门进行数据抽取 读写分离的场景: TIDB 没有主从的概念,无法进行读写分离 指定点恢复场景:指定时间点级别恢复,需要恢复到某个时间点 数据热点场景:高并发单行更新、热点小表、热点库存
4.2 运维标准化
业务接入
场景:当业务选型考虑TiDB时,我们会根据业务的使用场景和业务特点综合评估是否适合TiDB(优先 推荐使用MySQL)。
配置:评估业务成本压力和未来一年数据量、TPS,选择合适的TiDB集群配置。
使用:给使用方提供 MySQL 和 TiDB 的差异及其规范,避免增加开发周期和成本。
资源规格
根据不同业务场景,我们定义了不同的服务器配置。由于借助云上的资源交付能力和隔离能力, 我们无需像 IDC 那样,在高规格机器上采用多实例部署。这样避免了混部带来两个问题:1.多个实例之间的资源争夺;2.高规则机器部署密度与稳定性的权衡。
节点 | 数量 | 配置 |
TIDB | 3 | 基础规格:8C32G200GB(云盘) 高配规格:16C64G200GB(云盘) |
PD | 3 | 基础规格:8C16G200GB(云盘) 高配规格:16C64G200G(云盘) |
Monitor | 1 | 4C16G200GB(云盘) |
TIKV/TIFLASH | 3 | 基础规格:8C32G1788G(本地SSD) 高配规格:16C64G1788G(本地SSD) |
数据库备份
备份工具:BR[官方物理备份工具] 备份策略:凌晨低峰期进行数据全量备份 备份保留周期:7天
在线业务
对于在线业务,除了常规的BR备份外会额外调整 tikv_gc_life_time 时间为 1-3 天,当业务出现误操作时可以恢复三天内任意时间的数据。 离线业务
TiDB集群离线业务大部分是从上游RDS同步到TiDB的场景。上游RDS会有一份最近的数据,所以对于离线业务只有常规的BR备份。
4.3 稳定性治理
变更管理
面向 DBA 的流程管控
面向研发变更的系统管控
DML\DDL 变更工单风险自动化识别
DDL 与 DML 类型判断,确保每次执行的内容是同一个类型 SQL 语法检查,确保提交的 SQL 语法是正确的
该项的作用是将允许执行的进行风险识别,研发可以根据风险等级选择执行时间,DBA 也能在审批阶段判断是否合理,并修改执行时间。 相关风险定义
变更类型 | 变更项 | 风险提示 |
DDL | Create table | 低 |
Add index | 测试环境(低) 生产环境(表大小,低/中/高) | |
Add column | 低 | |
Modify column 类型有限修改 | 高 | |
Modify column 长度 变长 | 低 | |
Drop index | 测试环境(低) 生产环境(高) | |
Truncate table | 测试环境(低) 生产环境(高) | |
DML | update/delete | 测试环境(低) 生产环境(修改数量,低/中/高) |
insert | 低 |
下图是基于以上提到的能力,实现的 TiDB 变更管控功能。
稳定性巡检
巡检指标的数据采集来自于监控系统,我们会统计相关指标的峰值。每天记录一个点,展示近 30 天内的指标值。
某集群的巡检情况
慢查治理
告警管理
阈值管理
故障演练
4.4 人才储备
专业认证
PingCAP 目前有三个认证,分别是 PCTA、PCTP、PCSD。前两个是早期推出面向 DBA 从业者岗位初高级认证。得物 DBA 团队有 6 位同学获得TiDB的 PCTA 认证考试、其中 5 位同学获得了进阶的 PCTP (TiDB专家)认证考试。认证虽然不能完全代表实力,但是代表了 DBA 团队对技术的追求和 DBA 团队在得物做好 TiDB 服务支持的决心与态度。
通过PCTP认证学习,团队成员深入了解TiDB数据库的体系架构、设计理念与各个组件的运行原理。学习并掌握 TiDB 数据库的体系架构,设计实践,性能监控、参数优化、故障排除、SQL优化和高可用设计。这个对于公司和团队来说就是人才和技术上的储备。
部分在职的 PCTP 得物 DBA 证书截图
运维小组
4.5 技术运营
技术分享
技术博客
课程录制
5
TiDB 在核心业务场景实践
5.1 业务痛点
5.2 解决思路
优点 | 缺点 | |
规格调整 |
|
|
数据归档 |
|
|
调整分片规则 |
|
|
分布式数据库 |
|
|
基于以上提到的问题,我们对所有的解决方案都做了对比。表格中是对四种解决方案的关键信息提炼。我们希望能够选择一个比较长期的方案,可以支撑未来 3-5 年的需求,既要解决性能问题,还要解决容量问题,又要比较低的研发成本。所以最终选择了引入分布式数据库的方案。
5.3 数据库选型
由于得物在 2020 年就引入了 TiDB。虽然没有大规模推广,但是陆续也有不少业务接入。大部分的业务把它作为 MySQL 分库分表的聚合库使用,有一小部分业务是直接接入了读写需求。基于之前的实践经验和业务需求,经过和研发团队的协商,直接采用的读写库的使用方案。另外一个方面是从只读过渡到全量读写的周期会比较长,会产生不必要的并行成本和延迟项目时间。
5.4 兼容性&性能测试
兼容性测试
性能测试
单量较少的商家场景性能测试
和预期的结果一样,由于 TiDB 分布式的架构,数据获取路径比 MySQL 要长,所以 RT 上相比 MySQL 分别多出 91%、76%、52%。从这里可以看出随着并发的上升,TiDB 和 MySQL 之间的 RT 差距也逐步缩短。由于 TiDB 可以通过扩展 DB 和 KV 节点提升 QPS 能力,我们在压测中也做了相关验证,符合预期。包括现有数据量翻一倍的基础上对性能的影响也做了验证,结论是无影响。为了方便和后面的内容对比,我们这里只提供了 RT 的指标。
单量较多的商家场景性能测试
我们挑了几个出现频率较高且查询较慢的 SQL进行测试,详情参照以下内容。
SQL1
SELECT *
FROM table_name
WHERE xx_id= 1203030
AND xx_status IN(4000, 3040)
AND is_del= 0 ORDER BY id DESC,
create_time DESC LIMIT 20
SELECT [column_name] FROM table_name
WHERE xx_id = 1203030
AND xx_status = 8010
AND close_type = 13
AND close_time > ‘2022-06-19 18:16:24.519'
LIMIT 0, 30000
SELECT * FROM table_name
WHERE xx_id= 1203030
AND xx_status IN(7000, 8000, 8010)
AND is_del= 0
ORDER BY id DESC,create_time DESC
LIMIT 20
select count(*) from table_name
WHERE(seller_id= 1203030
and is_del= 0
and biz_type in('0', '12')
and create_time>= '2021-11-01 00:00:00.0'
and create_time< '2021-11-30 23:59:59.0'
and(xx_status<> 1000 R biz_type<> 21))
关于 xxDB 特别做了处理,大家可以忽略,因为我们主要对比的是 MySQL 和 TiDB。从测试结果来看效果很好,完全满足业务侧的要求。
5.5 遇到的一些问题
SQL 执行计划
Bug
5.6 上线效果
性能收益
成本收益
大促考验
6
总结
最后特别说明下,文章中涉及一些产品的对比只是基于我们当时的场景和需求进行的分析,并不代表某个数据库产品的好坏。写这篇文章的目的是想把我们 TiDB 落地经验做个阶段性总结,顺便也能给同行们做个大方向上的参考。我们的这套方法论,理论上适用于任何一个需要再企业内部引入新型数据,并且推广的场景。本文涉及的内容和方向比较多,无法每个模块都做深入的探讨。后面我们也会把大家感兴趣的模块单独拆分出来做几期深入分享。
*文/xiaoyu
关注得物技术,每周一三五晚18:30更新技术干货