tidb6.0:让tso更高效丨tidbbookrush(代码片段)

TiDB_PingCAP TiDB_PingCAP     2022-11-29     627

关键词:

本文作者:h5n1,TiDB爱好者,目前就职于联通软件研究院,asktug 主页

1. 前言

TiDB 作为一个分布式数据库,计算节点 tidb server 和存储节点 tikv/tiflash server 有着近乎线性的扩展能力,当资源不足时直接在线扩容即可。但作为整个集群大脑的 PD 节点因为只有 leader 提供服务,不能向其他组件一样通过扩展节点而提高处理能力。

目前 TSO 分配的主要问题:

  1. TSO 分配由 PD Leader 节点提供,大量请求下会导致 Leader 节点 CPU 利用率增高,影响事务延迟。

  2. PD Follower 节点基本处于空闲状态,系统资源利用率较低。

  3. TiDB 跨数据中心访问 PD Leader 时,数据中心间的延迟导致事务延迟增加。

为提升 TSO 的处理性能针对部分场景 TiDB 引入了 TSO Follower Proxy、RC Read TSO 优化、Local TSO 等特性,通过扩展 PD 处理能力和减少 TSO 请求的方式,提升整体吞吐量,降低事务延迟。

2. TSO

TSO 是一个单调递增的时间戳,由 PD leader 分配。TiDB 在事务开始时会获取 TSO 作为 start_ts、提交时获取 TSO 作为 commit_ts,依靠 TSO 实现事务的 MVCC。TSO 为 64 位的整型数值,由物理部分和逻辑部分组成,高 48 位为物理部分是 unixtime 的毫秒时间,低 18 位为逻辑部分是一个数值计数器,理论上每秒可产生 262144000(即 2 ^ 18 * 1000)个 TSO。

为保证性能 PD 并不会每次为一个请求生成一个 TSO,而是会预先申请一个可分配的时间窗口,时间窗口是当前时间和当前时间+3 秒后的 TSO,并保存在 etcd 内,之后便可以从窗口中分配 TSO。每隔一定时间就会触发更新时间窗口。当 PD 重启或 leader 切换后会从 etcd 内获取保存的最大 TSO 开始分配,以保证 TSO 的连续递增。

3. Follower Proxy

默认情况下 TSO 请求由 PD leader 处理,TiDB 内部通过 PD Client 向 PD leader 发送请求获取 TSO,PD client 并不会将收到的请求立刻发送给 PD leader ,而将同一时刻收到的所有请求打包发送给 PD leader,然后由 PD leader 返回一批 TSO。由于仅有 leader 提供服务,tidb server 数量较多时会有较多的 PD Client 和 PD Leader 建立连接,导致切换处理连接请求时 CPU 消耗较高。同时 follower 节点仅通过 raft 同步数据和提供选举等功能,基本处于空闲状态。

