TiDB 使用中心授时机制,每个事务都要从 PD 这一中心节点获取 TS 时间戳,PD 分配 TS 的 QPS 上限就是整个集群可扩展性的天花板。因此,搞清楚 PD 分配 TS 能力的上限就显得尤为重要了。
前段时间,从不同场合听到一个说法:PD 分配 TS 的 QPS 上限是 40w QPS。不过并没有看到相关的测试结果进行佐证。那么,事实真的是这样吗?
其实如果对 PD 分配 TS 的流程有所了解的话,就知道这个说法其实是存在一定问题的。
PD Client(通常也就是 TiDB)在有分配 TS 的需求时,并不是直接发送一个 RPC 请求到 PD,而是有一个 Batch 的过程,也就是会把同一时刻的 TS 请求进行合并后给 PD server 发送一个 RPC 请求,PD server 一口气分配一段 TS,然后客户端收到回复后再进行分发。
目前我们默认的 Batch 策略是 Client 始终保证只有一个 in-flight 请求,即在收到 PD server 的回复消息之前,所有的 TS 请求都会被放入下一个 Batch。也就是说,对于 PD server 来说,单个 Client 的请求并发量就是 1,不论这个 Client 实际的事务并发量是多少。
实际上,我们遇到 TSO 出现瓶颈,通常是因为 TiDB 的 CPU 繁忙,导致 TiDB 收到 PD 回复消息后进行分发的过程过慢(这个受 Go Runtime 调度影响较大),一般对 TiDB 进行扩容就能很好地解决问题。
有一种比较特殊的情况,就是不使用 TiDB 而是直接使用 Txn Client Library,如果客户端进程过多(比如上百个),每个客户端都要跟 PD server 建立连接和发送请求,确实会导致 PD server 负载过高而形成瓶颈。
那么回到问题本身,PD 分配 TS 的 QPS 上限是不是 40w 呢?为了排除 TiDB/TiKV 的影响,可以直接使用 pd-tso-bench 工具 进行测试。这里我使用 10000 的客户端 TS 并发。
在我的配置下,单个 bench client 测得 QPS 大约是 80 多万。随后启动更多的 bench client,每个新开的 bench client 输出都是 80 多万左右,这充分证明了 TSO 的瓶颈不在 PD server 而是在客户端。
截图的总 QPS 已经超过 300w 了,而且我继续加客户端的话还能更多,很显然最高 40w 的说法是不靠谱的。
这个说法是从哪里来的无从考证,不过我猜是因为始作俑者使用单个 TiDB 进行测试,TiDB 每个事务要取 2 次 TS,我这里测到的 80w 除以 2 正好是 40w,于是他就认为这是达到 PD 分配 TS 的极限,后面就有了这个流言。