作者:田帅萌,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 提供 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的集群,所以不好展示抖到不抖的收益。
升级之后:
升级之后的 1-2 个月左右,999-duration 延迟稳定在 250ms 以内。
最后
同程目前已有大约70套TiDB,核心服集群已经升级完毕,升级到7.1.5 。新增集群版本统一在 7.1.5。目前整体顺利,无故障,保障了 五一和暑期。
推荐:TiDB升级活动
社区和个人(升级导师)宗旨,让用户用更好的TiDB。
升级活动:https://asktug.com/t/topic/1025499