为什么更新的字段值是随机的,TiDB 性能下降 10 倍?
Why the TiDB performance drop for 10 times when the updated field value is random?
我设置了 TiDB、TiKV 和 PD 集群,以便使用由 MySQL 驱动程序连接的 YCSB 工具对它们进行基准测试。
该集群由 TiDB、TiKV 和 PD 各有 5 个实例组成。
每个节点 运行 一个 TiDB、TiKV 和 PD 实例。
但是,当我在更新语句中使用 YCSB 代码时,我注意到如果更新字段的值是固定的和硬编码的,则总吞吐量约为 30K tps,延迟约为 30 毫秒。如果更新的字段值是随机的,则总吞吐量约为 2k tps,延迟约为 300 毫秒。
更新语句创建代码如下:
@Override
public String createUpdateStatement(StatementType updateType) {
String[] fieldKeys = updateType.getFieldString().split(",");
StringBuilder update = new StringBuilder("UPDATE ");
update.append(updateType.getTableName());
update.append(" SET ");
for (int i = 0; i < fieldKeys.length; i++) {
update.append(fieldKeys[i]);
String randStr = RandomCharStr(); // 1) 3K tps with 300ms latency
//String randStr = "Hardcode-Field-Value"; // 2) 20K tps with 20ms latency
update.append(" = '" + randStr + "'");
if (i < fieldKeys.length - 1) {
update.append(", ");
}
}
// update.append(fieldKey);
update.append(" WHERE ");
update.append(JdbcDBClient.PRIMARY_KEY);
update.append(" = ?");
return update.toString();
}
我们如何解释这种性能差距?
是否由于 DistSQL 查询缓存,如本 post?
中所述
我设法从这个 post (Same transaction returns different results when i ran multiply times) and pr (https://github.com/pingcap/tidb/issues/7644) 中弄清楚了这一点。
这是因为如果更新的字段与之前的值相同,TiDB 将不会执行 txn。
我设置了 TiDB、TiKV 和 PD 集群,以便使用由 MySQL 驱动程序连接的 YCSB 工具对它们进行基准测试。 该集群由 TiDB、TiKV 和 PD 各有 5 个实例组成。 每个节点 运行 一个 TiDB、TiKV 和 PD 实例。
但是,当我在更新语句中使用 YCSB 代码时,我注意到如果更新字段的值是固定的和硬编码的,则总吞吐量约为 30K tps,延迟约为 30 毫秒。如果更新的字段值是随机的,则总吞吐量约为 2k tps,延迟约为 300 毫秒。
更新语句创建代码如下:
@Override
public String createUpdateStatement(StatementType updateType) {
String[] fieldKeys = updateType.getFieldString().split(",");
StringBuilder update = new StringBuilder("UPDATE ");
update.append(updateType.getTableName());
update.append(" SET ");
for (int i = 0; i < fieldKeys.length; i++) {
update.append(fieldKeys[i]);
String randStr = RandomCharStr(); // 1) 3K tps with 300ms latency
//String randStr = "Hardcode-Field-Value"; // 2) 20K tps with 20ms latency
update.append(" = '" + randStr + "'");
if (i < fieldKeys.length - 1) {
update.append(", ");
}
}
// update.append(fieldKey);
update.append(" WHERE ");
update.append(JdbcDBClient.PRIMARY_KEY);
update.append(" = ?");
return update.toString();
}
我们如何解释这种性能差距? 是否由于 DistSQL 查询缓存,如本 post?
中所述我设法从这个 post (Same transaction returns different results when i ran multiply times) and pr (https://github.com/pingcap/tidb/issues/7644) 中弄清楚了这一点。 这是因为如果更新的字段与之前的值相同,TiDB 将不会执行 txn。