github.com/pingcap/ticdc@v0.0.0-20220526033649-485a10ef2652/pkg/scheduler/workload.go (about) 1 // Copyright 2020 PingCAP, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 package scheduler 15 16 import ( 17 "math" 18 19 "github.com/pingcap/ticdc/cdc/model" 20 ) 21 22 type workloads map[model.CaptureID]model.TaskWorkload 23 24 func (w workloads) SetCapture(captureID model.CaptureID, workloads model.TaskWorkload) { 25 w[captureID] = workloads 26 } 27 28 func (w workloads) AlignCapture(captureIDs map[model.CaptureID]struct{}) { 29 for captureID := range captureIDs { 30 if _, exist := w[captureID]; !exist { 31 w[captureID] = make(model.TaskWorkload) 32 } 33 } 34 for captureID := range w { 35 if _, exist := captureIDs[captureID]; !exist { 36 delete(w, captureID) 37 } 38 } 39 } 40 41 func (w workloads) SetTable(captureID model.CaptureID, tableID model.TableID, workload model.WorkloadInfo) { 42 captureWorkloads, exist := w[captureID] 43 if !exist { 44 captureWorkloads = make(model.TaskWorkload) 45 w[captureID] = captureWorkloads 46 } 47 captureWorkloads[tableID] = workload 48 } 49 50 func (w workloads) RemoveTable(captureID model.CaptureID, tableID model.TableID) { 51 captureWorkloads, exist := w[captureID] 52 if !exist { 53 return 54 } 55 delete(captureWorkloads, tableID) 56 } 57 58 func (w workloads) AvgEachTable() uint64 { 59 var totalWorkload uint64 60 var totalTable uint64 61 for _, captureWorkloads := range w { 62 for _, workload := range captureWorkloads { 63 totalWorkload += workload.Workload 64 } 65 totalTable += uint64(len(captureWorkloads)) 66 } 67 return totalWorkload / totalTable 68 } 69 70 func (w workloads) Skewness() float64 { 71 totalWorkloads := make([]uint64, 0, len(w)) 72 var workloadSum uint64 73 for _, captureWorkloads := range w { 74 var total uint64 75 for _, workload := range captureWorkloads { 76 total += workload.Workload 77 } 78 totalWorkloads = append(totalWorkloads, total) 79 workloadSum += total 80 } 81 avgWorkload := float64(workloadSum) / float64(len(w)) 82 83 var totalVariance float64 84 for _, totalWorkload := range totalWorkloads { 85 totalVariance += math.Pow((float64(totalWorkload)/avgWorkload)-1, 2) 86 } 87 return math.Sqrt(totalVariance / float64(len(w))) 88 } 89 90 func (w workloads) SelectIdleCapture() model.CaptureID { 91 minWorkload := uint64(math.MaxUint64) 92 var minCapture model.CaptureID 93 for captureID, captureWorkloads := range w { 94 var totalWorkloadInCapture uint64 95 for _, workload := range captureWorkloads { 96 totalWorkloadInCapture += workload.Workload 97 } 98 if minWorkload > totalWorkloadInCapture { 99 minWorkload = totalWorkloadInCapture 100 minCapture = captureID 101 } 102 } 103 return minCapture 104 } 105 106 func (w workloads) Clone() workloads { 107 cloneWorkloads := make(map[model.CaptureID]model.TaskWorkload, len(w)) 108 for captureID, captureWorkloads := range w { 109 cloneCaptureWorkloads := make(model.TaskWorkload, len(captureWorkloads)) 110 for tableID, workload := range captureWorkloads { 111 cloneCaptureWorkloads[tableID] = workload 112 } 113 cloneWorkloads[captureID] = cloneCaptureWorkloads 114 } 115 return cloneWorkloads 116 }