作者:田帅萌,TiDB 社区北京地区组织者,布道师组委会成员,主要负责同程旅行TiDB、Redis、dts等技术栈。



背景:

作为一个 TiDB 老从业者,说实话在 TiDB v4 版本中确实存在一些性能抖动的情况。

随着 TiDB 研发团队的不断迭代和优化,这些问题已经得到或正在得到有效的解决和改善。

TiDB 社区以及官方也在推荐用户升级到 v7 或者 v8 版本,获得更稳定更好的产品体验。

TiDB 在 V4 版本的抖动的情况,根据多年维护经验主要集中在以下问题:

一、GC 效率低,导致部分 tombstone key 需要经过多轮的 GC 才会得到有效的清理。

二、添加索引,TiDB 在早期版本已经提供 Online DDL 的能力,但创建索引在扫表回填索引的时候会消耗大量资源。

三、扩容节点/删除节点,默认的 TiKV 底层 Region、Leader 调度并发方案影响到请求延迟。

四、统计信息错误,关系型数据库的优化器成本模型强依赖统计信息,自研 TiDB 统计信息挑战在所难免。

除了上述几个方面之外,在 TiDB 的老版本架构中,大量的 IO 读写响应对磁盘敏感度很高。也就说如果磁盘性能越好,抖动的感知就越小,磁盘性能越差,就会抖动得越明显。

但在 TiDB 的 v7 版本,研发团队对此进行了一系列优化,如 TiKV LSM-tree 优化、存储引擎优化等,逐步提高缓存及内存利用,数据写入和读取稳定性、性能优化等,响应速度也快了许多,老版本的问题在新的版本也得到了解决。



解决办法

架构修改:只要在TiKV层面,增加一层内存,数据写入和读取先经过一层内存,速度自然就快了。除此以外,像之前老版本的问题在新的版本也得到了解决。目前还在做,在未来的版本就会看见。

下面一起看看 TiDB v7 如何解决抖动的问题。



一、 GC 持续优化

在TiDB v7.1.0之前的版本,由于MVCC机制的局限,RocksDB中的数据版本在写入后很难被自动清理,导致数据冗余。这就像是一些不再需要的旧物品堆积在仓库中,占用空间却无法自动丢弃。为了解决这个问题,TiDB 提供了一种手动清理的方法,即通过手动压缩特定数据区域来触发GC(垃圾收集),类似于给仓库来个大扫除,清理掉那些不再需要的旧物品,从而为新物品腾出空间。

从TiDB v7.1.0版本开始,引入了改进的MVCC机制,这大大减少了数据冗余的问题,大多数情况下可以自动处理,减少了手动干预的需求。这就好比升级了仓库管理系统,使其能够智能识别并丢弃无用物品,保持仓库的整洁和空间的有效利用。简而言之,TiDB的这些改进让数据库的维护变得更加高效和自动化,我们在版本升级到 v7 以后,也验证这一功能优化后带来的收益。

延伸阅读 TiKV 内核原理解析:

1.TiDB MVCC 版本堆积相关原理及排查手段

https://cn.pingcap.com/blog/tidb-mvcc-mechanism-and-troubleshooting/

2.TiDB 组件 GC 原理及常见问题(GC 改善)

https://cn.pingcap.com/blog/garbage-collection-principle-and-common-problems

3.TiKV 组件内 GC 原理及常见问题(GC 改善)

https://cn.pingcap.com/blog/garbage-collection-principle-and-common-problems-in-tikv/


实践

我们有一个场景需求,在一套 100TB 规模集群中,由 DBA 手动删除 50T 的大库,执行drop table 分配删除,一次删除20T,删除动作到彻底清理掉数据,业务连续性没有受到影响,请求处理没有发生抖动现象。CF(Column Family)size 缓慢清理掉 50TB 的数据。

TiDB 究竟抖还是不抖?_tikv

TiDB 究竟抖还是不抖?_docs_02



二、添加索引

TiDB 提供 Online DDL 的功能在我们业务开发迭代中重度使用,但由于创建索引在扫表回填索引的时候会消耗大量资源,甚至与一些频繁更新的字段会发生冲突导致正常业务受到影响。大表创建索引的过程往往会持续很长时间,所以要尽可能地平衡执行时间和集群性能之间的关系,比如选择非高频更新时间段。

TiDB v6.5.0 支持多表 DDL 并行执行、支持 Fast DDL 在线添加索引提速 10x、支持单一 SQL 语句增删改多个列或索引、并支持轻量级 MDL 元数据锁彻底地解决了 DDL 变更过程中 DML 可能遇到的 information schema is changed 的问题。TiDB 在 TiDB Cloud 和 TiDB 私有化版本部署产品内核是一样的,所以我们也在 v7.1 版本也享受到开源软件的优化。

延伸阅读  Online DDL 的优化原理:

https://cn.pingcap.com/blog/10-times-online-ddl-performance-improvement/



三、扩容节点/删除 Tikv节点

扩容和删除Tikv节点,抖动与不抖动取决于参数。store limit 设置,设置的大,迁移速度就快,设置的小,迁移速度就慢,磁盘的影响严重就越快。在之前的版本需要用户手动调整。

