PD在进行coordinator is stopping时耗时过长,导致QPS跌零

【 TiDB 使用环境`】生产环境
【 TiDB 版本】4.0.14
【遇到的问题】
[2022/05/05 11:00:22.465 +08:00] [INFO] [cluster.go:332] [“coordinator is stopping”]
[2022/05/05 11:03:08.415 +08:00] [INFO] [cluster.go:328] [“coordinator has been stopped”]
PD在进行coordinator is stopping时耗时过长,这时主leader无法服务,其他的pd也会skip campaign leader and check later,很快就把tso耗完后,pd就无法提供服务。之后就会QPS跌零,时间长达两分多钟。

【问题现象及影响】
什么情况下pd coordinator is stopping 会长达两分多钟。

2 个赞

1)有没有启用cdc?
2)此时 有没有大量的scheduler操作?

2 个赞

都没有呢。

2 个赞

中间会出现很多这样的报错
logical part outside of max logical interval, please check ntp time

2 个赞

这种会不会是时间不同步导致的?你们配置NTP了么,要指向同一个时钟源

1 个赞

看起来是 leader退出后的 coordinator is stopping 花了两分多钟,这个过程没有申请新的tso的pysical部份,于是tso耗完。但是follower从etcd里可以读到leader,但是又不能收到leader的消息。会处在skip campaign leader and check later的循环里,于是也没有去竞争leader。

事务请求全局版本号的时候通过gRPC调用getRespTS(),PD将通过在内存中保留的可分配的时间窗口,直接在内存里面计算出TSO 并返回,避免每次分配TSO都需要持久化到etcd带来的开销。如果NTP时钟出现比较大的误差导致updateTimestamp()执行不及时,可能会出现logical time溢出,这个时候需要 阻塞 请求待updateTimestamp()执行后恢复。

const maxRetryCount = 100
func (s *Server) getRespTS(count uint32) (pdpb.Timestamp, error) {
	var resp pdpb.Timestamp

	if count == 0 {
		return resp, errors.New("tso count should be positive")
	}

	for i := 0; i < maxRetryCount; i++ {
		current, ok := s.ts.Load().(*atomicObject)
		if !ok || current.physical == zeroTime {
			log.Error("we haven't synced timestamp ok, wait and retry", zap.Int("retry-count", i))
			time.Sleep(200 * time.Millisecond)
			continue
		}
                //Physical time 是当前 unix time 的毫秒时间
		resp.Physical = current.physical.UnixNano() / int64(time.Millisecond)
                //logical time 则是一个最大 int64(1 << 18) 的计数器
		resp.Logical = atomic.AddInt64(&current.logical, int64(count))
                //如果logical time 溢出了,需要休眠updateTimestampStep时间,
                //等待调用updateTimestamp()重置logical time
		if resp.Logical >= maxLogical {
			log.Error("logical part outside of max logical interval, please check ntp time",
				zap.Reflect("response", resp),
				zap.Int("retry-count", i))
			tsoCounter.WithLabelValues("logical_overflow").Inc()
			time.Sleep(updateTimestampStep)
			continue
		}
		return resp, nil
	}
	return resp, errors.New("can not get timestamp")
}

这个代码我看了。日志里可以看到的是leader正在step down,但是coordinator is stopping花了两分多钟。整个两分多钟里,日志里pysical部份再不会向前递增,可能是因为leader正在step down,所以不会再继续updateTimestamp。但是还是有请求,只会累加logical部份,很快就超过1<< 18然后就开始报错了。然后coordinator has been stopped之后,才可以竞争leader,才恢复的。这个过程看起来和NTP没有关系。

从leader step down到下一个leader产生,中间花了两分多钟,于是产生了两分多钟的QPS跌零。
问题有两个:

  1. 为什么leader的coordinator is stopping花了两分多钟?
  2. follower是否需要coordinator has been stopped之后,才可以竞争leader?

今天又出现了相同问题,QPS跌零了七分钟。

1 个赞

奇怪,你这边有没有做过其他的什么操作,才导致这个发生呢? 有什么上下文背景?

1 个赞

https://github.com/tikv/pd/issues/4146
看下这个

2 个赞

PD的leader 有经常发生transfer吗?这种经常的频率是一天一次这种,都算比较频繁了。

一天几次,因为网络不太好的样子,租约过期。很像楼上发的这个issue。
https://github.com/tikv/pd/issues/4146
看下这个

这个很像,我看一下。感谢。

弱网环境引发的血案

你们这样一出现就太严重了。一天好几回。

咱们这个有啥后续结果吗,学习一下

最近看起来网好一些了,出现的频率低一些。还没有进行升级。

v5.3.0遇到一个类似的现象,coordinator stop时间更长,超过24hour