tidb5.4发版丨新功能解读(代码片段)

TiDB_PingCAP TiDB_PingCAP     2023-03-09     130

关键词:

TiDB 5.4 作为 2022 年开山之作,包含了许多有用有益的新功能和持续性的性能/稳定性提升。本文着重介绍重要新增功能和特性所带给用户的新体验和价值,按照以下章节来组织:

  • 基础性能优化和提升

  • 面向云环境的功能拓展

  • 产品易用性和运维支持

  • 新增实用性功能涉及到的系统配置开关选项

  • 主要的 bug 修复和稳定性提升

更多详细内容还可以参照 Release Notes 和 用户手册 

基础性能优化和提升

TiDB 5.4 在性能提升方面实现了以下的重要改进:查询计划可利用多个列上的索引进行高效条件过滤相关的优化工作,即通过正式支持索引合并查询优化功能,使此类查询的性能获得数量级的提升,并且具有响应时间稳定不占系统资源的突出特点;对于数据量大、读写更新频繁的分析场景, TiFlash 存储引擎的性能优化将使 CPU 占用率在现有基础上显著降低并间接帮助提升并发查询下的总体性能;最后,TiDB 5.4 在大规模数据同步场景下显著提升了同步工具 Lightning 的性能使得大规模的数据同步任务更轻松快捷

TiFlash 存储层大幅优化行存到列存转码效率

用户场景与挑战

HTAP 平台和应用中,数据更新和大量扫表行为交织在一起,存储系统的效能是影响性能和稳定性的关键因素,重度用户总是期待系统能有更好的性能并承载更多的业务。特别是 TiDB HTAP 采用了事务处理与分析查询物理分离的架构,同一份数据根据业务的需要,在后台进行自动的行式存储到列式存储的转换以分别响应 OLTP 和 OLAP 两种类型的负载。存储层大幅优化了从 TiKV “行”存储到 TiFlash “列”存储格式的转换效率,在“行 - 列”转换环节的 CPU 效率大幅提升,进而使得高负载情况下可以节约出更多的 CPU 资源用于其他环节的计算任务。

解决方案与效果

TiDB 5.4 重新梳理了 TiFlash 中行存到列存转码模块的代码架构,大量简化了冗余的数据结构和判断逻辑,采用 CPU 缓存和向量化友好的数据结构和算法,从而大幅提高运行效率。另外,新版本还相应地优化了 TiFlash 的存储引擎 DeltaTree 的默认配置,综合效果的确认参见下文。

列式存储引擎写入性能验证:在不同并发情况下吞吐性能提高 60%~90%

验证环境:

6 TiKV( 1 副本)、1 TiFlash( 1 副本),每个节点 40 个 CPU 逻辑 core,CH-benCHmark (1500 warehouse)。

CH-benCHmark 测试结果: 10 并发下部分查询(Q1、Q6)性能提高约 20%

测试环境:

3 TiKV( 3 副本)、2 TiFlash( 2 副本),每个节点 40 个 CPU 逻辑 core,CH-benCHmark (1500 warehouse)。

小结

TiDB 行存与列存之间的数据转换同步通常被外界认为是一种较大的 overhead, 但是经过努力,今后 TiDB 的行列转换在架构保持大体不变的情况下,实际运行时已经不构成明显的性能瓶颈。

TiDB 正式支持索引合并查询优化

用户场景与挑战

以往有些查询在逻辑上需要同时扫描多个列,而之前版本的 TiDB 处理区域扫描的查询中只能选择单独某一列(或多列)上的索引(或一个复合列索引),即便各列上都已经有索引但整体的性能受此影响不能达到理想状态。在 TiDB 5.4 版本中,正式提供了索引合并功能,得以允许优化器在查询处理中同时选择使用多列的索引以减少回表,达到超过一两个数量级的过滤效果。对于此类以往容易形成性能瓶颈的问题在查询时间和性能稳定性上都有较大帮助,例如(参见下文)查询的响应时间可以由 600 毫秒缩短 30 倍至 20 毫秒,并提升一个数量级的查询并发度。

解决方案

TiDB 在原有三种读数据算子基础上增加了第四种类型的算子 IndexMergeReader

  1. TableReader

  2. IndexReader

  3. IndexLookUpReader

  4. IndexMergeReader

前两种比较好理解,直接读取主表数据或者索引表数据。IndexLookUpReader(回表算子)会先读取索引表,得到 row_id,再根据 row_id 从主表中读取数据。

