tikv go-client间隔1秒使用,事务请求的时延会翻倍

【 TiKV 使用环境】测试
【 TiKV 版本】
tikv-server : v6.5.8
go-client :v2.0.7

【遇到的问题:问题现象及影响】
1.使用乐观事务反复put同一个key,value size为64kb,每次put的value会变化
2.循环put 1万次,平均时延2.3毫秒
3.循环put 1万次,中间sleep 1秒,平均时延4.5毫秒

业务请求不频繁,但对每次请求的时延很敏感,导致业务性能有抖动

源码,去掉Lock Key,可以优化500微秒:

func lockPuts(keys [][]byte, values [][]byte) error {
        tx, err := client.Begin()
        if err != nil {
                return err
        }
        tx.SetPessimistic(true)
        err = tx.LockKeysWithWaitTime(context.Background(), kv.LockNoWait, keys...)
        if err != nil {
                return err
        }

        for i := 0; i < len(keys); i++ {
                key, val := keys[i], values[i]
                err := tx.Set(key, val)
                if err != nil {
                        tx.Rollback()
                        return err
                }
        }


        tx.Commit(context.Background())
        return nil
}


        var total int64 = 0
        for i := 0; i < 10000; i++ {
                start := time.Now()
                err := lockPut(xxx,xxx)
                if err != nil {
                        panic(err)
                }
                end := time.Since(start)
                fmt.Println("cost:", end, "\n")
                total += end.Microseconds()
                time.Sleep(1*time.Second)
        }

        fmt.Println("avg:", total/int64(*count))

【资源配置】
nvme盘,tiup部署默认配置的3个tikv节点

两次循环put有什么不同?

time.sleep(1)

这个有commit吗?

有的commit

一万次put\commit 这样?第一轮都是2.3毫秒,第二轮都是4.5毫秒?顺序执行?也没有个事务冲突fallback?
如果集群没有其他请求的话,纯测试的话,你把sleep的时间间隔搞长一些、put的次数也搞长一些,让监控采集到数据,然后看看监控

我贴了代码,都是顺序执行的

应该要多几组测试来进行对比。

有进行 P99、P95统计么?是不是有少数请求特别长?可以发一下跑出来的日志,大家分析一下。

循环多跑机组,然后如果再继续分的话,把lockkey里面的加锁和put和提交单独计时,看看每一组的耗时主要差别在哪里?我理解put耗时应该不大,差别可能在lock和commit。你这个用的是悲观事务吧,不是乐观事务。

LockKey会让这个失效?不过Lock Key看起来是悲观事务玩法

image
这个单词应该是悲观事务的意思

悲观事务和乐观事务,在提交时间上差异没有这么明显吧

还是有的,乐观事务会优化500微妙左右

不sleep的话kv_prewrite会从1.9毫秒降到700微秒的样子,kv_commit也从700微秒降到400微秒左右

append log的时延也降低了

raft engine写延时降低

有可能是 batch 的原因
MaxBatchSize 设成 0 试试

import "github.com/tikv/client-go/v2/config"
...
...
config.UpdateGlobal(func(c *config.Config) {
	c.TiKVClient.MaxBatchSize = 0
})

效果不大

对于中间没有 sleep 1 秒的 case 设置 MaxBatchSize = 0,跑出来还是 700 us,效果不大是这个意思?

嗯,无论加不加sleep,均没有缩短时延,似乎不是这个问题

加锁、put都很稳定,前者是10微秒以内,后者在40微秒以内,但是commit会从1100+ 微秒涨到2200+微秒