在TiDB v7的版本中新增了参数,简单来说需要用户关心会自动调整。

新增基于 snapshot 执行细节来自动调整 store limit 大小的控制器。将 store-limit-version 设置为 v2 即可开启该控制器,开启后,用户无需手动调整 store limit 配置来控制扩缩容的速度 。



四、统计信息错误,导致SQL走错索引。

这个问题,我理解是数据库开发或者优化最难的问题。无论是 MySQL 开源数据库,还在SQLsever 商业数据库,在统计信息优化和迭代过程中,统计信息的稳定性问题都有存在。先说一下TiDB的优化器方面的迭代吧

TiDB v6.2.0 引入了新的代价模型 Cost Model Version 2,Cost Model Version 2 对代价公式进行了更精确的回归校准,调整了部分代价公式,比此前版本的代价公式更加准确。

再说一下如何解决这个问题

1.通过监控的手段 发现 SQL 走错索引,TiDB 在 Dashboard 中提供丰富的 SQL 状态以及慢查询可观测性功能,可以将 TopN 以及 Slow Query 以白屏化、可视化的方式展现给 DBA 进行排查以及优化;

2.定期收集统计信息,TiDB 提供自动收集信息功能以外,还提供针对自动收集统计信息的并发度调整,大表统计信息在地线程池收集完成。

如果发生走错索引的情况,可以先绑定执行计划,然后在收集统计信息。

延伸阅读 TiDB 统计信息原理解析以及统计信息实践方法:

1.统计信息 https://docs.pingcap.com/zh/tidb/v7.1/statistics

2.并行收集统计信息

https://docs.pingcap.com/zh/tidb/v7.1/statistics#tidb_index_serial_scan_concurrency



五、 LSM 树和存储引擎优化

Time to Live (TTL) 是一种在TiDB中用于自动管理数据生命周期的行级策略。通过为表设置TTL属性,可以指定数据的存活时间,过期后系统将自动清理这些数据。使用场景:处理验证码、短链接记录、历史订单等需要定期删除的信息,以及自动清除计算过程中的临时数据。

TTL的并发设计允许它在不干扰在线业务的情况下,跨多个TiDB Server节点进行高效的并行删除操作。重要的是,TTL提供了一种灵活的清理方式,但并不保证数据会立即被删除。这意味着即使数据已过期,用户在某些情况下可能仍能读取到这些信息,直到它们最终被系统后台任务处理并删除。简而言之,TTL为TiDB用户提供了一个高效、自动化的数据过期处理方案。

TiDB 数据库对于 TiKV 和 RockDB 都在不断完善compaction机制,以期降低 LSM Tree 带来的读放大、写放大以及空间放大问题,进一步提升系统性能。同时TiKV中提供了丰富的监控指标用于监控GC 、Compaction等,方便用户掌握相关运行情况、排查write stall等问题原因。



**六、新增plan cache **

TiDB 优化器对这两类查询的处理是一样的:Prepare 时将参数化的 SQL 查询解析成 AST(抽象语法树),每次 Execute 时根据保存的 AST 和具体的参数值生成执行计划。

当开启执行计划缓存后,每条 Prepare 语句的第一次 Execute 会检查当前查询是否可以使用执行计划缓存,如果可以则将生成的执行计划放进一个由 LRU 链表构成的缓存中;在后续的 Execute 中,会先从缓存中获取执行计划,并检查是否可用,如果获取和检查成功则跳过生成执行计划这一步,否则重新生成执行计划并放入缓存中

TiDB 在 Prepare Plan Cache 功能:

https://docs.pingcap.com/zh/tidb/v7.1/sql-prepared-plan-cache


七、RC(Read Committed)优化

Read-Commited 隔离级别需要在悲观事务模式下,在悲观事务中每个 SQL 执行时会从 PD 获取 TSO (for_update_ts) 用于一致性读、冲突检测等,每个 SQL 相当于一个 Snapshot-Isolation 的’小事务’,相比乐观事务模式悲观事务产生的 TSO 请求会更多,在整个事务期间如果能在不破坏事务一致性和隔离性的情况下减少 tso 请求次数,就能够降低PD的负载和事务延迟,从而提升整体性能。


八、OOM 的优化

TiDB 在解决TiDB-sever 层的OOM问题,主要的解决办法

1、计算下推,推到存储层。

2、中间层缓存到磁盘。

3、更多的内存层面的限制与优化



九、个人升级收益实践

升级之前:

注:因为手里没有4和4之前的集群,只有v5的集群,所以不好展示抖到不抖的收益。

升级之后:

TiDB 究竟抖还是不抖?_https_03

TiDB 究竟抖还是不抖?_docs_04

升级之后的 1-2 个月左右,999-duration 延迟稳定在 250ms 以内。



最后

同程目前已有大约70套TiDB,核心服集群已经升级完毕,升级到7.1.5 。新增集群版本统一在 7.1.5。目前整体顺利,无故障,保障了 五一和暑期。