IndexMergeReader 执行流程类似于 IndexLookUpReader,区别在于可以利用多个索引进行回表,在如下例的场景可以极大提升查询的性能:

SELECT * FROM t1 WHERE c1 < 10 OR c2 < 100;

上述查询中如果 c1/c2 上都有索引,但是由于过滤条件是 OR,无法单独使用 c1 或 c2 索引,导致只能进行全表扫。使用索引合并可以解决无法使用索引的问题:索引合并会单独利用 c1/c2 索引得到 row_idx ,然后将两个索引拿到的 row_id 进行 UNION 操作,以 UNION 操作的结果从主表中获取实际行。

索引合并优势场景

数据来源为以 TPC-H SF 1 (lineitem 表行数为 600W),使用如下的查询来获取 lineitem 表中价格为 930,或者 orderkey 为 10000 且 comment 为特定字符串的行:

SELECT l_partkey, l_orderkey
FROM  lineitem
WHERE ( l_extendedprice = 930
OR l_orderkey = 10000 AND Substring(Lpad(l_comment, 'b', 100), 50, 1) = 'b' )
AND EXISTS(SELECT 1
FROM  part
WHERE l_partkey = p_partkey);

不使用索引合并时,执行时间为 3.38s+

使用索引合并时,执行时间为 8.3ms:

索引合并非舒适场景

如果使用过滤性很差的条件,则直接使用全表扫的性能会比使用索引合并更好

SELECT l_partkey, l_orderkey
FROM  lineitem
WHERE ( l_extendedprice >= 930     
OR l_orderkey >= 10000 )    
AND EXISTS(SELECT 1
FROM  part
WHERE l_partkey = p_partkey);

下面的查询没有使用索引合并,执行时间只有 2.34s 

使用 hint 强制优化器选择索引合并,由于需要额外的回表时间,执行时间需要 19.79s

无明显收益场景

在以下场景中,使用索引合并不会带来明显的收益 在数据量不大的情况下,由于数据很快能扫描并过滤完成,使用索引合并不会有很大收益 在过滤条件计算比较快的情况下(例如只是整型的比较),即使数据量相对较大(例如百万行级别),相对于全表扫,索引合并也不会有很大提升。

如下查询,虽然条件的过滤性很高,但是由于计算比较轻量级(只是整型的比较),计算都在 TiKV 完成,所以使用索引合并(26ms) 和不使用索引合并(30ms) 性能差异不大。

SELECT l_partkey, l_orderkey
FROM  lineitem
WHERE ( l_extendedprice <= 930     
OR l_orderkey = 10000 ) 
AND EXISTS(SELECT 1
FROM  part
WHERE l_partkey = p_partkey);

资源消耗

在索引合并优势场景的查询中,由于大部分行已经在 TiKV 过滤掉,所以 CPU/内存资源消耗基本可以忽略。

未使用索引合并的查询,由于过滤条件无法下推,导致需要将所有行都传给 TiDB 进行 Selection 操作,内存消耗较大,在 10 个并发查询情况下,TiDB 需要 2G 内存来过滤 600W 行数据。

小结

  • 在过滤条件选择率较高时,可以考虑使用索引合并。数据流量较大且过滤条件较好的场景,查询响应时间可缩短 2 个数量级(本文给出的例子是 400 倍),将秒级响应的查询变为毫秒级。
  • 索引合并可大幅减少并发查询时的系统资源消耗,特别是过滤条件无法下推的查询(消耗资源较大)可以达到颠覆性的效果(例如原本消耗 2GB 的查询,使用索引合并之后资源消耗甚至可以忽略不计)。

TiDB Lightning 新增高效的重复数据检测特性

用户场景与挑战

在生产环境中,由于历史原因,用户的各个分片 MySQL 实例的数据可能存在重复,当主键/唯一索引重复时则形成冲突数据。因此在将多个分片 MySQL 合并导入下游 TiDB 时必须进行检测和处理,且可能高达几十 TB 的单表数据量对检测效率也是一项极大的挑战。

解决方案

TiDB Lightning 是用于从 CSV/SQL 文件高速导入大规模数据到新 TiDB 集群的工具。Lightning 的 local backend 模式可将源数据编码为有序键值对,直接插入 TiKV 存储,其导入效率极高,并且支持使用多台主机并行导入一张表,是目前初始化 TiDB 集群数据的常用方式。

在 local backend 模式下,数据导入并不会经过事务写入的接口,因此无法在插入时检测冲突数据。在之前的版本, Lightning 仅能通过对比 KV 级别的校验码来实现,但局限性较大,仅能知晓发生了错误,却无法定位冲突数据的位置。

