作者:田帅萌,主要负责同程旅行TiDB、Redis、dts等技术栈。
一、背景
为了更好的保障业务稳定性,针对老的TiDB集群进行升级操作。期望在五一之前把一部分的TiDB集群升级完成。
因为每年五一、十一 这套TiDB集群都会有偶发的性能问题,导致业务报错。本质的原因是业务SQL复杂,索引数量多,导致优化器走错索引,造成全表扫描,Tikv cpu消耗异常,TiDB内存OOM。
在升级完成后,今年的五一期间,这套TiDB集群平稳运行,未造成故障,性能还有一定提升。通过TiDB的可观测性,能够发现问题SQL进行优化。
在跟TiDB的小伙伴交流中,得知当前版本和后续版本的主攻计划:
在TiDB 456 系列版本中,主要追求的是性能。
在TiDB 7系列版本,要求是主攻稳定性。
二、收益
2.1从性能的角度来说:
大概有至少一倍的性能提升,升级之前:
升级之后:
2.2 从稳定性和故障角度:
至少今年五一,这套TiDB集群平稳运行
2.3 从可观测行的角度:
2.3.1 dashboard 可分享
可以分享给业务同学,业务也能通过dashboard 更直观的发现慢查询。
之前的版本中,dashboard采用root账户登陆,权限太大。而新的版本中采用了dashboardAdmin 账户更安全。
2.3.2 topSQL 使SQL无处遁行
比如通过监控发现TiKV cpu升高
完全可以通过top SQL 发现问题SQL
2.3.4 SQL执行计划绑定更方便
然后在根据SQL进行优化,比如添加SQL 或者绑定执行计划等手段。
现在SQL执行计划绑定也特别方便,可以在SQL语句分析里面,绑定执行计划
三、升级的流程
这套TiDB集群毕竟核心,所有没有采用原地升级的方式,进行升级操作。而是采用新建一套集群 数据导入的方式进行。
主要的考虑 毕竟跨了2个大版本,以及这套集群的重要性。
为了升级这套集群,做了很多准备工作,可以简单分享一下。
表结构和数据导入
数据校对,业务角度校对,DBA抽样校对,用于保障数据一致性。
历史的绑定计划,人工导入到新的集群。避免SQL走错索引,造成性能问题。
慢查询SQL 在新的集群,手动跑,进行性能校对。(我们自研了一个流量回放工具,主要用于MySQL的升级校对,理论上支持TiDB,但没进行测试,后续计划切换之前,先跑一次流量回放)。也可以先跟业务切预发环境,业务在预发环境进行测试,SQL兼容性以及性能。
四、升级期间遇到的问题
4.1 由于参数 设置问题,导致执行计划走错,性能下降严重。
参数 tidb_opt_agg_push_down 默认是关闭的。
这个变量用来设置优化器是否执行聚合函数下推到 Join,Projection 和 UnionAll 之前的优化操作。当查询中聚合操作执行很慢时,可以尝试设置该变量为 ON。
因为这套集群 都是 Join 等复杂SQL,理论上开启这个参数有性能提升,这套集群并没有开启tiflash,导致了执行计划跟旧集群完全不一样,没有正收益,有负收益而且影响很大。
由于目前 TiDB 优化器的 CBO 能力还不够完善,类似这样的参数还不能默认打开。这个变量对于 AP tiflash 来说大部分时间都是正收益,需要的时候可以考虑在确定打给 tiflash 的 query 连接上开启。
建议:默认参数不要动~
4.2 新的集群 copr_cache 没命中
通过 explain ANALYZE SQL 发现
增加配置 tikv-client.copr-cache.capacity-mb: 3000.0 (默认1000.0)
TiDB-server的参数,缓存的总数据量大小。当缓存空间满时,旧缓存条目将被逐出。
当TiDB-server内存充足的情况下才能调整此参数。
五、未来规划
后续集群升级到7.x系列,我个人更看好8.1这个版本。
8.1这么多稳定性和性能提升。TiDB越来越好。
六、给TiDB的建议
6.1 完善复杂SQL的执行计划绑定
目前此功能不适用于带有子查询的查询、访问 TiFlash 的查询或连接 3 个或更多表的查询。
6.2 旧集群的执行计划绑定历史
从7.1开始 及以上版本,可以down出来,导入新集群。(只要把mysql.bind_info 导出到新集群导入即可)
需要重新加载 强制重新加载绑定信息 ADMIN RELOAD BINDINGS;
注:导入进去最好再验证下,新老版本要是有语法兼容变化可能导致部分bind 失效。
6.3 TiDB针对大容量磁盘的支持
TiDB 针对大容量磁盘支持,比如支持单个tikv 7T容量。
七、TiDB降本手段
针对历史数据,归档数据,进一步压缩,利用cpu换空间,比较适用写多,几乎不读历史数据的场景。可以修改参数
raftdb.defaultcf.compression-per-level:no no zstd zstd zstd zstd zstd
raftdb.writecf.compression-per-level:no no zstd zstd zstd zstd zstd
rocksdb.defaultcf.compression-per-level: no no zstd zstd zstd zstd zstd
rocksdb.writecf.compression-per-level :no no zstd zstd zstd zstd zstd
如果是6系列版本可以进一步修改
coprocessor.region-max-size: 128M
coprocessor.region-split-keys: 1280000
coprocessor.region-split-size: 128M
增大 region size
八、总结
这次TiDB集群的升级之旅让我深刻体会到了细致规划和准备的重要性。通过与TiDB社区的交流和反馈,我看到了产品不断进步的可能。我相信,随着TiDB的不断发展,它将为用户提供更加稳定、高效和易用的数据库解决方案。同时,我也期待未来能够与社区共同探索更多提升性能和降低成本的方法。
我们也可以看到TiDB集群升级对于提升性能、增强稳定性以及优化资源使用具有显著效果。我的亲身经历展示了升级过程中的细致规划和对潜在问题的深思熟虑,同时也反映出了TiDB社区对于产品持续改进的承诺和努力。 总结如下:
- 性能与稳定性提升:升级后的TiDB集群在高负载情况下表现出色,性能得到至少一倍的提升,同时在重要的业务高峰期保持了稳定性。
- 可观测性的增强:新版本通过改进的dashboard和top SQL功能,使得慢查询和问题SQL的识别变得更加直观和便捷,同时提升了安全性。
- 升级策略:采取了新建集群和数据迁移的策略,以避免原地升级可能带来的风险,并通过详尽的准备工作确保了数据的一致性和完整性。
- 问题解决:在升级过程中遇到的问题,如参数配置导致性能下降和copr_cache未命中,都通过调整配置和增加缓存容量得到了有效解决。
- 成本优化:通过数据归档和压缩,利用CPU资源优化存储空间使用,为写入密集型场景提供了成本效益高的解决方案。
- 社区互动的重要性:在与TiDB团队的交流反映了社区的开放性和对用户反馈的重视,这对于开源项目的长期发展至关重要。 总体而言,这篇文章不仅为TiDB用户提供了升级的参考经验,也为开源社区的互动和发展提供了宝贵的见解。通过不断的技术创新和社区合作,TiDB正朝着更高效、更稳定、更易用的分布式数据库系统迈进。
在此,特别感谢下表妹、瓜哥、军军的支持。