Skip to content

Commit

Permalink
resource_control: calibrate resource support sysbench (#42695)
Browse files Browse the repository at this point in the history
ref #38825
  • Loading branch information
HuSharp authored Apr 14, 2023
1 parent 2062b68 commit 15ce809
Show file tree
Hide file tree
Showing 9 changed files with 10,185 additions and 10,027 deletions.
5 changes: 4 additions & 1 deletion executor/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -839,7 +839,10 @@ func (b *executorBuilder) buildSimple(v *plannercore.Simple) Executor {
}
}
case *ast.CalibrateResourceStmt:
return b.buildCalibrateResource(v.Schema())
return &calibrateResourceExec{
baseExecutor: newBaseExecutor(b.ctx, v.Schema(), 0),
workloadType: s.Tp,
}
case *ast.LoadDataActionStmt:
return &LoadDataActionExec{
baseExecutor: newBaseExecutor(b.ctx, nil, 0),
Expand Down
63 changes: 39 additions & 24 deletions executor/calibrate_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,40 +21,57 @@ import (

"github.com/docker/go-units"
"github.com/pingcap/errors"
"github.com/pingcap/tidb/expression"
"github.com/pingcap/tidb/kv"
"github.com/pingcap/tidb/parser/ast"
"github.com/pingcap/tidb/util/chunk"
"github.com/pingcap/tidb/util/sqlexec"
)

const (
// the workload name of TPC-C
workloadTpcc = "tpcc"
// the default workload to calculate the RU capacity.
defaultWorkload = workloadTpcc
)

// workloadBaseRUCostMap contains the base resource cost rate per 1 kv cpu within 1 second,
// the data is calculated from benchmark result, these data might not be very accurate,
// but is enough here because the maximum RU capacity is depend on both the cluster and
// but is enough here because the maximum RU capacity is depended on both the cluster and
// the workload.
var workloadBaseRUCostMap = map[string]*baseResourceCost{
workloadTpcc: {
var workloadBaseRUCostMap = map[ast.CalibrateResourceType]*baseResourceCost{
ast.TPCC: {
tidbCPU: 0.6,
kvCPU: 0.15,
readBytes: units.MiB / 2,
writeBytes: units.MiB,
readReqCount: 300,
writeReqCount: 1750,
},
ast.OLTPREADWRITE: {
tidbCPU: 1.25,
kvCPU: 0.35,
readBytes: units.MiB * 4.25,
writeBytes: units.MiB / 3,
readReqCount: 1600,
writeReqCount: 1400,
},
ast.OLTPREADONLY: {
tidbCPU: 2,
kvCPU: 0.52,
readBytes: units.MiB * 28,
writeBytes: 0,
readReqCount: 4500,
writeReqCount: 0,
},
ast.OLTPWRITEONLY: {
tidbCPU: 1,
kvCPU: 0,
readBytes: 0,
writeBytes: units.MiB,
readReqCount: 0,
writeReqCount: 3550,
},
}

// the resource cost rate of a specified workload per 1 tikv cpu
type baseResourceCost struct {
// the average tikv cpu time, this is used to calculate whether tikv cpu
// or tidb cpu is the performance bottle neck.
tidbCPU float64
// the kv CPU time for calculate RU, it's smaller than the actually cpu usage.
// the kv CPU time for calculate RU, it's smaller than the actual cpu usage.
kvCPU float64
// the read bytes rate per 1 tikv cpu.
readBytes uint64
Expand All @@ -66,15 +83,11 @@ type baseResourceCost struct {
writeReqCount uint64
}

func (b *executorBuilder) buildCalibrateResource(schema *expression.Schema) Executor {
return &calibrateResourceExec{
baseExecutor: newBaseExecutor(b.ctx, schema, 0),
}
}

type calibrateResourceExec struct {
baseExecutor
done bool

workloadType ast.CalibrateResourceType
done bool
}

func (e *calibrateResourceExec) Next(ctx context.Context, req *chunk.Chunk) error {
Expand Down Expand Up @@ -102,11 +115,13 @@ func (e *calibrateResourceExec) Next(ctx context.Context, req *chunk.Chunk) erro
return err
}

// we only support TPC-C currently, will support more in the future.
workload := defaultWorkload
baseCost, ok := workloadBaseRUCostMap[workload]
// The default workload to calculate the RU capacity.
if e.workloadType == ast.WorkloadNone {
e.workloadType = ast.TPCC
}
baseCost, ok := workloadBaseRUCostMap[e.workloadType]
if !ok {
return errors.Errorf("unknown workload '%s'", workload)
return errors.Errorf("unknown workload '%T'", e.workloadType)
}

if totalTiDBCPU/baseCost.tidbCPU < totalKVCPUQuota {
Expand All @@ -132,7 +147,7 @@ type ruConfig struct {
}

func getRUSettings(ctx context.Context, exec sqlexec.RestrictedSQLExecutor) (*ruConfig, error) {
rows, fields, err := exec.ExecRestrictedSQL(ctx, []sqlexec.OptionFuncAlias{sqlexec.ExecOptionUseCurSession}, "SHOW CONFIG WHERE TYPE = 'pd' AND name like 'controller.request-unit.%'")
rows, fields, err := exec.ExecRestrictedSQL(ctx, []sqlexec.OptionFuncAlias{sqlexec.ExecOptionUseCurSession}, "SHOW CONFIG WHERE TYPE = 'pd' AND name like 'controller.request-unit.%'")
if err != nil {
return nil, errors.Trace(err)
}
Expand Down
6 changes: 5 additions & 1 deletion executor/calibrate_resource_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ func TestCalibrateResource(t *testing.T) {
return items
}

// empty requet-unit config error
// empty request-unit config error
rs, err := tk.Exec("CALIBRATE RESOURCE")
require.NoError(t, err)
require.NotNil(t, rs)
Expand Down Expand Up @@ -96,6 +96,10 @@ func TestCalibrateResource(t *testing.T) {
return fpName == fpname
})
tk.MustQueryWithContext(ctx, "CALIBRATE RESOURCE").Check(testkit.Rows("68569"))
tk.MustQueryWithContext(ctx, "CALIBRATE RESOURCE WORKLOAD TPCC").Check(testkit.Rows("68569"))
tk.MustQueryWithContext(ctx, "CALIBRATE RESOURCE WORKLOAD OLTP_READ_WRITE").Check(testkit.Rows("53026"))
tk.MustQueryWithContext(ctx, "CALIBRATE RESOURCE WORKLOAD OLTP_READ_ONLY").Check(testkit.Rows("31463"))
tk.MustQueryWithContext(ctx, "CALIBRATE RESOURCE WORKLOAD OLTP_WRITE_ONLY").Check(testkit.Rows("109776"))

// change total tidb cpu to less than tikv_cpu_quota
mockData["tidb_server_maxprocs"] = [][]types.Datum{
Expand Down
4 changes: 2 additions & 2 deletions metrics/grafana/tidb_resource_control.json
Original file line number Diff line number Diff line change
Expand Up @@ -2164,7 +2164,7 @@
"timeFrom": null,
"timeRegions": [],
"timeShift": null,
"title": "Seccessful KV Request Wait Duration",
"title": "Successful KV Request Wait Duration",
"tooltip": {
"msResolution": true,
"shared": true,
Expand Down Expand Up @@ -2280,7 +2280,7 @@
"timeFrom": null,
"timeRegions": [],
"timeShift": null,
"title": "Seccessful KV Request Count",
"title": "Successful KV Request Count",
"tooltip": {
"msResolution": true,
"shared": true,
Expand Down
30 changes: 30 additions & 0 deletions parser/ast/misc.go
Original file line number Diff line number Diff line change
Expand Up @@ -3721,14 +3721,44 @@ func (n *SetResourceGroupStmt) Accept(v Visitor) (Node, bool) {
return v.Leave(n)
}

// CalibrateResourceType is the type for CalibrateResource statement.
type CalibrateResourceType int

// calibrate resource [ workload < TPCC | OLTP_READ_WRITE | OLTP_READ_ONLY | OLTP_WRITE_ONLY> ]
const (
WorkloadNone CalibrateResourceType = iota
TPCC
OLTPREADWRITE
OLTPREADONLY
OLTPWRITEONLY
)

func (n CalibrateResourceType) Restore(ctx *format.RestoreCtx) error {
switch n {
case TPCC:
ctx.WriteKeyWord(" WORKLOAD TPCC")
case OLTPREADWRITE:
ctx.WriteKeyWord(" WORKLOAD OLTP_READ_WRITE")
case OLTPREADONLY:
ctx.WriteKeyWord(" WORKLOAD OLTP_READ_ONLY")
case OLTPWRITEONLY:
ctx.WriteKeyWord(" WORKLOAD OLTP_WRITE_ONLY")
}
return nil
}

// CalibrateResourceStmt is a statement to fetch the cluster RU capacity
type CalibrateResourceStmt struct {
stmtNode
Tp CalibrateResourceType
}

// Restore implements Node interface.
func (n *CalibrateResourceStmt) Restore(ctx *format.RestoreCtx) error {
ctx.WriteKeyWord("CALIBRATE RESOURCE")
if err := n.Tp.Restore(ctx); err != nil {
return errors.Annotate(err, "An error occurred while restore CalibrateResourceStmt.CalibrateResourceType")
}
return nil
}

Expand Down
5 changes: 5 additions & 0 deletions parser/misc.go
Original file line number Diff line number Diff line change
Expand Up @@ -539,6 +539,9 @@ var tokenMap = map[string]int{
"OF": of,
"OFF": off,
"OFFSET": offset,
"OLTP_READ_ONLY": oltpReadOnly,
"OLTP_READ_WRITE": oltpReadWrite,
"OLTP_WRITE_ONLY": oltpWriteOnly,
"ON_DUPLICATE": onDuplicate,
"ON": on,
"ONLINE": online,
Expand Down Expand Up @@ -785,6 +788,7 @@ var tokenMap = map[string]int{
"TOKUDB_ZSTD": tokudbZstd,
"TOP": top,
"TOPN": topn,
"TPCC": tpcc,
"TRACE": trace,
"TRADITIONAL": traditional,
"TRAILING": trailing,
Expand Down Expand Up @@ -844,6 +848,7 @@ var tokenMap = map[string]int{
"WITH": with,
"WITHOUT": without,
"WRITE": write,
"WORKLOAD": workload,
"X509": x509,
"XOR": xor,
"YEAR_MONTH": yearMonth,
Expand Down
Loading

0 comments on commit 15ce809

Please sign in to comment.