新增的重复数据检测特性使得 Lightning 精准检测冲突数据,并且内置了一种冲突数据删除算法以自动聚合。检测到冲突数据后, Lightning 可以将其保存以供使用者筛选后再次插入。

重复数据检测特性默认关闭,可以在使用时根据不同的场景需求设置 record/remove 等不同的处理方式。

详细性能验证数据可参考下表:

小结

使用 Lightning 并行导入特性,开启重复数据检测,可以精准定位数据源中的冲突数据,执行效率在多次优化后耗时占比约为总时长的 20%。

面向云环境的功能拓展

TiDB 5.4 重视与云环境的生态结合,特别推出了一项可以大幅节约存储成本的 Raft Engine日志存储引擎,可为用户节约 30% 以上的数据传输费用同时还在某些场合下有额外的性能收益;强化了数据备份效率,在支持 Amazon S3、Google Cloud Storage 的基础上,新增了对 Azure 环境的支持,完成了与世界主流云厂商存储服务的对接。

支持使用 Raft Engine 作为 TiKV 的日志存储引擎

用户场景与挑战

云环境上用户最为关心的问题之一是成本,数据存储量和 IO 请求所产生的开销不可小觑。通常来说,分布式数据库在处理用户写入时需要复制并持久化记录大量的日志,这无疑会增加用户部署服务的成本。另一方面看,由于云环境下的硬件资源有较为明确的限制,当用户负载发生波动,而预设的硬件配置无法满足时,服务质量也会受到显著影响。

解决方案

TiDB 5.4 推出一项实验性功能:Raft Engine,一款自研的 开源 日志存储引擎,相较于使用默认的 RocksDB 引擎,它最大的优势在于节省了磁盘带宽的使用量。首先,Raft Engine 将 TiDB 集群的“写入日志”压缩后直接存放在文件队列中,而不进行额外的全量转储。另外,Raft Engine 拥有更为高效的垃圾回收机制,利用过期数据的空间局部性进行批量清理,在大部分场景下不额外占用后台资源。

这些优化能够大幅降低同等负载下 TiDB 集群中存储节点的磁盘带宽使用量。这意味着,同等水平的集群将能服务更高峰值的业务输入,而同等强度的业务可以缩减部分存储节点数量来获得近似的服务水平。

另外,作为自研引擎,Raft Engine 具有更轻量的执行路径,在一些场景下显著减少了写入请求的尾延迟。

在实验环境中,TPC-C 5000 Warehouse 负载下,使用 Raft Engine 能够减少集群约 30% 的总写入带宽,并对前台吞吐有一定提升。

详情参见 用户手册 

小结

使用 Raft Engine 存储集群日志,能够有效减少写入带宽用量,节省云上部署成本的同时提升服务稳定性。

支持 Azure Blob Storage 作为备份目标存储

Backup & Restore (BR) 支持 Azure Blob Storage 作为备份的远端目标存储。在 Azure Cloud 环境部署 TiDB 的用户,可以支持使用该功能方便地将集群数据备份到 Azure Blob Storage 服务中,支持 AD 备份 和 密钥访问 两种恢复方式。囿于篇幅,具体信息请移步用户手册中的 Azure Blob Storage 备份支持 与 外部存储 章节。

产品易用性和运维支持

TiDB 5.4 持续提升产品易用性和运维效率,做出了以下的努力:为提升优化器生成执行计划的质量,增强了统计信息的收集和管理功能,可以针对不同的表、分区、索引设置不同的采集配置项并且默认保存设置,方便后续收集统计信息时沿用已有配置项;数据备份过程有时会影响正常业务,这是长久以来困扰一些用户的问题。5.4 BR 新增了备份线程自动调节功能,可显著减轻备份带来的负面影响;TiDB 运行过程中产生的大量日志数据处理不当会造成对性能和稳定性的影响,5.4 版本提供了新的实验特性可 使用 Raft Engine 保存日志,可以显著减少写流量和 CPU 使用率,提升前台吞吐减少尾延迟;此外,TiDB 自 5.4 开始 支持 GBK 字符集 

统计信息采集配置持久化

详情参见 用户手册 

优化备份对集群的影响

详情参见 用户手册 

新增实用性功能涉及到的系统配置开关选项

TiDB 5.4 对系统配置参数的优化做出了许多努力,完整信息可参见 Release notes 和相关用户手册,本文仅举其中一项代表性的改善点。