在 5.3.0 版本引入 TSO Follower Proxy 功能,当开启后 tidb 的 PD Client 会随机选择一个 PD 节点(包括 leader 和 follower )发送 TSO 请求,PD Follower 会作为一个代理服务将收到的一批请求按照默认情况下 PD Client 处理 TSO 方式打包发送给 leader 处理,以进一步减少 PD Client 和 PD Leader 的交互次数以及 PD leader 的连接数,以此降低 leader 的 CPU 负载。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IMpqCUk9-1656300380513)(https://tidb-blog.oss-cn-beijing.aliyuncs.com/media/1654048816(1)]-1654048828624.jpg)

通过设置全局变量 tidb_enable_tso_follower_proxy 为 true 即可开启 PD follower 的 TSO 代理功能,该功能适用于 tidb server 数量较多并发请求很高,PD leader 因高压力的 TSO 请求而达到 CPU 瓶颈,导致 TSO RPC 请求的延迟较高的场景。

4. RC Read TSO 优化

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

6.0 版本中对 RC 事务中的 SELECT 语句 TSO 请求做了优化,使用一种乐观方式获取 TSO ,仅当遇到新版本后才会获取最新的 TSO 读取数据,通过减少读操作从 PD 获取 TSO 的请求次数,从而降低查询延迟,提升读写冲突较小场景的 QPS。该特性由 tidb_rc_read_check_ts 变量控制,默认为 off,开启该功能设置为 on 即可。

优化后 select 语句处理基本过程如下:

  1. Select 语句执行时不从 PD 获取 TSO 作为 for_update_ts,而是使用上一个有效的 TSO 作为 for_update_ts(即为 read_ts)。如果是事务中的第一个语句则是 start_ts,否则是上一个 SQL 的 for_update_ts。

  2. 构建执行计划并执行,发送到 tikv 的数据读取请求(pointget、coprocessor)会带上 RcReadCheckTS 标志。

  3. 数据读取请求使用前面获得的 read_ts 做一致性读取,并将数据返回 tidb server。

  4. TiKV 会检查返回的数据是否有更新版本,如果有更新的版本则返回 WriteConflict 错误,否则返回数据后正常结束执行。

  5. 如果此时 tidb 还未向 client 发送数据则会从 PD 获取最新的 TSO 作为 for_update_ts 重新执行整个查询,否则会向 client 返回错误。

从上面的过程可以看出当遇到新版本后会导致 tidb server 使用正常的流程重新获取 TSO 和执行 SQL,在读写冲突的情况下会降低性能使得事务执行时间延长。如果已经有部分数据返回 client 的话会导致报错 SQL 执行失败,虽然通过增加 tidb_init_chunk_size 变量大小延迟 tikv 返回数据时间,可以降低一些上述错误发生的情况,但仍然不是一个根本解决方式。

5. Local TSO

在多数据中心场景下 PD leader 位于某个数据中心内,数据中心间的延迟会造成 TSO 请求延迟增加,如果能够在数据中心内完成 TSO 请求和分配则可以大大降低 TSO 请求延迟。基于此 tidb 引入了 Local TSO (实验功能),PD 中设计 2 个 TSO allocator 角色:local tso allocator 和 global tso allocator,相应的事务也被分成了本地事务 local transaction 和全局事务 global transaction 两种。

  • Local TSO

当通过 enable-local-tso 启用后数据中心内的 PD 会选出一个节点作为 local tso allocator 用于分配 TSO,该节点作为 local tso 分配的 leader 角色( PD 角色仍为 follower )。当事务操作的数据仅涉及到本数据中心的数据时,则判断为本地事务,向本地 tso allocator 申请 local tso。

每个数据中心分配自己的 local tso,相互之间是独立的,为避免不同数据中心分配了相同的 TSO,PD 会设置 local tso 中的逻辑时间低几位做后缀,不同的数据中心使用不同的值,同时这些信息会持久化记录到 PD 内。

  • Global TSO

当事务操作的数据涉及到其他数据中心时则为全局事务,此时需要向 PD leader 申请 global tso, PD leader 作为 global tso allocator。当未启用 local-tso 功能时,仍按原来的逻辑所有数据中的 TSO 请求由 PD leader 负责处理。

为保证 local tso 和 global tso 的线性增长,global tso allocator 和 local tso allocator 会进行 max_tso 同步:

  1. Global tso allocator 收集所有 local tso allocator 的最大 local tso。

  2. 从所有 local tso 中选出一个最大的 local tso 作为 max_tso 下发到 local allocator。

  3. 如果 max_tso 比自己的大则更新 TSO 为 max_tso,否则直接返回成功。

Local tso 的使用需要考虑不同的数据中心处理不同的业务,同时要结合 PlacementRules in SQL 将表根据业务规则按数据中心进行分布,同时可设置 txn_scope 变量为 local/global 用于人为控制获取 global tso 还是 local tso.

基本配置步骤 (目前不支持 Local TSO 回退为 Global TSO 模式):

  1. PD、TiKV、TiDB server 均需要根据实际部署设置 label,为保证高可用每个 DC 的 PD 数量应>1。

  1. 开启库或表级 Placement Rules in SQL,根据地域和业务关系进行调度。

CREATE PLACEMENT POLICY dc1_leader LEADER_CONSTRAINTS="DC1" FOLLOWER_CONSTRAINTS="DC1,DC2,DC3" FOLLOWERS=2; Alter table new_order PARTITION p0 PLACEMENT POLICY dc1_leaders;

  1. 设置 PD 参数 enable-local-tso=on 使用 tiup reload 重启 PD 开启 Local TSO 功能。启用之后可通过 pd-ctl -u pd_ip:pd_port member 中 tso_allocator_leaders 项内容查看每个中心的 local tso allocator leader。

6. 测试

6.1 测试环境

6.2 TSO Follower Proxy

在 1024 线程下使用 sysbench 对 6 张 1 亿记录表在开启 TSO Follower Proxy 前后的 TPS 和平均延迟如下:

测试期间 TSO Follower Proxy 关闭和开启时的 CPU 利用率:

6.3 RC Read TSO

使用 tiup-bench 测试不同线程下开启 tidb_rc_read_check_ts 前后的 TPCC,可以看到开启该功能后对 TPCC 有一定提升,但随着线程数增加冲突增多 TPCC 出现下降情况。

通过 TiDB –> PD Client –> PD Client CMD OPS 监控可以看到 256 线程下开启 tidb_rc_read_check_ts 后 PD client 中等待 TSO 的次数明显降低。

6.4 Local TSO

Local TSO 作为实验功能尚需完善,TPCC 测试中当开启该功能后出现大量报主键重复错误。

7. 总结

为提升 TSO 的扩展性和效率,TiDB 进行了大量的优化工作,但这些优化有确定的场景,需要结合业务和实际情况考虑,否则盲目开启有可能会造成 QPS 降低、延迟增高的情况:

对于 Follower TSO Proxy 适合于由于 PD Leader CPU 繁忙导致的 TSO 获取延迟的场景,通过开启 Follower Proxy 后降低 leader 的压力。

RC Read TSO 优化适合于读多写少的场景,如果数据冲突严重反而会造成性能下降。

Local TSO 作为 TiDB 分布式授时方案从理论上能够解决因数据中心间的延迟造成的 TSO 延迟,不过目前实验功能尚有一些问题。

CSDN 社区图书馆,开张营业! 深读计划,写书评领图书福利~

区服分析丨更透彻的游戏营运数据解读,助力高效增长

全民买量时代,新服和新区持续增开,对玩家长线留存及付费提升显得尤为重要。在分析游戏活动效果和玩家营运数据时,相信大家都曾有过这样的疑问:不同区服玩家的表现如何对比分析?怎样合理评估新... 查看详情

区服分析丨更透彻的游戏营运数据解读,助力高效增长

全民买量时代,新服和新区持续增开,对玩家长线留存及付费提升显得尤为重要。在分析游戏活动效果和玩家营运数据时,相信大家都曾有过这样的疑问:不同区服玩家的表现如何对比分析?怎样合理评估新... 查看详情

让 SQL 查询更高效

】让SQL查询更高效【英文标题】:MakingSQLquerymoreefficient【发布时间】:2011-06-1401:10:53【问题描述】:如何让这个SQL查询更有效率?SELECT(SELECTCOUNT(*)FROMtableWHEREprice<10)ASpriceUnder10,(SELECTCOUNT(*)FROMtableWHEREpriceBETWEEN10AND20)ASprice10to20,(SEL 查看详情

数商云采购管理系统解决方案丨让企业与供应商高效协同

一般来说,越是大型单位对采购的需求相对较大,特别传统制造业、金融行业、工程行业等高密集的采购单位,但是按照传统的采购方式,太多的痛点亟待解决:1、制造行业面临的采购问题:(1)... 查看详情

老男孩逆袭思想:it新手如何让提问更高效?

老男孩逆袭思想:IT新手如何让提问更高效? 查看详情

无法让 SDSF 响应 TSO 或批处理命令

】无法让SDSF响应TSO或批处理命令【英文标题】:CannotgetSDSFtorespondtoTSOorbatchcommands【发布时间】:2020-06-0712:32:48【问题描述】:我正在尝试编写一个JCL作业步骤,它将检索活动(此)作业的JESMSGLG、JESJCL和JESLOG数据集。这里的想法... 查看详情

让 C# mandelbrot 绘图更高效

】让C#mandelbrot绘图更高效【英文标题】:MakingC#mandelbrotdrawingmoreefficient【发布时间】:2013-06-2816:37:05【问题描述】:首先,我知道这个问题听起来确实好像我没有搜索过,但我确实搜索过很多次。我为C#编写了一个小的Mandelbrot绘... 查看详情

tso和gso

...发送到网卡之前判断网卡是否支持TSO,如果网卡支持TSO则让网卡分段,否则协议栈分完段再交给驱动。 如果TSO开启,GSO会自动开启。查看tso和gso是否开启 查看详情

如何让 Python 中的 for 循环更高效

】如何让Python中的for循环更高效【英文标题】:HowtomaketheforloopmoreefficientinPython【发布时间】:2018-04-2014:22:01【问题描述】:我有一个Python代码,可以生成给定句子中单词的所有可能排列。我希望将这些排列写在.txt文档中。如果... 查看详情

有没有办法让这个 Python kNN 函数更高效?

】有没有办法让这个PythonkNN函数更高效?【英文标题】:IsthereawaytomakethisPythonkNNfunctionmoreefficient?【发布时间】:2014-12-1112:59:15【问题描述】:在MATLAB遇到问题后,我决定尝试Python:我编写了一个函数,当样本属于我自己的类时... 查看详情

如何让这段代码更高效(KS测试)

】如何让这段代码更高效(KS测试)【英文标题】:Howtomakethispieceofcodemoreefficient(KSTest)【发布时间】:2020-09-0408:42:30【问题描述】:我的数据看起来像这样id1,id2,similarityCHEMBL1,CHEMBL1,1CHEMBL2,CHEMBL1,0.18CHEMBL3,CHEMBL1,0.56CHEMBL4,CHEMBL1,0.64CH... 查看详情

2021google开发者大会丨构建高效机器学习生态

Google致力于构建先进的机器学习生态,带来高效开发体验,并助力开发者将机器学习应用到多个领域。从科学研究、商业变革到公益事业,解决现实生活中的各种问题。准备好了吗?一起来了解2021Google开发者大会... 查看详情

tidb6.5新特性解析丨过去一年,我们是如何让tiflash高效又稳定地榨干cpu?

TiDB6.5LTS版本已经发布了。这是TiDBV6的第二个长期支持版,携带了诸多备受期待的新特性:产品易用性进一步提升、内核不断打磨,更加成熟、多样化的灾备能力、加强应用开发者生态构建……TiDB6.5新特性解析系列文... 查看详情

filecoin官方信息丨web3.storage:让filecoin的存储更简单便捷

ProtocolLabs最近推出了Web3.Storage,这是一个简单、便捷的应用程序,供开发人员从Filecoin的去中心化存储网络存储和检索数据!Web3.Storage将无限期地保持免费为开发人员提供了一种简单的途径来构建具有冗余、分散存储... 查看详情

React:我怎样才能让这个 React 组件写得更好更高效?

】React:我怎样才能让这个React组件写得更好更高效?【英文标题】:React:HowcanImakethisReactComponentwrittenbettertobemoreefficient?【发布时间】:2021-11-0617:04:08【问题描述】:我觉得我在重复onIncrement中的代码,并且可以更好地重构它。max... 查看详情

brvah(让recyclerview变得更高效)

本文来自网易云社区作者:吴思博对于RecyclerView,我们重复编写着那一个又一个的列表界面,有的要分组,有的要添加广告头部、有的要不同类型item排列、等等需求,主要代码有大部分是重复的,如果有一个框架能够帮快速的... 查看详情

brvah(让recyclerview变得更高效)

本文来自网易云社区作者:吴思博对于RecyclerView,我们重复编写着那一个又一个的列表界面,有的要分组,有的要添加广告头部、有的要不同类型item排列、等等需求,主要代码有大部分是重复的,如果有一个框架能够帮快速的... 查看详情

数商云行业沙龙第九期丨目录化采购商城,让采购更简单便捷

如何让采购更加高效便捷,实现像淘宝一样快速精准的批量集中采购?11月25日,全链数字化业务协同服务商——数商云举办了线上“目录化采购商城,让采购更简单便捷”的主题直播分享。数商云方案中心封金华... 查看详情