code: func PutKVToEtcd(ctx context.Context, etcdCli *clientv3.Client, retryCnt int, key, val string,
  	opts ...clientv3.OpOption) error {
  	var err error
  	for i := 0; i < retryCnt; i++ {
  		if isContextDone(ctx) {
  			return errors.Trace(ctx.Err())
  		}
  
  		childCtx, cancel := context.WithTimeout(ctx, keyOpDefaultTimeout)
  		_, err = etcdCli.Put(childCtx, key, val, opts...)
  		cancel()
  		if err == nil {
  			return nil
  		}
  		logutil.Logger(ddlLogCtx).Warn("[ddl] etcd-cli put kv failed", zap.String("key", key), zap.String("value", val), zap.Error(err), zap.Int("retryCnt", i))
  		time.Sleep(keyOpRetryInterval)
  	}
  	return errors.Trace(err)
  }
docs: // PutKVToEtcd puts key value to etcd.
  // etcdCli is client of etcd.
  // retryCnt is retry time when an error occurs.
  // opts is configures of etcd Operations.