支持 session 变量设置有界限过期读

TiDB 是基于 Raft 协议的多副本分布式数据库。面对高并发,高吞吐业务场景,可以通过 follower 节点实现读性能扩展,构建读写分离架构。针对不同的业务场景,follower 可以提供以下两种读模式:

  • 强一致读:通过强一致读,可以确保所有节点读取的数据实时一致,适用于一致性要求严格的业务场景,但是因为 leader 和 follower 的数据同步延迟导致强一致读的吞吐较低、延迟较高,特别是在跨机房架构下延迟问题被进一步放大。

  • 过期读:过期读是指可以通过快照读取过去时间的过期数据,不保证实时一致性,解决了 leader 节点和 follower 节点的延迟问题,提升吞吐。该读模式适用于数据实时一致性要求较低或者数据更新不频繁的业务场景。

TiDB 目前支持通过显示只读事务或 SQL 语句的方式开启 follower 过期读。两种方式均支持“指定时间”的精确过期读和“指定时间边界”的非精确过期读两种模式,详细用法请参考 过期读官方文档 

从 TiDB 5.4.0 版本开始,TiDB 支持通过 session 变量设置有界限过期读,进一步提升易用性,具体设置示例如下:

set @@tidb_replica_read=leader_and_follower
set @@tidb_read_staleness="-5"

通过该设置,TiDB 可以通过 session 变量快速开启过期读,避免了频繁的显示开启只读事务或者在每个 SQL 内指定过期读语法,提升易用性,方便批量地实现就近选取 leader 或 follower 节点,并读取 5 秒钟内的最新过期数据,满足准实时场景下低延迟、高吞吐数据访问的业务诉求。

主要的 bug 修复和稳定性提升

自 TiDB 5.1 版本发布以来,提高稳定性不断“捉虫”,是研发和 QA 团队最优先的任务。5.4 版本总计进行了 200 余项的体验优化,其中主要部分在 Release notes 中记录,其他细节可以参考 GitHub 上的 PR 记录。TiDB 研发和 QA 团队始终秉持对用户负责的姿态,使产品日臻完善,期待赢得广大用户的信任。

PM 寄语

2022 年是广大 TiDB 用户事业虎虎生风蒸蒸日上的一年,希望 TiDB 5.4 能给用户带来更多的舒心,更多的便利,助力各种应用和业务的健康高效发展。敬请关注 TiDB 官网 , GitHub 以及各种社交媒体账号,谨代表 TiDB 产品经理(PM) 团队、研发工程与质量团队一道,期待与广大用户一起开创更美好的一年。如果您对 TiDB 的产品有任何建议,欢迎来到 internals.tidb.io 与我们交流。

查看 TiDB 5.4.0 Release Notes ,立即 下载试用 ,开启 TiDB 5.4.0 之旅。

新书推荐——华为·无线局域网应用技术(微课版丨第2版)(代码片段)

新书推荐——华为·无线局域网应用技术(微课版丨第2版)近日,由正月十六工作室组编,黄君羡主编的教材《无线局域网应用技术(微课版丨第2版)》在人民邮电出版社正式出版。无线局域网应用技术... 查看详情

新书推荐——华为·无线局域网应用技术(微课版丨第2版)(代码片段)

新书推荐——华为·无线局域网应用技术(微课版丨第2版)近日,由正月十六工作室组编,黄君羡主编的教材《无线局域网应用技术(微课版丨第2版)》在人民邮电出版社正式出版。无线局域网应用技术... 查看详情

解读appstore新功能:自定义产品页面和a/btest工具(代码片段)

????????关注后回复 “进群” ,拉你进程序员交流群????????一、前言可能很多开发者还没有意识到,今年WWDC21推出《GetreadytooptimizeyourAppStoreproductpage》[1]是一个重磅功能!因为iOSapp下载的地方,目前只有一个:A... 查看详情

aop之javassist应用于自动实现eventbus解读(代码片段)

解读demo:https://github.com/north2016/T-MVP一.前言javassist是一个操作class文件即class字节码的动态类库;在打包过程中,用来检查、”动态”修改以及创建Java类。其功能与jdk自带的反射功能类似,但比反射功能更强大。为了方... 查看详情

全面解读php面试-常量及数据类型(代码片段)

本文主要讲解字符串的定义方式,数据类型和常量的相关内容。一、字符串的定义方式1、字符串的定义方式除了单双引号外,还有一种叫heredoc和newdoc 在我们需要定义很长一段儿字符串的时候需要用到heredoc。它的格式如下:... 查看详情

