# TiDB Cluster Load Test Performance Analysis Guide 

DRAFT: TiDB Cluster Load Test Performance Analysis Guide (draft translation)    

## TiDB performance map

[TiDB Performance Map](https://github.com/pingcap/tidb-map/blob/master/maps/performance-map.png)

**TiDB performance map**        

**1 Performance medical examination form**        

1.1 Before compression testing  

1.1.1 System medical examination form  

**1.2 Under pressure test**        

1.2.1 Piezometric end physical checklist  

1.2.2 TiDB Body Checklist  

1.2.3 TiKV Medical Checklist  

1.2.4 PD Medical Examination Form   12

**2 Flowchart of data reading and writing**         **14**

2.1 TiKV Data Write Flowchart   14

**2.2 TiKV Data Reading Flowchart**         **14**

**2.3 TiDB Data Write Flowchart**         **15**

2.4 TiDB Data Read Flowchart   15

**3 Operating Instructions**         **16**

**3.1 CPU**         **16**

3.1.1 tidb-server   16

3.1.2 tikv-server   17

**3.2 Disks**         **17**

3.2.1 Using fio to pressure test the disks used by TiKV   17

**3.3 Network**         **18**

3.3.1 Network latency   18

3.3.2 Network bandwidth   18

**4 Performance POC FAQ**         **20**

* * *

## 1 Performance Health Check

---------------

The checklist provides the items that need to be checked during the performance test, as well as the meaning and reference values of the items. The purpose is to enable new hires to analyze the bottlenecks in the load test by following the list.

### 1.1 Before Test

---------------

#### 1.1.1 System checklist

<table>
<tbody>
<tr>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left"><strong>Category</strong></p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left"><strong>Items</strong></p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left"><strong>Results</strong></p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left"><strong>Reference value / meaning</strong></p>
</td>
</tr>
<tr>
<td colspan="1" rowspan="2">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Deployment-related</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Is the test tool on the same server room as the TiDB cluster -</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">If the test tool and TiDB cluster are in different server rooms, be aware of the network bandwidth of the server room and the network latency, See section 3.3.2.</p>
</td>
</tr>
<tr>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
</td>
</tr>
<tr>
<td colspan="1" rowspan="3">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">System-related</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">TiKV machine fio load test</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Reference 3.2.1</p>
</td>
</tr>
<tr>
<td colspan="1" rowspan="1">
<ol class="lst-kix_list_2-0 start" start="1">
<li class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Network bandwidth</li>
<li class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Network latency</li>
</ol>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">In particular, pay attention to the network bandwidth of the machine where the test tool is located and the machine where haproxy (if any) is located.</p>
</td>
</tr>
<tr>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">NUMA</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Reference 3.1.1</p>
</td>
</tr>
<tr>
<td colspan="1" rowspan="4">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Business-related</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Is there a self-incrementing id</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
</td>
<td colspan="1" rowspan="2">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Self-incrementing ids or indexes can lead to hotspot issues</p>
</td>
</tr>
<tr>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Whether there is a self-incrementing index</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
</td>
</tr>
<tr>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Is there a read hotspot</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">For example, frequent scans of small tables</p>
</td>
</tr>
<tr>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Are there write hotspots</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
</td>
</tr>
</tbody>
</table>

### 1.2 During Test

---------------

#### 1.2.1 Test tool checklist

<table>
<tbody>
<tr>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left"><strong>Category</strong></p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left"><strong>Items</strong></p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left"><strong>result</strong></p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left"><strong>Reference value/meaning</strong></p>
</td>
</tr>
<tr>
<td colspan="1" rowspan="2">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Test Tool</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left"><em>The machine where the test tool is located</em></p>
<ol class="lst-kix_list_14-0 start" start="1">
<li class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left"><span class="wysiwyg-color-black wysiwyg-font-size-medium">CPU usage</span></li>
<li class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left"><span class="wysiwyg-color-black wysiwyg-font-size-medium">CPU load</span></li>
<li class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Inbound/outbound bandwidth</li>
<li class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">NIC send/receive packet soft interrupt hit full single core</li>
</ol>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Reference values.</p>
<ol class="lst-kix_list_12-0 start" start="1">
<li class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">CPU usage should be below 90%.</li>
<li class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">CPU load should be lower than the number of cores.</li>
<li class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Note if the bandwidth is full.</li>
</ol>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">The command <span class="wysiwyg-font-size-small wysiwyg-color-black70">mpstat -P ALL 2 </span>lists at all cores. The column %soft is the soft interrupt. You can also use top -H to see if one of the ksoftirqd threads is full.</p>
</td>
</tr>
<tr>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left"><em>haproxy machine (if present)</em></p>
<ol class="lst-kix_list_1-0 start" start="1">
<li class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left"><span class="wysiwyg-color-black wysiwyg-font-size-medium">CPU usage</span></li>
<li class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left"><span class="wysiwyg-color-black wysiwyg-font-size-medium">CPU load</span></li>
<li class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Inbound/outbound bandwidth</li>
</ol>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Reference values.</p>
<ol class="lst-kix_list_6-0 start" start="1">
<li class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">CPU usage should be below 90%.</li>
<li class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">CPU load should be lower than the number of cores.</li>
<li class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Check if the bandwidth is hit full.</li>
</ol>
</td>
</tr>
</tbody>
</table>

#### 1.2.2 TiDB Checklist

<table>
<tbody>
<tr>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left"><strong>Category</strong></p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left"><strong>Items</strong></p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left"><strong>Reference value/meaning</strong></p>
</td>
</tr>
<tr>
<td colspan="1" rowspan="14">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">monitoring</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left"><span class="wysiwyg-color-black wysiwyg-font-size-medium">QPS</span></p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Overall system QPS.</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">TIP: Edit this panel to show the third equation (Equation C) to get the theoretical QPS upper limit. The theoretical QPS should be 10% higher than the actual QPS. If the value is too high, it means the pressure is not in the database.</p>
</td>
</tr>
<tr>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left"><span class="wysiwyg-color-black wysiwyg-font-size-medium">Duration</span></p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Reference value: .999 should be less than 500ms under OLTP load</p>
</td>
</tr>
<tr>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left"><span class="wysiwyg-color-black wysiwyg-font-size-medium">Internal SQL QPS</span></p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">QPS of internal SQL executed by TiDB, not user SQL. e.g. reading system variables when creating a connection, automatic update of statistics, GC owner updating the safe point, etc.</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Reference value: within 20</p>
</td>
</tr>
<tr>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left"><span class="wysiwyg-color-black wysiwyg-font-size-medium">Connection Count</span></p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">The number of connections from the client to the tidb.</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Reference value: within 500, with emphasis on balance.</p>
</td>
</tr>
<tr>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left"><span class="wysiwyg-color-black wysiwyg-font-size-medium">Heap Memory Usage </span></p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">TiDB memory usage.</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Reference: OLTP load should be under 3 GB with TiDB local latch on and under 1 GB with latch off.</p>
</td>
</tr>
<tr>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left"><span class="wysiwyg-color-black wysiwyg-font-size-medium">Transaction Statement Num</span></p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">The number of statements in a single transaction.</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Reference value: within 500</p>
</td>
</tr>
<tr>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left"><span class="wysiwyg-color-black wysiwyg-font-size-medium">Transaction Retry Num</span></p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">The number of transaction retries.</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Reference: 3 and above is high, 6 and above is considered a very serious conflict.</p>
</td>
</tr>
<tr>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left"><span class="wysiwyg-color-black wysiwyg-font-size-medium">Lock Resolve OPS</span></p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Frequency of lock resolving due to read-write/write-write conflicts.</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Reference: expired and not_expired should both be within 500.</p>
</td>
</tr>
<tr>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left"><span class="wysiwyg-color-black wysiwyg-font-size-medium">KV Backoff OPS</span></p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">The number of waits caused by a transaction waiting for a lock or region route update.</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Reference value: txnLockFast and txnLock should be within 500.</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">regionMiss should be within 5000 when importing data.</p>
</td>
</tr>
<tr>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left"><span class="wysiwyg-color-black wysiwyg-font-size-medium">KV Cmd Duration</span></p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">The duration between sending a request to TiKV and receiving a reply.</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Reference value: .99 should be within 500ms except for data import and batch insert scenarios.</p>
</td>
</tr>
<tr>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left"><span class="wysiwyg-color-black wysiwyg-font-size-medium">PD TSO RPC Duration </span></p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">The latency of TiDB getting ts from PD. This is mainly related to the latency from TiDB to PD. If the load on the tidb-server machine is particularly high, it may also cause high tso duration.</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Reference value: within 30ms if TiDB and PD are in the same server room.</p>
</td>
</tr>
<tr>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left"><span class="wysiwyg-color-black wysiwyg-font-size-medium">Get Token Duration</span></p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">The delay of requesting a token. The number of SQL executed at the same time cannot exceed the setting of the parameter token-limit in the configuration file. Increase token-limit If the value is high.</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Reference value: within 1 ms</p>
</td>
</tr>
<tr>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left"><span class="wysiwyg-color-black wysiwyg-font-size-medium">AutoID QPS</span></p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">When the cached Auto-ID is exhausted, the QPS for getting more cache from &nbsp;TiKV</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Reference value: within 0.5</p>
</td>
</tr>
<tr>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left"><span class="wysiwyg-color-black wysiwyg-font-size-medium">AutoID Duration</span></p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left"><span class="wysiwyg-color-black wysiwyg-font-size-medium">&nbsp;</span></p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Time to fetch the Auto-ID cache. Multiple TiDBs fetching the Auto-ID cache for the same table at the same time will increase this value. For example, multiple threads concurrently writing to a table</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Reference value: within 100 ms</p>
</td>
</tr>
<tr>
<td colspan="1" rowspan="3">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">configuration file</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left"><span class="wysiwyg-color-black wysiwyg-font-size-medium">token-limit</span></p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">The default is 1000, which means that up to 1000 requests will be processed simultaneously, and the rest will be queued. If the number of connections to a single tidb-server exceeds 1000, the parameter needs to be increased.</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Reference value: token-limit should be greater than the number of connections.</p>
</td>
</tr>
<tr>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left"><span class="wysiwyg-color-black wysiwyg-font-size-medium">txn-local-latches</span></p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Enabled by default with capacity 2048000, used to detect write conflicts in the same TiDB and reduce the cost of transaction retries. Can be turned off if the scenario is confirmed to be conflict-free.</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Reference value: Default parameter</p>
</td>
</tr>
<tr>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left"><span class="wysiwyg-color-black wysiwyg-font-size-medium">prepared-plan-cache</span></p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Default is off. When on, cache execution plan for reuse. Sysbench uses the prepare/execute form for all statements except the insert statements, so it is recommended to turn it on. In addition to the TiDB side, client code also needs to confirm whether to use Prepare semantics. For example, JDBC clients need to configure the setting &nbsp;useServerPrepStmts</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Reference value: enabled = true</p>
</td>
</tr>
<tr>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">system variable</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left"><span class="wysiwyg-color-black wysiwyg-font-size-medium">tidb_constraint_check_in_place</span></p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Off by default, on only for compatibility. Check uniqueness for every row inserted. Recommended turning off for load test.</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Reference value: off</p>
</td>
</tr>
<tr>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left"><span class="wysiwyg-color-black wysiwyg-font-size-medium">tidb_max_chunk_size </span></p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Default 1024, the maximum number of rows in a chunk during the execution process</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Reference values.</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">OLTP Applications = 32</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">OLAP application = 1024 or more</p>
</td>
</tr>
<tr>
<td colspan="1" rowspan="2">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Resource consumption</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left"><span class="wysiwyg-color-black wysiwyg-font-size-medium">CPU usage</span></p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Reference 3.1.1</p>
</td>
</tr>
<tr>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left"><span class="wysiwyg-color-black wysiwyg-font-size-medium">CPU load</span></p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Should be less than the number of cores, refer to 3.1.1</p>
</td>
</tr>
<tr>
<td colspan="1" rowspan="2">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">common problems</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">AutoID conflict issues</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">TiDB will request a range of IDs from TiKV if the table has AutoIncrement columns, or has implicit IDs, and then distribute the ID in memory. When the IDs in memory are exhausted, another range will be requested. This operation “read + update” key "TID:table_id ", which could lead to write/write conflicts. Consider increasing the allocation step of AutoID.</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">In addition, specifying a value for AutoIncrement may also trigger an update of this key, which can also introduce write-write conflicts if concurrency is high. It is not recommended to specify the value of the AutoIncrement column frequently at insert time</p>
</td>
</tr>
<tr>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">NUMA issues</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Reference 3.1.1</p>
</td>
</tr>
</tbody>
</table>

* #### 1.2.3 TiKV Medical Checklist
    
<table>
<tbody>
<tr>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left"><strong>Category</strong></p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left"><strong>Items</strong></p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left"><strong>result</strong></p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left"><strong>Reference value/meaning</strong></p>
</td>
</tr>
<tr>
<td colspan="1" rowspan="2">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">System-related</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left"><span class="wysiwyg-color-black wysiwyg-font-size-medium"><em>Node-exporter</em></span></p>
<ol class="lst-kix_list_15-0 start" start="1">
<li class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">CPU usage</li>
<li class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">CPU load</li>
<li class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">CPU IO wait</li>
<li class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Network bandwidth</li>
</ol>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Reference values.</p>
<ol class="lst-kix_list_3-0 start" start="1">
<li class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">CPU usage should be below 85%. Please refer to 3.1.2</li>
<li class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">CPU load should be lower than the number of cores. Please refer to 3.1.2</li>
<li class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">CPU IO wait should ideally be below 5%, otherwise, it means that disk IO is busy and you need to check if the disk load is reaching a bottleneck.</li>
<li class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Both inbound/outbound bandwidths should be below the bandwidth limit.</li>
</ol>
</td>
</tr>
<tr>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left"><span class="wysiwyg-color-black wysiwyg-font-size-medium"><em>Disk-performance</em></span></p>
<ol class="lst-kix_list_16-0 start" start="1">
<li class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">IO latency</li>
<li class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">IO utilization</li>
<li class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Disk load</li>
</ol>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Reference values.</p>
<ol class="lst-kix_list_8-0 start" start="1">
<li class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">The io latency for write should ideally be less than 4ms, and the io latency for read can be slightly higher than for write since most reads are likely to go to cache.</li>
<li class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">IO util should ideally be below 90%.</li>
<li class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Disk load should preferably be below 5.</li>
</ol>
</td>
</tr>
<tr>
<td colspan="1" rowspan="5">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">TiKV Core Module CPU Usage</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">TiKV raftstore CPU (write related) latch wait duration</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Is the wait balance between TiKVs? Unbalanced means there is a write hotspot problem.</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Reference value: preferably less than raftstore.store-pool-size \* 85%</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left"><img title="" src="/hc/article_attachments/4410271544599/image-0.png" alt=""></p>
</td>
</tr>
<tr>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">TiKV apply CPU (write related)</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Is there a balance between TiKVs? Unbalanced means there is a write hotspot problem.</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Reference value: preferably less than raftstore.apply-pool-size \* 90%</p>
</td>
</tr>
<tr>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">TiKV scheduler worker CPU (write-related)</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Is there a balance between TiKVs? Unbalanced means there is a write hotspot problem.</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Reference value: preferably less than storage.scheduler-worker-pool-size * 90%</p>
</td>
</tr>
<tr>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">TiKV storage readpool CPU (read related)</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
</td>
<td colspan="1" rowspan="1">
<ul class="lst-kix_list_9-0 start">
<li class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Is there a balance between TiKVs? Unbalanced means there is a read hotspot problem.</li>
</ul>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>

<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Reference value: preferably below readpool.storage.[high|normal|low]-concurrency \* 90%</p>
</td>
</tr>
<tr>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">TiKV Coprocessor CPU (read related)</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Is there a balance between TiKVs? Unbalanced means there is a read hotspot problem.</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Reference value: preferably below <span class="wysiwyg-color-black wysiwyg-font-size-medium">readpool.coprocessor.[high|normal|low]-concurrency * 90% </span></p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left"><img title="" src="/hc/article_attachments/4410281641879/image-1.png" alt=""></p>
</td>
</tr>
<tr>
<td colspan="1" rowspan="11">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">TiKV Delay (write related)</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left"><span class="wysiwyg-color-black wysiwyg-font-size-medium">gRPC duration</span></p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">The total time spent on the TiKV side of the request.</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Potential network issues can be found by comparing the TiKV gRPC duration with the TiDB KV duration. For example, if the gRPC duration is very short in TiKV but the KV duration of TiDB is very long, it means that the network latency between TiDB and TiKV may be high or the bandwidth of the network card between TiDB and TiKV is full.</p>
</td>
</tr>
<tr>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left"><span class="wysiwyg-color-black wysiwyg-font-size-medium">Scheduler duration</span></p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Consists of the following four parts.</p>
<ol class="lst-kix_list_17-0 start" start="1">
<li class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">latch-wait duration</li>
<li class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">async-snapshot duration</li>
<li class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">The processing time of the command in the scheduler</li>
<li class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">async-write duration</li>
</ol>
</td>
</tr>
<tr>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left"><span class="wysiwyg-color-black wysiwyg-font-size-medium">Scheduler latch wait duration</span></p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Reasons for high latch wait latency.</p>
<ol class="lst-kix_list_11-0 start" start="1">
<li class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Multiple transactions writing to the same key at the same time cause a conflict, which requires waiting for a lock.</li>
<li class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">The number of keys written to TiKV at the same time is very high (e.g., a large concurrent import event) and exceeds the default value of latch 2048000. In such cases, adjust the latch count to alleviate the wait. The corresponding parameter is [storage] <strong>scheduler-concurrency</strong>.</li>
</ol>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Reference value: .99 Preferably less than 20ms.</p>
</td>
</tr>
<tr>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left"><span class="wysiwyg-color-black wysiwyg-font-size-medium">Storage async-snapshot duration</span></p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Delay in raft snapshot request (need to fetch a snapshot before reading).</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Reference value: .99 should be less than 5ms.</p>
</td>
</tr>
<tr>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left"><span class="wysiwyg-color-black wysiwyg-font-size-medium">Storage async-write duration</span></p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">raft write latency, consisting mainly of the following components.</p>
<ol class="lst-kix_list_18-0 start" start="1">
<li class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Propose wait duration</li>
<li class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Commit wait duration (no metric for now)</li>
<li class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Append log duration</li>
<li class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Apply wait duration</li>
<li class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Apply log duration</li>
</ol>
</td>
</tr>
<tr>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left"><span class="wysiwyg-color-black wysiwyg-font-size-medium">Propose wait duration</span></p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">The delay between sending a request to the raftstore and when the raftstore starts processing the request. If this delay is high, the raftstore is busy or the append log is time-consuming, which means that the raftstore cannot process the request in time. (Note that a high proposed wait in version 2.1 may be due to a high number of individual TiKV leaders, e.g. more than 10k, resulting in high latency for periodic tasks. ---- Check the .99 duration of raftstore events under the raft process to confirm. In this case, you need to enable region merge to reduce the number of regions).</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Reference value: preferably below 50-100ms</p>
</td>
</tr>
<tr>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left"><span class="wysiwyg-color-black wysiwyg-font-size-medium">Append log duration</span></p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">The time it takes to write raft log/ Writing raft logs to raftdb.</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Reference value: preferably less than 50ms</p>
</td>
</tr>
<tr>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left"><span class="wysiwyg-color-black wysiwyg-font-size-medium">Apply wait duration</span></p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">The delay between when committed raft logs are sent to the apply thread and when the apply thread applies those logs. If this latency is high, the apply thread is busy. You need to check if this is due to high apply CPU or due to high disk load.</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Reference value: preferably less than 100ms</p>
</td>
</tr>
<tr>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left"><span class="wysiwyg-color-black wysiwyg-font-size-medium">Apply log duration</span></p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Time consumed in execution of raft log. Applying log means writing user data to kvdb.</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Reference value: preferably less than 100ms</p>
</td>
</tr>
<tr>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left"><span class="wysiwyg-color-black wysiwyg-font-size-medium">RocksDB kvdb write duration</span></p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">The time it takes to write kv RocksDB.</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Reference value: max Preferably less than 50ms</p>
</td>
</tr>
<tr>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left"><span class="wysiwyg-color-black wysiwyg-font-size-medium">RocksDB raftdb write duration</span></p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Time consumed to write into raft RocksDB.</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Reference value: Preferably less than 50ms max</p>
</td>
</tr>
<tr>
<td colspan="1" rowspan="3">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">TiKV Delay (Read Related)</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left"><span class="wysiwyg-color-black wysiwyg-font-size-medium">gRPC duration</span></p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Same as the gRPC duration in TiKV write-related latency.</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Reference value: None</p>
</td>
</tr>
<tr>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left"><span class="wysiwyg-color-black wysiwyg-font-size-medium">Coprocessor wait duration</span></p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Coprocessor request’s wait time.</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Reference value: less than 50ms, ideally. If you find that the wait duration is high during the stress test, e.g., higher than 50ms, it means that the Coprocessor is queuing and you need to check the CPU usage of the Coprocessor.</p>
</td>
</tr>
<tr>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left"><span class="wysiwyg-color-black wysiwyg-font-size-medium">Storage async-snapshot duration</span></p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Same as async-snapshot duration in TiKV write-related latency.</p>
</td>
</tr>
<tr>
<td colspan="1" rowspan="5">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left"><span class="wysiwyg-color-black wysiwyg-font-size-medium">Coprocessor</span></p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left"><span class="wysiwyg-color-black wysiwyg-font-size-medium">Scan keys</span></p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">How many keys were scanned by a single request.</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">The metric can assist in identifying potential problems with full table sweeps of query results that should be indexed.</p>
</td>
</tr>
<tr>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left"><span class="wysiwyg-color-black wysiwyg-font-size-medium">Table scan - details</span></p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">The number of next, prev, seek, etc. operations caused by table scan requests per unit time.</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Reference value: None</p>
</td>
</tr>
<tr>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left"><span class="wysiwyg-color-black wysiwyg-font-size-medium">Table scan - perf statistics </span></p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left"><span class="wysiwyg-color-black wysiwyg-font-size-medium">Reference values:</span></p>
<ol class="lst-kix_5n8yzpauj0oo-0 start" start="1">
<li class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">If the <strong>delete_skipped </strong>value is high, it means that a large number of tombstones exist inside RocksDB.</li>
<li class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">If the many differences of <strong>next/prev</strong>&nbsp;are observed between <strong>key_skipped</strong>&nbsp;and <strong>details</strong>, it means that there are many internal versions of RocksDB.</li>
</ol>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
</td>
</tr>
<tr>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left"><span class="wysiwyg-color-black wysiwyg-font-size-medium">Index scan - details</span></p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">The number of next, prev, seek etc. operations by index scan requests per unit time.</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Reference value: None</p>
</td>
</tr>
<tr>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left"><span class="wysiwyg-color-black wysiwyg-font-size-medium">Index scan - perf statistics</span></p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Reference values.</p>
<ol class="lst-kix_list_10-0 start" start="1">
<li class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">If the <strong>delete_skipped </strong>value is high, it means that a large number of tombstones exist inside RocksDB.</li>
<li class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">If the many differences of <strong>next/prev</strong>&nbsp;are observed between <strong>key_skipped</strong>&nbsp;and <strong>details</strong>, it means that there are many internal versions of RocksDB.</li>
</ol>
</td>
</tr>
<tr>
<td colspan="1" rowspan="2">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Peer migration related</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left"><span class="wysiwyg-color-black wysiwyg-font-size-medium">Snapshot: rate snapshot message</span></p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Speed of peer scheduling.</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Reference value: there should not be too much scheduling during the stress test, below 10 is recommended.</p>
</td>
</tr>
<tr>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left"><span class="wysiwyg-color-black wysiwyg-font-size-medium">.9999 snapshot size</span></p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">region The size of the Peer.</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Reference: should be less than 200MB. A large snapshot may cause variation in stress tests.</p>
</td>
</tr>
<tr>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left"><span class="wysiwyg-color-black wysiwyg-font-size-medium">Scheduler</span></p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left"><span class="wysiwyg-color-black wysiwyg-font-size-medium">pending commands</span></p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">The number of requests being processed. This is usually a write request.</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Reference value: Generally less than 5k. Also check if there is a single TiKV that is significantly higher than other TiKVs, if so state.</p>
<ol class="lst-kix_list_7-0 start" start="1">
<li class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">This TiKV may be a write hotspot</li>
<li class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">This TiKV may be slower than other TiKV writes</li>
</ol>
</td>
</tr>
<tr>
<td colspan="1" rowspan="3">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left"><span class="wysiwyg-color-black wysiwyg-font-size-medium">RocksDB kvdb</span></p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left"><span class="wysiwyg-color-black wysiwyg-font-size-medium">write flow</span></p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Write-in traffic conditions.</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">You can see how much traffic there is between TiKV's by adding by instance to the metric expression. Ideally, all TiKV's will have similar write traffic, and if one TiKV is significantly higher than the others, there is a write hotspot issue.</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Reference value: None</p>
</td>
</tr>
<tr>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left"><span class="wysiwyg-color-black wysiwyg-font-size-medium">read flow</span></p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Read the traffic situation.</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">You can see how much traffic there is between TiKV's by adding by instance to the metric expression. Ideally, all TiKV's will have similar read traffic, if one TiKV is significantly higher than the others, there is a read hotspot issue.</p>
</td>
</tr>
<tr>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left"><span class="wysiwyg-color-black wysiwyg-font-size-medium">keys flow</span></p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">write flow and read flow are in byte units. On the other hand keys flow is a flow calculated based on the number of keys. Ideally, all TiKVs have the same keys flow. A TiKV with a high keys flow with the same write flow will typically obtain a higher CPU usage and is a potential bottleneck.</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Reference value: None</p>
</td>
</tr>
</tbody>
</table>

TiKV Notes:

1. Most of the latency-related metrics shown on grafana is an average value of all TiKVs, and the individual TiKV values can be viewed by modifying grafana's expression and adding **by instance** at the end of the expression. This way you can spot potential problems/cases where a single TiKV is much slower than other TiKVs.
2. Some latency-related metrics also need to **be looked at for .999**, such as **append log duration**, **apply log duration**. The reason is that TiKV uses a pipeline model for processing requests, and if a jam occurs in the middle, it will cause a latency increase for the next batch tasks.
3. If you're having trouble looking at the metric above, you can refer to the TiDB performance map above.

#### 1.2.4 PD Examination Form

<table>
<tbody>
<tr>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left"><strong>coverage</strong></p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left"><strong>Inspection items</strong></p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left"><strong>result</strong></p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left"><strong>Reference value/meaning</strong></p>
</td>
</tr>
<tr>
<td colspan="1" rowspan="2">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left"><span class="wysiwyg-color-black wysiwyg-font-size-medium">Cluster</span></p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left"><span class="wysiwyg-color-black wysiwyg-font-size-medium">Store Status</span></p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Check for TiKVs with abnormal states, such as <strong>disconnect</strong>.</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Reference value: 0</p>
</td>
</tr>
<tr>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left"><span class="wysiwyg-color-black wysiwyg-font-size-medium">Region Health</span></p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Since there are a small number of <strong>extra_peer</strong>&nbsp;/ <strong>learner_peer</strong>&nbsp;/ <strong>pending_peer </strong>in the scheduling, regions that have too many of these three or have other states need to be analyzed.</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Reference value: value for the three should be less than 20 in the default configuration, the others are 0</p>
</td>
</tr>
<tr>
<td colspan="1" rowspan="2">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left"><span class="wysiwyg-color-black wysiwyg-font-size-medium">Operator</span></p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left"><span class="wysiwyg-color-black wysiwyg-font-size-medium">Schedule operator create</span></p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Generate scheduling records, and if the region is balanced with a large number of generated schedules for a long period of time then you need to pay attention to the cause.</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Reference: balance-leader &gt; 100, balance-region &gt; 10, hot-write &lt; 10, lasts more than 1h Indicates a problem.</p>
</td>
</tr>
<tr>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left"><span class="wysiwyg-color-black wysiwyg-font-size-medium">Schedule operator timeout</span></p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Normally there are no scheduling timeouts or a small number of timeouts, if there are persistent scheduling timeouts, you need to pay attention to the cause.</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Reference value: below <span class="wysiwyg-color-black wysiwyg-font-size-medium">1 OPM</span></p>
</td>
</tr>
<tr>
<td colspan="1" rowspan="2">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left"><span class="wysiwyg-color-black wysiwyg-font-size-medium">Statistics -Balance</span></p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left"><span class="wysiwyg-color-black wysiwyg-font-size-medium">Store available</span></p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">If the node configuration is the same, the available space should not vary too much from one TiKV node to another.</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Reference value: Difference not exceeding <strong>50% </strong>for space occupancy below <strong>60%</strong>, a difference not exceeding <strong>20%</strong>; for space occupancy between <strong>60</strong>&nbsp;and <strong>80%</strong>; difference not exceeding <strong>5% </strong>for space occupancy above <strong>80%</strong></p>
</td>
</tr>
<tr>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left"><span class="wysiwyg-color-black wysiwyg-font-size-medium">Store leader/region score</span></p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">The scores of TiKV nodes should be similar, and the curves should converge when the scores change, if they don't converge and there are no down or offline node operations, there is a scheduling problem</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Reference value: None</p>
</td>
</tr>
<tr>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left"><span class="wysiwyg-color-black wysiwyg-font-size-medium">Statistics - hotspot</span></p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left"><span class="wysiwyg-color-black wysiwyg-font-size-medium">Hot write region's leader/peer distribution</span></p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">If there are write hotspots, the leader/peer distribution of the hotspots should be relatively even.</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Reference value: None</p>
</td>
</tr>
<tr>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left"><span class="wysiwyg-color-black wysiwyg-font-size-medium">etcd</span></p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left"><span class="wysiwyg-color-black wysiwyg-font-size-medium">disk WAL fsync duration</span></p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">disk flashing too slowly can cause the PD leader to cut off service.</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Reference value: preferably less than 100ms</p>
</td>
</tr>
<tr>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left"><span class="wysiwyg-color-black wysiwyg-font-size-medium">TiDB</span></p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left"><span class="wysiwyg-color-black wysiwyg-font-size-medium">Handle requests duration</span></p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">The main focus is tso response time, which should be kept at the millisecond range</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Reference value: preferably less than 10ms</p>
</td>
</tr>
<tr>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left"><span class="wysiwyg-color-black wysiwyg-font-size-medium">Heartbeat</span></p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left"><span class="wysiwyg-color-black wysiwyg-font-size-medium">99% Region heartbeat latency</span></p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
</td>
<td colspan="1" rowspan="1">
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">If latency is increasing, indicating the PD has reached the bottleneck of processing region heartbeat</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">&nbsp;</p>
<p class="wysiwyg-color-black wysiwyg-font-size-medium wysiwyg-text-align-left">Reference value: preferably less than 50ms</p>
</td>
</tr>
</tbody>
</table>

## 2 Data reading and writing flowchart

-------------------------------

### 2.1 TiKV Data Writing Flowchart

-------------------------------

![TiKV Data Writing Flowchart](/hc/article_attachments/4410271544855/image-2.png)

### 2.2 TiKV Data Reading Flowchart

-------------------------------

![TiKV Data Reading Flowchart](/hc/article_attachments/4410281641623/image-3.png)

* * *

## 3 Operational instructions

-------------------------------

```
    CPU, disk, and network are the core resources inside a distributed system, and we need to check whether a particular resource of a node becomes the bottleneck of the whole system during the stress test.
```

### 3.1 CPU

-------------------------------

#### 3.1.1 tidb-server

The tidb-server is compute-oriented, so theoretically the CPU can be maxed out during the stress test. However, TiDB often allocates large memory blocks, and the current Go 1.13 implementation is flawed in this area, resulting in very serious lock contention, which results in a cap limit, perhaps 80%.

If this happens, you can choose to try compiling the binary package with Go 1.14 or the soon-to-be-released Go 1.15. Note that all versions prior to v4.0.1, v3.0.15, and v3.1.2 **cannot be compiled** directly with Go 1.15; the DDL module in those versions incorrectly relies on a bug fixed in Go 1.15, which causes problems with all DDL executions.

Or you can avoid this problem by using multiple TiDB instances with NUMA-tied cores. If you don't tie cores in NUMA architecture, the CPU utilization rate may reach 80% and can't go up, the Page Migration of NUMA may be higher, and the corresponding Minor Page Fault will also increase, which will seriously affect the Query Duration, you may see the following situation on the monitor.

![NUMA Statistics](/hc/article_attachments/4410281642391/image-4.png)

The above NUMA statistics can be obtained by several Promethean queries as follows.

```bash
rate(node\_vmstat\_numa\_hit{instance="$host"}\[1m\])  
rate(node\_vmstat\_numa\_local{instance="$host"}\[1m\])  
rate(node\_vmstat\_numa\_miss{ instance="$host"}\[1m\])  
rate(node\_vmstat\_numa\_foreign{instance="$host"}\[1m\])  
rate(node\_vmstat\_numa\_pages\_migrated{instance="$host"}\[ 1m\])
```

Generally speaking, it is normal for NUMA Page Migration to be around one or two hundred.

To see the numa status of the machine via `numactl --hardware`.

```bash
$ numactl --hardware

_available: 2 nodes (0-1)_

_node 0 cpus: 0 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34 36 38_

_node 0 size: 65442 MB_

_node 0 free: 7463 MB_

_node 1 cpus: 1 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31 33 35 37 39_

_node 1 size: 65536 MB_

_node 1 free: 4255 MB_

_node distances:_

_node 0 1_

  _0: 10 21_

  _1: 21 10_
```

Bind the two tidb-servers to separate nodes via taskset.

```bash
# taskset -cp 1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31,33,35,37,39 tidb-server1-pid

# taskset -cp 0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38 tidb-server2-pid
```

After tying cores via taskset, the performance.max-procs parameter of tidb-server needs to be set to the number of cores in a single node, e.g. it should be set to 20 in the example above.

#### 3.1.2 TiKV\-server

CPU load should not be higher than the number of CPU cores. TiKV-server includes not only the computation part but also operations such as reading and writing to disk.

### 3.2 Disks

-------------

#### 3.2.1 Using fio to pressure test the disks used by TiKV

bs=4k mainly depends on iops, because the amount of data per IO is relatively small and iops tends to bottleneck first

```bash
\# fio -ioengine=libaio -bs=4k -direct=1 -thread -rw=write -size=10G -filename=test -name="PingCAP max throughput" -iodepth=4 -runtime=60

 _write:_ _IOPS=57.7k__, BW=225MiB/s (236MB/s) (10.0GiB/45465msec)_
```

```bash
bs=64k mainly depends on band-width, the amount of data per IO is relatively large, bandwidth tends to bottleneck first

\# fio -ioengine=libaio -bs=64k -direct=1 -thread -rw=write -size=10G -filename=test -name="PingCAP max throughput" -iodepth=4 -runtime=60

 _write: IOPS=12.3k,_ _BW=772MiB/s_ _(809MB/s) (10.0GiB/13269msec)_
```

bs=512k mainly depends on the band-width, the amount of data per IO is relatively large, the bandwidth tends to reach the bottleneck first. Compared with the 64k result, if the bandwidth is higher than 64k, it means 64k does not reach the bandwidth limit, and the bandwidth is larger.

```bash
\# fio -ioengine=libaio -bs=512k -direct=1 -thread -rw=write -size=10G -filename=test -name="PingCAP max throughput" -iodepth=4 -runtime=60
```

### 3.3 Network

---------------

TiDB is a distributed system, and the components are connected to each other through the network. When performing performance pressure testing, you need to pay attention not only to the performance of each component itself but also to the network between components. The main concern of the network is latency and bandwidth.

#### 3.3.1 Network latency

In addition, the client sends the request to the tidb-sever, the tidb-sever goes PD to ts, the tidb-server sends the request to the TiKV-server, and the TiKV-server sends it back to the tidb-server. You can see that a request needs to go through many transfers between components. So if the network latency is high, the latency of the request will increase exponentially. This is especially important when deploying across server rooms.

Get the latency between the components with the ping command.

```bash
\# ping 18.237.168.166

_PING 18.237.168.166 (18.237.168.166) 56(84) bytes of data._

_64 bytes from 18.237.168.166: icmp\_seq=1 ttl=63 time=0.686 ms_

_64 bytes from 18.237.168.166: icmp\_seq=2 ttl=63 time=0.321 ms_

_64 bytes from 18.237.168.166: icmp\_seq=3 ttl=63 time=0.354 ms_

_64 bytes from 18.237.168.166: icmp\_seq=4 ttl=63 time=0.331 ms_

_64 bytes from 18.237.168.166: icmp\_seq=5 ttl=63 time=0.339 ms_
```

The **two-site, three-center deployment** scenario requires special attention. TiKV-server and PD-sever off-site should preferably not have a leader. the pressure test program (client) and tidb-server should preferably be deployed in the local server room as well.

#### 3.3.2 Network bandwidth

1\. The machine where the pressure test program (client) is located

The piezo program is the point of origin of all requests and the final point of reception of all results. So the network bandwidth of the machine it is on is very critical.

When writing the pressure test, generally the egress traffic of the client's machine is higher, and when reading the pressure test, the ingress traffic of the client's machine will be higher. If the NIC bandwidth of the client's machine has already hit its limit, you need to add more press tests to the machine.

2\. haproxy machine

If haproxy is used for load balancing during the pressure test, you need to pay special attention to whether the bandwidth of the machine where haproxy is located is full, as the haproxy node is the transit node for all traffic.

3\. tidb-server machine

You also need to pay attention to the network bandwidth usage of the machine where the tidb-server is located during the compression test. Especially if there are only a few or even only one tidb-server.

4\. TiKV-server machine

The network bandwidth usage of the TiKV-server machine is definitely something to look at as well. For example, are there any write hotspots or read hotspots that are causing a single TiKV-server to have much more traffic than other TiKV-servers, thus causing the network bandwidth of this TiKV-server machine to hit full capacity.

Network traffic can be viewed with the nload or iptraf commands. To view network traffic using nload.

```bash
\# nload

_Device ens5 \[172.31.22.58\] (1/2):_

_\======================================================================_

_Incoming:_

                                                                                                                         _Curr: 1.02 kBit/s_

                                                                                                                         _Avg: 1.15 kBit/s_

                                                                                                                         _Min: 520.00 Bit/s_

                                                                                                                         _Max: 4.11 kBit/s_

                                                                                                                         _Ttl: 33.62 GByte_

_Outgoing:_

                                                                                                                       _Curr: 9.55 kBit/s_

                                                                                                                       _Avg: 10.39 kBit/s_

                                                                                                                       _Min: 4.05 kBit/s_

                                                                                                                       _Max: 14.34 kBit/s_

                                                                                                                       _Ttl: 584.38 GByte_
```

* * *

## 4 Performance POC FAQ

------------------------

### References

This is a draft translation of [TiDB 集群压测性能瓶颈分析指南](https://docs.google.com/document/d/1PNtOB8-SOelLIjHsxjXuWOo8RjPB7LHkEBbOd1fX7sc/edit#heading=h.iw14kt6g182h)

[tidb-map.svg](https://drive.google.com/file/d/1YR6n8DpWcw_SQSVa24S6T8WIMMOLg74K/view)