Skip to content

TxnKV Advanced

disksing edited this page Feb 24, 2022 · 11 revisions

Advanced Transactional API

Asynchronous Commit

Normally, client must wait for the commit to complete in two phases (2PC) synchronously. If the application is very latency sensitive and the transaction does not involve many keys, consider turning on the async commit option.

When async commit is used, the transaction will return a successful commit to the application as soon as the first stage of Prewrite is completed, so there is less latency. The cost is that if a failure is encountered, the transaction is more costly to recover.

Note that if async commit is enabled for transactions that involve too many keys, synchronous commit may still be used. It depends on whether the number of keys is smaller than the asyncCommit.KeysLimit configuration (default is 256).

Example:

txn.SetEnableAsyncCommit(true)

1PC

If all the keys to be written for a transaction belong to the same region, then it can be committed in one phase commit (1PC), i.e., the trasaction is committed by only one RPC.

Compared with Asynchronous Commit, 1PC has a similar effect of reducing latency. Also, because there are fewer RPCs, 1PC can better control resource usage. It is recommended to enable 1PC to optimize performance if the transaction if small enough (especially for single row transactions).

Example:

txn.SetEnable1PC(true)

Causal Consistency

When async commit or 1PC is enabled, we can further redudce latency by omitting getting CommitTS from PD but using locally computed timestamp directly if the linear consistency constraint can be relaxed.

The side effect of setting causal consistency is that there may be other concurrent transactions with larger timestamp than the current transaction, but cannot read the keys written by the current transaction.

Example:

txn.SetCausalConsistency(true)

Transaction Priority

client-go provides 3 kinds of priorities for transactions. After setting the corresponding priority, TiKV will segregate the tasks with different priorities and ensure the execution of high priority tasks first.

In general, it is recommanded to use Normal (default value), High for critical transactions, and Low for transactions with no response time requirements.

Example:

txn.SetPriority(txnkv.PriorityHigh)
snapshot.SetPriority(txnkv.PriorityLow)

Skip Fill Cache

TiKV automatically uses the memory cache of recently read data to speed up queries.

If the transaction/snapshot is running a large, one-time query, the cache mechanism will have the opposite effect -- not only will the read data not be accessed again for a while, but the hot data that was in the cache may be moved out of the cache.

To avoid this, client-go provides SetNotFillCache to disable caching data.

snapshot.SetNotFillCache(true)
txn.GetSnapshot().SetNotFillCache(true)

Key Only

Sometimes when scanning data, we only care about the key and not the value, in this case setting KeyOnly can somewhat reduce the network overhead and get performance optimization.

When KeyOnly is set, iter.Value() will return nil results (instead of an error).

snapshot.SetKeyOnly(true)
txn.GetSnapshot().SetKeyOnly(true)

Sampling Scan

Sometimes we scan all the data to perform statistical analysis and the results do not need to be completely accurate. This is the case when sampling can be used to avoid too much IO pressure.

The snapshot.SetSampleStep() function can control the sampling ratio. For example, step=100 means that 1 record is returned every 99 records, which means that 1% of the data is sampled.

snapshot.SetSampleStep(100)
txn.GetSnapshot().SetSampleStep(100)

Transaction Scopes

In the case of cross-center deployment with local transaction enabled, you can use the SetScope() method to specify the scope where the transaction runs. Please refer the document for more details.

txn.SetScope("zone1")

Disk Full Option

txnkv provides methods to control the behavior when the disk is full or almost full. The default behavior (NotAllowedOnFull) is to return an error when disk is full. You can change it to AllowedOnAlmostFull or AllowedOnAlreadyFull to allow the transaction to continue even if the disk is full or almost full.

Note: this feature is supported by TiKV 5.3.0+. Setting the option will have no effect for old versions.

txn.SetDiskFullOpt(kvrpcpb.DiskFullOpt_AllowedOnAlreadyFull)

Delete Range

To avoid consuming a lot of resources for sending keys over the network, txnkv also supports DeleteRange to quickly delete all data in a range. Notice that this API does not keep recent MVCC versions, but deletes all keys in the range immediately.

completeRegions, err := client.DeleteRange(context.Background(), []byte("begin"), []byte("end"), 4)
if err != nil {
    // ... handle error ...
}

Known Issue

  • It is not supported to use nil as endKey of delete range. (#428)