kubernetes之pod超详细解读--第二篇(代码片段)

8.资源对象对pod的调度??在kubernetes集群中,pod基本上都是容器的载体,通常需要通过相应的资源对象来完成一组pod的调度和自动控制功能,比如:deployment、daemonSet、RC、Job等等。接下来小编将一一介绍这些资源对象如何调度pod。... 查看详情

图文解读mysqlinnodbundolog(代码片段)

什么是UndoLog?如何理解UndoLogUndoLog的功能UndoLog的存储结构UndoLog的工作原理UndoLog的类型UndoLog的生命周期UndoLog的配置参数参考文章文章导读:什么是UndoLog?Undo:意为撤销或取消,以撤销操作为目的,返回某个状... 查看详情

12节,完稿&发版(代码片段)

作者:小傅哥博客:https://bugstack.cn沉淀、分享、成长,让自己和他人都能有所收获!😄一、前言💥为什么?写写快乐的热门文章不好吗!从开始准备成体系的编写IDEAPlugin知识内容前,我就知... 查看详情

tidbv6.2发版(代码片段)

TiDBv6.2于8月23日发布了。在全新的版本中,TiDB提供了诸多方面的提升,它们主要集中于:可观测性、性能、稳定性、数据生态加强以及MySQL兼容几个领域。可观测性在新版本中,TiDBDashboard支持了可视化执行计划。... 查看详情

tidbv6.2发版(代码片段)

TiDBv6.2于8月23日发布了。在全新的版本中,TiDB提供了诸多方面的提升,它们主要集中于:可观测性、性能、稳定性、数据生态加强以及MySQL兼容几个领域。可观测性在新版本中,TiDBDashboard支持了可视化执行计划。... 查看详情

springboot3.0正式发布及新特性解读(代码片段)

...布更新的还有2.7.x和2.6.x两条版本线,SpringBoot是我见过的发版最守时的技术框架之一。SpringBoot3.0现已正式发布,它包含了12个月以来151个开发者的5700多次代码提交。这是自4.5年前发布2.0以来,SpringBoot的第一次重大修订。它也是... 查看详情

万字长文-解读功能开关|idcf(代码片段)

...是一组模式,可以帮助团队快速但安全地向用户提供新功能。在这篇关于功能开关的文章中,我们将从一个简短的故事开始,展示功能开关有用的一些典型场景。然后我们将深入研究细节,涵盖有助于团队通过功... 查看详情

记一次生产发版时springboot服务停用启用的问题(代码片段)

...接做成linux服务来启动和停用。然而,每次通过jenkins构建发版,项目构建完毕,还要手动再去重启服务。听交接的同事说,可能是有一个钩子阻止服务停用了。但是,我还是有点纳闷的,既然阻止了服务停用,按道理服务是还能... 查看详情

使用composedesktop开发一款桌面端多功能apk工具(代码片段)

...着,而且还有几个马甲包也要维护,不知道大家发版的时候复杂不复杂,反正我们每次发版的时候都需要经历–打包、加固、对齐、重签名、打渠道 查看详情

解读数仓中的数据对象及相关关系(代码片段)

摘要:为实现不同的功能,GaussDB(DWS)提供了不同的数据对象类型,包括索引、行存表、列存表及其辅助表等。这些数据对象在特定的条件下实现不同的功能,为数据库的快速高效提供了保证,本文对... 查看详情

tidb6.5lts发版(代码片段)

在2023伊始,我们很高兴向大家宣布,TiDB6.5LTS版本已经发布了。这是TiDBV6的第二个长期支持版(上一个是TiDB6.1),除了携带了诸多备受期待的新特性,同时也将得到TiDB开发社区的长期维护,是推荐企业... 查看详情

vue源码解读1(代码片段)

前言vue是一个非常典型的MVVM框架,它的核心功能一是双向数据绑定系统,二是组件化开发系统。那么本文是以一种通俗易懂的的角度来实现一个简单的双向数据绑定系统,如果你用过vue却对vue的实现原理不太清楚,或者没用过vu... 查看详情

若依框架登录,token,自定义session,鉴权等前后端流程解读(代码片段)

背景之前虽然讲了login,getInfo,getRoutes的三个接口,但从设计的角度来讲,这3个接口并没有完整实现一个功能。这里重点讲解若依框架对于自定义session,token校验,权限验证三个方面的实现。这些对于自己实现一个简单... 查看详情