TiDB 6.0: 让TSO更高效

作者:闫彬彬

原文来源:https://tidb.net/blog/2f7e4eb7

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作为sart_ts、提交时获取tso作为commit_ts,依靠tso实现事务的MVCC。TSO为64位的整型数值,由物理部分和逻辑部分组成,高48位为物理部分是unixtime的毫秒时间,低48位为逻辑部分是一个数值计数器,理论上每秒可产生262144000个tso。

       为保证性能PD会每次分配3秒的tso,并保存在etcd内,当pd 重启或leader切换后会从etcd内获取保存的最大tso开始分配,以保证tso的连续递增。

3       Follower Proxy

       默认情况下tso请求由PD leader处理,tidb的 tso 请求会发给PD client, PD client并不会将收到的请求立刻发送给PD leader ,而将同一时刻收到的所有请求打包发送给PD leader,然后由PD leader返回一批tso。由于仅有leader提供服务,tidb数量较多时会有较多的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负载。

       启PD follower的tso代理功能需设置变量tidb_enable_tso_follower_proxy,该功能适用于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变量控制,默认为false。

       优化后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使用正常的流程重新获取ts和执行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 alllocator。当未启用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.

6      测试

6.1    测试环境

TiDB版本 V6.0.0(DMR)
主机 ARM 96C(4 numa_node),384G内存,普通SSD,共3台
系统部署 5*tidb ,6*tikv,3*PD,1*haproxy, 绑定不同numa_node

6.2    TSO follower proxy

         使用sysbench持续压测,可以看到在开启tso_follower_proxy后pd leader cpu利用率有所降低。由于资源限制不能把PD leader CPU压倒很高,因此对leader CPU降低不是很明显。

       关闭tso_follower_proxy:

image.png

       开启tso_follower_proxy:

 image.png

6.3    RC read tso

       可以看到在开启tidb_rc_read_check_ts后可以看到tidb发起的 tso请求数量明显下降,由于攒批的原因实际发送到pd 的tso请求下降不明显。

image.png

开启该功能后CPU利用率也有所下降。

 image.png

7      总结

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

{{o.name}}
{{m.name}}

猜你喜欢

转载自my.oschina.net/u/5674736/blog/5529268
TSO