From 5fb9a6e366abd090561328951fb9073568d08b64 Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Thu, 11 Jul 2024 09:46:47 +0300 Subject: [PATCH 01/20] rename variable mysqlMetricThresholds to metricThresholds Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- .../tabletserver/throttle/throttler.go | 32 +++++++++---------- .../tabletserver/throttle/throttler_test.go | 20 ++++++------ 2 files changed, 26 insertions(+), 26 deletions(-) diff --git a/go/vt/vttablet/tabletserver/throttle/throttler.go b/go/vt/vttablet/tabletserver/throttle/throttler.go index e3e36123e7e..2535150e97a 100644 --- a/go/vt/vttablet/tabletserver/throttle/throttler.go +++ b/go/vt/vttablet/tabletserver/throttle/throttler.go @@ -192,12 +192,12 @@ type Throttler struct { MetricsThreshold atomic.Uint64 checkAsCheckSelf atomic.Bool - mysqlMetricThresholds *cache.Cache - aggregatedMetrics *cache.Cache - throttledApps *cache.Cache - recentApps *cache.Cache - metricsHealth *cache.Cache - appCheckedMetrics *cache.Cache + metricThresholds *cache.Cache + aggregatedMetrics *cache.Cache + throttledApps *cache.Cache + recentApps *cache.Cache + metricsHealth *cache.Cache + appCheckedMetrics *cache.Cache initMutex sync.Mutex enableMutex sync.Mutex @@ -258,7 +258,7 @@ func NewThrottler(env tabletenv.Env, srvTopoServer srvtopo.Server, ts *topo.Serv throttler.mysqlInventory = mysql.NewInventory() throttler.throttledApps = cache.New(cache.NoExpiration, 0) - throttler.mysqlMetricThresholds = cache.New(cache.NoExpiration, 0) + throttler.metricThresholds = cache.New(cache.NoExpiration, 0) throttler.aggregatedMetrics = cache.New(aggregatedMetricsExpiration, 0) throttler.recentApps = cache.New(recentAppsExpiration, recentAppsExpiration) throttler.metricsHealth = cache.New(cache.NoExpiration, 0) @@ -426,14 +426,14 @@ func (throttler *Throttler) WatchSrvKeyspaceCallback(srvks *topodatapb.SrvKeyspa // - throttler config. This can be a list of zero or more entries. These metrics override the inventory. func (throttler *Throttler) convergeMetricThresholds() { for _, metricName := range base.KnownMetricNames { - if val, ok := throttler.mysqlMetricThresholds.Get(throttlerConfigPrefix + metricName.String()); ok { + if val, ok := throttler.metricThresholds.Get(throttlerConfigPrefix + metricName.String()); ok { // Value supplied by throttler config takes precedence - throttler.mysqlMetricThresholds.Set(metricName.String(), val, cache.DefaultExpiration) + throttler.metricThresholds.Set(metricName.String(), val, cache.DefaultExpiration) continue } // metric not indicated in the throttler config, therefore we should use the default threshold for that metric - if val, ok := throttler.mysqlMetricThresholds.Get(inventoryPrefix + metricName.String()); ok { - throttler.mysqlMetricThresholds.Set(metricName.String(), val, cache.DefaultExpiration) + if val, ok := throttler.metricThresholds.Get(inventoryPrefix + metricName.String()); ok { + throttler.metricThresholds.Set(metricName.String(), val, cache.DefaultExpiration) } } } @@ -502,13 +502,13 @@ func (throttler *Throttler) applyThrottlerConfig(ctx context.Context, throttlerC { // Metric thresholds for metricName, threshold := range throttlerConfig.MetricThresholds { - throttler.mysqlMetricThresholds.Set(throttlerConfigPrefix+metricName, threshold, cache.DefaultExpiration) + throttler.metricThresholds.Set(throttlerConfigPrefix+metricName, threshold, cache.DefaultExpiration) } for _, metricName := range base.KnownMetricNames { if _, ok := throttlerConfig.MetricThresholds[metricName.String()]; !ok { // metric not indicated in the throttler config, therefore should be removed from the map // so that we know to apply the inventory default threshold - throttler.mysqlMetricThresholds.Delete(throttlerConfigPrefix + metricName.String()) + throttler.metricThresholds.Delete(throttlerConfigPrefix + metricName.String()) } } throttler.convergeMetricThresholds() @@ -1181,7 +1181,7 @@ func (throttler *Throttler) refreshMySQLInventory(ctx context.Context) error { threshold = metricsThreshold } - throttler.mysqlMetricThresholds.Set(inventoryPrefix+metricName.String(), math.Float64frombits(threshold), cache.DefaultExpiration) + throttler.metricThresholds.Set(inventoryPrefix+metricName.String(), math.Float64frombits(threshold), cache.DefaultExpiration) } throttler.convergeMetricThresholds() clusterSettingsCopy := *mysqlSettings @@ -1284,7 +1284,7 @@ func (throttler *Throttler) getAggregatedMetric(aggregatedName string) base.Metr } func (throttler *Throttler) getMySQLStoreMetric(ctx context.Context, scope base.Scope, metricName base.MetricName) (base.MetricResult, float64) { - thresholdVal, found := throttler.mysqlMetricThresholds.Get(metricName.String()) + thresholdVal, found := throttler.metricThresholds.Get(metricName.String()) if !found { return base.NoSuchMetric, 0 } @@ -1295,7 +1295,7 @@ func (throttler *Throttler) getMySQLStoreMetric(ctx context.Context, scope base. func (throttler *Throttler) mysqlMetricThresholdsSnapshot() map[string]float64 { snapshot := make(map[string]float64) - for key, value := range throttler.mysqlMetricThresholds.Items() { + for key, value := range throttler.metricThresholds.Items() { threshold, _ := value.Object.(float64) snapshot[key] = threshold } diff --git a/go/vt/vttablet/tabletserver/throttle/throttler_test.go b/go/vt/vttablet/tabletserver/throttle/throttler_test.go index d9b910a3152..aba313c91cf 100644 --- a/go/vt/vttablet/tabletserver/throttle/throttler_test.go +++ b/go/vt/vttablet/tabletserver/throttle/throttler_test.go @@ -253,7 +253,7 @@ func newTestThrottler() *Throttler { throttler.mysqlInventory = mysql.NewInventory() throttler.throttledApps = cache.New(cache.NoExpiration, 0) - throttler.mysqlMetricThresholds = cache.New(cache.NoExpiration, 0) + throttler.metricThresholds = cache.New(cache.NoExpiration, 0) throttler.aggregatedMetrics = cache.New(10*aggregatedMetricsExpiration, 0) throttler.recentApps = cache.New(recentAppsExpiration, 0) throttler.metricsHealth = cache.New(cache.NoExpiration, 0) @@ -380,17 +380,17 @@ func TestApplyThrottlerConfig(t *testing.T) { }) t.Run("metric thresholds", func(t *testing.T) { { - val, ok := throttler.mysqlMetricThresholds.Get("lag") + val, ok := throttler.metricThresholds.Get("lag") require.True(t, ok) assert.Equal(t, float64(0.75), val) } { - val, ok := throttler.mysqlMetricThresholds.Get("threads_running") + val, ok := throttler.metricThresholds.Get("threads_running") require.True(t, ok) assert.Equal(t, float64(3.0), val) } { - val, ok := throttler.mysqlMetricThresholds.Get("loadavg") + val, ok := throttler.metricThresholds.Get("loadavg") require.True(t, ok) assert.Equal(t, float64(1.0), val) } @@ -432,7 +432,7 @@ func TestApplyThrottlerConfigMetricThresholds(t *testing.T) { t.Run("check low threshold", func(t *testing.T) { sleepTillThresholdApplies() { - _, ok := throttler.mysqlMetricThresholds.Get("config/lag") + _, ok := throttler.metricThresholds.Get("config/lag") assert.False(t, ok) } assert.Equal(t, float64(0.0033), throttler.GetMetricsThreshold()) @@ -455,7 +455,7 @@ func TestApplyThrottlerConfigMetricThresholds(t *testing.T) { t.Run("check with high 'lag' threshold", func(t *testing.T) { sleepTillThresholdApplies() { - val, ok := throttler.mysqlMetricThresholds.Get("config/lag") + val, ok := throttler.metricThresholds.Get("config/lag") require.True(t, ok) assert.Equal(t, float64(4444), val) } @@ -471,17 +471,17 @@ func TestApplyThrottlerConfigMetricThresholds(t *testing.T) { assert.Equal(t, float64(0.0033), throttler.GetMetricsThreshold()) t.Run("metric thresholds", func(t *testing.T) { { - val, ok := throttler.mysqlMetricThresholds.Get("config/lag") + val, ok := throttler.metricThresholds.Get("config/lag") require.True(t, ok) assert.Equal(t, float64(4444), val) } { - val, ok := throttler.mysqlMetricThresholds.Get("inventory/lag") + val, ok := throttler.metricThresholds.Get("inventory/lag") require.True(t, ok) assert.Equal(t, float64(0.0033), val) } { - val, ok := throttler.mysqlMetricThresholds.Get("lag") + val, ok := throttler.metricThresholds.Get("lag") require.True(t, ok) assert.Equal(t, float64(4444), val) } @@ -903,7 +903,7 @@ func TestRefreshMySQLInventory(t *testing.T) { throttler := &Throttler{ mysqlClusterProbesChan: make(chan *mysql.ClusterProbes), - mysqlMetricThresholds: cache.New(cache.NoExpiration, 0), + metricThresholds: cache.New(cache.NoExpiration, 0), ts: &FakeTopoServer{}, mysqlInventory: mysql.NewInventory(), } From c6d70474b796ebf3fa7cc1e4e29888f72faf0c29 Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Thu, 11 Jul 2024 09:47:07 +0300 Subject: [PATCH 02/20] rename function mysqlMetricThresholdsSnapshot to metricThresholdsSnapshot Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- go/vt/vttablet/tabletserver/throttle/throttler.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/go/vt/vttablet/tabletserver/throttle/throttler.go b/go/vt/vttablet/tabletserver/throttle/throttler.go index 2535150e97a..042a8aa6c9f 100644 --- a/go/vt/vttablet/tabletserver/throttle/throttler.go +++ b/go/vt/vttablet/tabletserver/throttle/throttler.go @@ -1293,7 +1293,7 @@ func (throttler *Throttler) getMySQLStoreMetric(ctx context.Context, scope base. return throttler.getAggregatedMetric(aggregatedName), threshold } -func (throttler *Throttler) mysqlMetricThresholdsSnapshot() map[string]float64 { +func (throttler *Throttler) metricThresholdsSnapshot() map[string]float64 { snapshot := make(map[string]float64) for key, value := range throttler.metricThresholds.Items() { threshold, _ := value.Object.(float64) @@ -1650,7 +1650,7 @@ func (throttler *Throttler) Status() *ThrottlerStatus { MetricNameUsedAsDefault: throttler.metricNameUsedAsDefault().String(), AggregatedMetrics: throttler.aggregatedMetricsSnapshot(), - MetricsThresholds: throttler.mysqlMetricThresholdsSnapshot(), + MetricsThresholds: throttler.metricThresholdsSnapshot(), MetricsHealth: throttler.metricsHealthSnapshot(), ThrottledApps: throttler.ThrottledApps(), AppCheckedMetrics: throttler.appCheckedMetricsSnapshot(), From 9eb59b312e4e64b8c8f2fc4e28cf361085161176 Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Thu, 11 Jul 2024 09:48:49 +0300 Subject: [PATCH 03/20] rename *Interval variables away from 'mysql' Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- .../tabletserver/throttle/throttler.go | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/go/vt/vttablet/tabletserver/throttle/throttler.go b/go/vt/vttablet/tabletserver/throttle/throttler.go index 042a8aa6c9f..dcd6b196b8f 100644 --- a/go/vt/vttablet/tabletserver/throttle/throttler.go +++ b/go/vt/vttablet/tabletserver/throttle/throttler.go @@ -85,10 +85,10 @@ import ( const ( leaderCheckInterval = 5 * time.Second - mysqlCollectInterval = 250 * time.Millisecond // PRIMARY polls replicas - mysqlDormantCollectInterval = 5 * time.Second // PRIMARY polls replicas when dormant (no recent checks) - mysqlRefreshInterval = 10 * time.Second // Refreshing tablet inventory - mysqlAggregateInterval = 125 * time.Millisecond + activeCollectInterval = 250 * time.Millisecond // PRIMARY polls replicas + dormantCollectInterval = 5 * time.Second // PRIMARY polls replicas when dormant (no recent checks) + inventoryRefreshInterval = 10 * time.Second // Refreshing tablet inventory + metricsAggregateInterval = 125 * time.Millisecond throttledAppsSnapshotInterval = 5 * time.Second recentCheckRateLimiterInterval = 1 * time.Second // Ticker assisting in determining when the throttler was last checked @@ -264,15 +264,15 @@ func NewThrottler(env tabletenv.Env, srvTopoServer srvtopo.Server, ts *topo.Serv throttler.metricsHealth = cache.New(cache.NoExpiration, 0) throttler.appCheckedMetrics = cache.New(cache.NoExpiration, 0) - throttler.httpClient = base.SetupHTTPClient(2 * mysqlCollectInterval) + throttler.httpClient = base.SetupHTTPClient(2 * activeCollectInterval) throttler.initThrottleTabletTypes() throttler.check = NewThrottlerCheck(throttler) throttler.leaderCheckInterval = leaderCheckInterval - throttler.mysqlCollectInterval = mysqlCollectInterval - throttler.mysqlDormantCollectInterval = mysqlDormantCollectInterval - throttler.mysqlRefreshInterval = mysqlRefreshInterval - throttler.mysqlAggregateInterval = mysqlAggregateInterval + throttler.mysqlCollectInterval = activeCollectInterval + throttler.mysqlDormantCollectInterval = dormantCollectInterval + throttler.mysqlRefreshInterval = inventoryRefreshInterval + throttler.mysqlAggregateInterval = metricsAggregateInterval throttler.throttledAppsSnapshotInterval = throttledAppsSnapshotInterval throttler.dormantPeriod = dormantPeriod throttler.recentCheckDormantDiff = int64(throttler.dormantPeriod / recentCheckRateLimiterInterval) @@ -1012,7 +1012,7 @@ func (throttler *Throttler) generateTabletProbeFunction(scope base.Scope, tmClie } return func(ctx context.Context) mysql.MySQLThrottleMetrics { // Some reasonable timeout, to ensure we release connections even if they're hanging (otherwise grpc-go keeps polling those connections forever) - ctx, cancel := context.WithTimeout(ctx, 4*mysqlCollectInterval) + ctx, cancel := context.WithTimeout(ctx, 4*activeCollectInterval) defer cancel() // Hit a tablet's `check-self` via HTTP, and convert its CheckResult JSON output into a MySQLThrottleMetric @@ -1205,7 +1205,7 @@ func (throttler *Throttler) refreshMySQLInventory(ctx context.Context) error { // not the leader (primary tablet)? Then no more work for us. } // The primary tablet is also in charge of collecting the shard's metrics - ctx, cancel := context.WithTimeout(ctx, mysqlRefreshInterval) + ctx, cancel := context.WithTimeout(ctx, inventoryRefreshInterval) defer cancel() tabletAliases, err := throttler.ts.FindAllTabletAliasesInShard(ctx, throttler.keyspace, throttler.shard) From 9f2716af8e8459659334014b3d2b43db73b78a28 Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Thu, 11 Jul 2024 09:49:32 +0300 Subject: [PATCH 04/20] rename *Interval variables away from 'mysql' Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- .../tabletserver/throttle/throttler.go | 24 +++++++++---------- .../tabletserver/throttle/throttler_test.go | 8 +++---- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/go/vt/vttablet/tabletserver/throttle/throttler.go b/go/vt/vttablet/tabletserver/throttle/throttler.go index dcd6b196b8f..2da4ee9475a 100644 --- a/go/vt/vttablet/tabletserver/throttle/throttler.go +++ b/go/vt/vttablet/tabletserver/throttle/throttler.go @@ -157,10 +157,10 @@ type Throttler struct { isOpen atomic.Bool leaderCheckInterval time.Duration - mysqlCollectInterval time.Duration - mysqlDormantCollectInterval time.Duration - mysqlRefreshInterval time.Duration - mysqlAggregateInterval time.Duration + activeCollectInterval time.Duration + dormantCollectInterval time.Duration + inventoryRefreshInterval time.Duration + metricsAggregateInterval time.Duration throttledAppsSnapshotInterval time.Duration dormantPeriod time.Duration @@ -269,10 +269,10 @@ func NewThrottler(env tabletenv.Env, srvTopoServer srvtopo.Server, ts *topo.Serv throttler.check = NewThrottlerCheck(throttler) throttler.leaderCheckInterval = leaderCheckInterval - throttler.mysqlCollectInterval = activeCollectInterval - throttler.mysqlDormantCollectInterval = dormantCollectInterval - throttler.mysqlRefreshInterval = inventoryRefreshInterval - throttler.mysqlAggregateInterval = metricsAggregateInterval + throttler.activeCollectInterval = activeCollectInterval + throttler.dormantCollectInterval = dormantCollectInterval + throttler.inventoryRefreshInterval = inventoryRefreshInterval + throttler.metricsAggregateInterval = metricsAggregateInterval throttler.throttledAppsSnapshotInterval = throttledAppsSnapshotInterval throttler.dormantPeriod = dormantPeriod throttler.recentCheckDormantDiff = int64(throttler.dormantPeriod / recentCheckRateLimiterInterval) @@ -862,10 +862,10 @@ func (throttler *Throttler) Operate(ctx context.Context, wg *sync.WaitGroup) { return t } leaderCheckTicker := addTicker(throttler.leaderCheckInterval) - mysqlCollectTicker := addTicker(throttler.mysqlCollectInterval) - mysqlDormantCollectTicker := addTicker(throttler.mysqlDormantCollectInterval) - mysqlRefreshTicker := addTicker(throttler.mysqlRefreshInterval) - mysqlAggregateTicker := addTicker(throttler.mysqlAggregateInterval) + mysqlCollectTicker := addTicker(throttler.activeCollectInterval) + mysqlDormantCollectTicker := addTicker(throttler.dormantCollectInterval) + mysqlRefreshTicker := addTicker(throttler.inventoryRefreshInterval) + mysqlAggregateTicker := addTicker(throttler.metricsAggregateInterval) throttledAppsTicker := addTicker(throttler.throttledAppsSnapshotInterval) primaryStimulatorRateLimiter := timer.NewRateLimiter(throttler.dormantPeriod) throttler.recentCheckRateLimiter = timer.NewRateLimiter(recentCheckRateLimiterInterval) diff --git a/go/vt/vttablet/tabletserver/throttle/throttler_test.go b/go/vt/vttablet/tabletserver/throttle/throttler_test.go index aba313c91cf..f2151e3b50f 100644 --- a/go/vt/vttablet/tabletserver/throttle/throttler_test.go +++ b/go/vt/vttablet/tabletserver/throttle/throttler_test.go @@ -263,10 +263,10 @@ func newTestThrottler() *Throttler { // High contention & racy intervals: throttler.leaderCheckInterval = 10 * time.Millisecond - throttler.mysqlCollectInterval = 10 * time.Millisecond - throttler.mysqlDormantCollectInterval = 10 * time.Millisecond - throttler.mysqlRefreshInterval = 10 * time.Millisecond - throttler.mysqlAggregateInterval = 10 * time.Millisecond + throttler.activeCollectInterval = 10 * time.Millisecond + throttler.dormantCollectInterval = 10 * time.Millisecond + throttler.inventoryRefreshInterval = 10 * time.Millisecond + throttler.metricsAggregateInterval = 10 * time.Millisecond throttler.throttledAppsSnapshotInterval = 10 * time.Millisecond throttler.dormantPeriod = 5 * time.Second throttler.recentCheckDormantDiff = int64(throttler.dormantPeriod / recentCheckRateLimiterInterval) From 685441e2370aec26e29289d59dfa94098ea3d870 Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Thu, 11 Jul 2024 10:08:34 +0300 Subject: [PATCH 05/20] rename aggregateMySQLProbes -> aggregateMetricResults. Cleanup tests Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- go/vt/vttablet/tabletserver/throttle/mysql.go | 2 +- .../tabletserver/throttle/mysql_test.go | 57 ++++++++----------- .../tabletserver/throttle/throttler.go | 2 +- 3 files changed, 25 insertions(+), 36 deletions(-) diff --git a/go/vt/vttablet/tabletserver/throttle/mysql.go b/go/vt/vttablet/tabletserver/throttle/mysql.go index ae0361c6018..ee24bf38b40 100644 --- a/go/vt/vttablet/tabletserver/throttle/mysql.go +++ b/go/vt/vttablet/tabletserver/throttle/mysql.go @@ -49,7 +49,7 @@ import ( "vitess.io/vitess/go/vt/vttablet/tabletserver/throttle/mysql" ) -func aggregateMySQLProbes( +func aggregateMetricResults( ctx context.Context, metricName base.MetricName, tabletResultsMap mysql.TabletResultMap, diff --git a/go/vt/vttablet/tabletserver/throttle/mysql_test.go b/go/vt/vttablet/tabletserver/throttle/mysql_test.go index 78cc1fdbdd3..8fb25f0929d 100644 --- a/go/vt/vttablet/tabletserver/throttle/mysql_test.go +++ b/go/vt/vttablet/tabletserver/throttle/mysql_test.go @@ -78,7 +78,7 @@ func noSuchMetricMap() base.MetricResultMap { return result } -func TestAggregateMySQLProbesNoErrors(t *testing.T) { +func TestAggregateMetricResultsNoErrors(t *testing.T) { ctx := context.Background() tabletResultsMap := mysql.TabletResultMap{ alias1: newMetricResultMap(1.2), @@ -87,50 +87,46 @@ func TestAggregateMySQLProbesNoErrors(t *testing.T) { alias4: newMetricResultMap(0.6), alias5: newMetricResultMap(1.1), } - var probes mysql.Probes = map[string](*mysql.Probe){} - for clusterKey := range tabletResultsMap { - probes[clusterKey] = &mysql.Probe{Alias: clusterKey} - } { - worstMetric := aggregateMySQLProbes(ctx, base.DefaultMetricName, tabletResultsMap, 0, false, 0) + worstMetric := aggregateMetricResults(ctx, base.DefaultMetricName, tabletResultsMap, 0, false, 0) value, err := worstMetric.Get() assert.NoError(t, err) assert.Equal(t, value, 1.7) } { - worstMetric := aggregateMySQLProbes(ctx, base.DefaultMetricName, tabletResultsMap, 1, false, 0) + worstMetric := aggregateMetricResults(ctx, base.DefaultMetricName, tabletResultsMap, 1, false, 0) value, err := worstMetric.Get() assert.NoError(t, err) assert.Equal(t, value, 1.2) } { - worstMetric := aggregateMySQLProbes(ctx, base.DefaultMetricName, tabletResultsMap, 2, false, 0) + worstMetric := aggregateMetricResults(ctx, base.DefaultMetricName, tabletResultsMap, 2, false, 0) value, err := worstMetric.Get() assert.NoError(t, err) assert.Equal(t, value, 1.1) } { - worstMetric := aggregateMySQLProbes(ctx, base.DefaultMetricName, tabletResultsMap, 3, false, 0) + worstMetric := aggregateMetricResults(ctx, base.DefaultMetricName, tabletResultsMap, 3, false, 0) value, err := worstMetric.Get() assert.NoError(t, err) assert.Equal(t, value, 0.6) } { - worstMetric := aggregateMySQLProbes(ctx, base.DefaultMetricName, tabletResultsMap, 4, false, 0) + worstMetric := aggregateMetricResults(ctx, base.DefaultMetricName, tabletResultsMap, 4, false, 0) value, err := worstMetric.Get() assert.NoError(t, err) assert.Equal(t, value, 0.3) } { - worstMetric := aggregateMySQLProbes(ctx, base.DefaultMetricName, tabletResultsMap, 5, false, 0) + worstMetric := aggregateMetricResults(ctx, base.DefaultMetricName, tabletResultsMap, 5, false, 0) value, err := worstMetric.Get() assert.NoError(t, err) assert.Equal(t, value, 0.3) } } -func TestAggregateMySQLProbesNoErrorsIgnoreHostsThreshold(t *testing.T) { +func TestAggregateMetricResultsNoErrorsIgnoreHostsThreshold(t *testing.T) { ctx := context.Background() tabletResultsMap := mysql.TabletResultMap{ alias1: newMetricResultMap(1.2), @@ -139,49 +135,46 @@ func TestAggregateMySQLProbesNoErrorsIgnoreHostsThreshold(t *testing.T) { alias4: newMetricResultMap(0.6), alias5: newMetricResultMap(1.1), } - var probes mysql.Probes = map[string](*mysql.Probe){} - for clusterKey := range tabletResultsMap { - probes[clusterKey] = &mysql.Probe{Alias: clusterKey} - } + { - worstMetric := aggregateMySQLProbes(ctx, base.DefaultMetricName, tabletResultsMap, 0, false, 1.0) + worstMetric := aggregateMetricResults(ctx, base.DefaultMetricName, tabletResultsMap, 0, false, 1.0) value, err := worstMetric.Get() assert.NoError(t, err) assert.Equal(t, value, 1.7) } { - worstMetric := aggregateMySQLProbes(ctx, base.DefaultMetricName, tabletResultsMap, 1, false, 1.0) + worstMetric := aggregateMetricResults(ctx, base.DefaultMetricName, tabletResultsMap, 1, false, 1.0) value, err := worstMetric.Get() assert.NoError(t, err) assert.Equal(t, value, 1.2) } { - worstMetric := aggregateMySQLProbes(ctx, base.DefaultMetricName, tabletResultsMap, 2, false, 1.0) + worstMetric := aggregateMetricResults(ctx, base.DefaultMetricName, tabletResultsMap, 2, false, 1.0) value, err := worstMetric.Get() assert.NoError(t, err) assert.Equal(t, value, 1.1) } { - worstMetric := aggregateMySQLProbes(ctx, base.DefaultMetricName, tabletResultsMap, 3, false, 1.0) + worstMetric := aggregateMetricResults(ctx, base.DefaultMetricName, tabletResultsMap, 3, false, 1.0) value, err := worstMetric.Get() assert.NoError(t, err) assert.Equal(t, value, 0.6) } { - worstMetric := aggregateMySQLProbes(ctx, base.DefaultMetricName, tabletResultsMap, 4, false, 1.0) + worstMetric := aggregateMetricResults(ctx, base.DefaultMetricName, tabletResultsMap, 4, false, 1.0) value, err := worstMetric.Get() assert.NoError(t, err) assert.Equal(t, value, 0.6) } { - worstMetric := aggregateMySQLProbes(ctx, base.DefaultMetricName, tabletResultsMap, 5, false, 1.0) + worstMetric := aggregateMetricResults(ctx, base.DefaultMetricName, tabletResultsMap, 5, false, 1.0) value, err := worstMetric.Get() assert.NoError(t, err) assert.Equal(t, value, 0.6) } } -func TestAggregateMySQLProbesWithErrors(t *testing.T) { +func TestAggregateMetricResultsWithErrors(t *testing.T) { ctx := context.Background() tabletResultsMap := mysql.TabletResultMap{ alias1: newMetricResultMap(1.2), @@ -190,31 +183,27 @@ func TestAggregateMySQLProbesWithErrors(t *testing.T) { alias4: noSuchMetricMap(), alias5: newMetricResultMap(1.1), } - var probes mysql.Probes = map[string](*mysql.Probe){} - for clusterKey := range tabletResultsMap { - probes[clusterKey] = &mysql.Probe{Alias: clusterKey} - } t.Run("nonexistent", func(t *testing.T) { - worstMetric := aggregateMySQLProbes(ctx, nonexistentMetricName, tabletResultsMap, 0, false, 0) + worstMetric := aggregateMetricResults(ctx, nonexistentMetricName, tabletResultsMap, 0, false, 0) _, err := worstMetric.Get() assert.Error(t, err) assert.Equal(t, base.ErrNoSuchMetric, err) }) t.Run("no ignore", func(t *testing.T) { - worstMetric := aggregateMySQLProbes(ctx, base.DefaultMetricName, tabletResultsMap, 0, false, 0) + worstMetric := aggregateMetricResults(ctx, base.DefaultMetricName, tabletResultsMap, 0, false, 0) _, err := worstMetric.Get() assert.Error(t, err) assert.Equal(t, base.ErrNoSuchMetric, err) }) t.Run("ignore 1", func(t *testing.T) { - worstMetric := aggregateMySQLProbes(ctx, base.DefaultMetricName, tabletResultsMap, 1, false, 0) + worstMetric := aggregateMetricResults(ctx, base.DefaultMetricName, tabletResultsMap, 1, false, 0) value, err := worstMetric.Get() assert.NoError(t, err) assert.Equal(t, 1.7, value) }) t.Run("ignore 2", func(t *testing.T) { - worstMetric := aggregateMySQLProbes(ctx, base.DefaultMetricName, tabletResultsMap, 2, false, 0) + worstMetric := aggregateMetricResults(ctx, base.DefaultMetricName, tabletResultsMap, 2, false, 0) value, err := worstMetric.Get() assert.NoError(t, err) assert.Equal(t, 1.2, value) @@ -222,19 +211,19 @@ func TestAggregateMySQLProbesWithErrors(t *testing.T) { tabletResultsMap[alias1][base.DefaultMetricName] = base.NoSuchMetric t.Run("no such metric", func(t *testing.T) { - worstMetric := aggregateMySQLProbes(ctx, base.DefaultMetricName, tabletResultsMap, 0, false, 0) + worstMetric := aggregateMetricResults(ctx, base.DefaultMetricName, tabletResultsMap, 0, false, 0) _, err := worstMetric.Get() assert.Error(t, err) assert.Equal(t, base.ErrNoSuchMetric, err) }) t.Run("no such metric, ignore 1", func(t *testing.T) { - worstMetric := aggregateMySQLProbes(ctx, base.DefaultMetricName, tabletResultsMap, 1, false, 0) + worstMetric := aggregateMetricResults(ctx, base.DefaultMetricName, tabletResultsMap, 1, false, 0) _, err := worstMetric.Get() assert.Error(t, err) assert.Equal(t, base.ErrNoSuchMetric, err) }) t.Run("metric found", func(t *testing.T) { - worstMetric := aggregateMySQLProbes(ctx, base.DefaultMetricName, tabletResultsMap, 2, false, 0) + worstMetric := aggregateMetricResults(ctx, base.DefaultMetricName, tabletResultsMap, 2, false, 0) value, err := worstMetric.Get() assert.NoError(t, err) assert.Equal(t, value, 1.7) diff --git a/go/vt/vttablet/tabletserver/throttle/throttler.go b/go/vt/vttablet/tabletserver/throttle/throttler.go index 2da4ee9475a..9a673bbfe54 100644 --- a/go/vt/vttablet/tabletserver/throttle/throttler.go +++ b/go/vt/vttablet/tabletserver/throttle/throttler.go @@ -1255,7 +1255,7 @@ func (throttler *Throttler) aggregateMySQLMetrics(ctx context.Context) error { ignoreHostsThreshold := throttler.mysqlInventory.IgnoreHostsThreshold ignoreDialTCPErrors := throttler.configSettings.MySQLStore.IgnoreDialTCPErrors - aggregatedMetric := aggregateMySQLProbes(ctx, metricName, tabletResultsMap, ignoreHostsCount, ignoreDialTCPErrors, ignoreHostsThreshold) + aggregatedMetric := aggregateMetricResults(ctx, metricName, tabletResultsMap, ignoreHostsCount, ignoreDialTCPErrors, ignoreHostsThreshold) aggregatedMetricName := metricName.AggregatedName(scope) throttler.aggregatedMetrics.Set(aggregatedMetricName, aggregatedMetric, cache.DefaultExpiration) if metricName == metricNameUsedAsDefault { From dd11de1b32542f5ee5eecd9f3dca6fe301bdc87c Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Thu, 11 Jul 2024 10:16:00 +0300 Subject: [PATCH 06/20] rename MySQLThrottleMetrics -> ThrottleMetrics. Rename mysqlThrottleMetricChan -> throttleMetricChan Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- .../throttle/mysql/mysql_throttle_metric.go | 52 ++++++------- .../tabletserver/throttle/throttler.go | 74 +++++++++---------- .../tabletserver/throttle/throttler_test.go | 16 ++-- 3 files changed, 71 insertions(+), 71 deletions(-) diff --git a/go/vt/vttablet/tabletserver/throttle/mysql/mysql_throttle_metric.go b/go/vt/vttablet/tabletserver/throttle/mysql/mysql_throttle_metric.go index 58447315a94..d4bd079572a 100644 --- a/go/vt/vttablet/tabletserver/throttle/mysql/mysql_throttle_metric.go +++ b/go/vt/vttablet/tabletserver/throttle/mysql/mysql_throttle_metric.go @@ -66,31 +66,31 @@ const ( MetricsQueryTypeUnknown ) -var mysqlMetricCache = cache.New(cache.NoExpiration, 10*time.Second) +var metricCache = cache.New(cache.NoExpiration, 10*time.Second) -func getMySQLMetricCacheKey(probe *Probe) string { +func getMetricCacheKey(probe *Probe) string { return probe.Alias } -func cacheMySQLThrottleMetric(probe *Probe, mySQLThrottleMetrics MySQLThrottleMetrics) MySQLThrottleMetrics { - for _, metric := range mySQLThrottleMetrics { +func cacheThrottleMetric(probe *Probe, throttleMetrics ThrottleMetrics) ThrottleMetrics { + for _, metric := range throttleMetrics { if metric.Err != nil { - return mySQLThrottleMetrics + return throttleMetrics } } if probe.CacheMillis > 0 { - mysqlMetricCache.Set(getMySQLMetricCacheKey(probe), mySQLThrottleMetrics, time.Duration(probe.CacheMillis)*time.Millisecond) + metricCache.Set(getMetricCacheKey(probe), throttleMetrics, time.Duration(probe.CacheMillis)*time.Millisecond) } - return mySQLThrottleMetrics + return throttleMetrics } -func getCachedMySQLThrottleMetrics(probe *Probe) MySQLThrottleMetrics { +func getCachedThrottleMetrics(probe *Probe) ThrottleMetrics { if probe.CacheMillis == 0 { return nil } - if metrics, found := mysqlMetricCache.Get(getMySQLMetricCacheKey(probe)); found { - mySQLThrottleMetrics, _ := metrics.(MySQLThrottleMetrics) - return mySQLThrottleMetrics + if metrics, found := metricCache.Get(getMetricCacheKey(probe)); found { + throttleMetrics, _ := metrics.(ThrottleMetrics) + return throttleMetrics } return nil } @@ -109,8 +109,8 @@ func GetMetricsQueryType(query string) MetricsQueryType { return MetricsQueryTypeUnknown } -// MySQLThrottleMetric has the probed metric for a tablet -type MySQLThrottleMetric struct { // nolint:revive +// ThrottleMetric has the probed metric for a tablet +type ThrottleMetric struct { // nolint:revive Name base.MetricName Scope base.Scope Alias string @@ -118,40 +118,40 @@ type MySQLThrottleMetric struct { // nolint:revive Err error } -type MySQLThrottleMetrics map[base.MetricName]*MySQLThrottleMetric // nolint:revive +type ThrottleMetrics map[base.MetricName]*ThrottleMetric // nolint:revive -// NewMySQLThrottleMetric creates a new MySQLThrottleMetric -func NewMySQLThrottleMetric() *MySQLThrottleMetric { - return &MySQLThrottleMetric{Value: 0} +// NewThrottleMetric creates a new ThrottleMetric +func NewThrottleMetric() *ThrottleMetric { + return &ThrottleMetric{Value: 0} } // GetClusterTablet returns the ClusterTablet part of the metric -func (metric *MySQLThrottleMetric) GetTabletAlias() string { +func (metric *ThrottleMetric) GetTabletAlias() string { return metric.Alias } // Get implements MetricResult -func (metric *MySQLThrottleMetric) Get() (float64, error) { +func (metric *ThrottleMetric) Get() (float64, error) { return metric.Value, metric.Err } // WithError returns this metric with given error -func (metric *MySQLThrottleMetric) WithError(err error) *MySQLThrottleMetric { +func (metric *ThrottleMetric) WithError(err error) *ThrottleMetric { metric.Err = err return metric } // ReadThrottleMetrics returns a metric for the given probe. Either by explicit query // or via SHOW REPLICA STATUS -func ReadThrottleMetrics(ctx context.Context, probe *Probe, metricsFunc func(context.Context) MySQLThrottleMetrics) MySQLThrottleMetrics { - if metrics := getCachedMySQLThrottleMetrics(probe); metrics != nil { +func ReadThrottleMetrics(ctx context.Context, probe *Probe, metricsFunc func(context.Context) ThrottleMetrics) ThrottleMetrics { + if metrics := getCachedThrottleMetrics(probe); metrics != nil { return metrics } started := time.Now() - mySQLThrottleMetrics := metricsFunc(ctx) + throttleMetrics := metricsFunc(ctx) - go func(metrics MySQLThrottleMetrics, started time.Time) { + go func(metrics ThrottleMetrics, started time.Time) { stats.GetOrNewGauge("ThrottlerProbesLatency", "probes latency").Set(time.Since(started).Nanoseconds()) stats.GetOrNewCounter("ThrottlerProbesTotal", "total probes").Add(1) for _, metric := range metrics { @@ -160,7 +160,7 @@ func ReadThrottleMetrics(ctx context.Context, probe *Probe, metricsFunc func(con break } } - }(mySQLThrottleMetrics, started) + }(throttleMetrics, started) - return cacheMySQLThrottleMetric(probe, mySQLThrottleMetrics) + return cacheThrottleMetric(probe, throttleMetrics) } diff --git a/go/vt/vttablet/tabletserver/throttle/throttler.go b/go/vt/vttablet/tabletserver/throttle/throttler.go index 9a673bbfe54..ab19e119aa9 100644 --- a/go/vt/vttablet/tabletserver/throttle/throttler.go +++ b/go/vt/vttablet/tabletserver/throttle/throttler.go @@ -180,10 +180,10 @@ type Throttler struct { throttleTabletTypesMap map[topodatapb.TabletType]bool - mysqlThrottleMetricChan chan *mysql.MySQLThrottleMetric - mysqlClusterProbesChan chan *mysql.ClusterProbes - throttlerConfigChan chan *topodatapb.ThrottlerConfig - serialFuncChan chan func() // Used by unit tests to inject non-racy behavior + throttleMetricChan chan *mysql.ThrottleMetric + mysqlClusterProbesChan chan *mysql.ClusterProbes + throttlerConfigChan chan *topodatapb.ThrottlerConfig + serialFuncChan chan func() // Used by unit tests to inject non-racy behavior mysqlInventory *mysql.Inventory @@ -205,7 +205,7 @@ type Throttler struct { cancelEnableContext context.CancelFunc throttledAppsMutex sync.Mutex - readSelfThrottleMetrics func(context.Context) mysql.MySQLThrottleMetrics // overwritten by unit test + readSelfThrottleMetrics func(context.Context) mysql.ThrottleMetrics // overwritten by unit test httpClient *http.Client @@ -251,7 +251,7 @@ func NewThrottler(env tabletenv.Env, srvTopoServer srvtopo.Server, ts *topo.Serv }), } - throttler.mysqlThrottleMetricChan = make(chan *mysql.MySQLThrottleMetric) + throttler.throttleMetricChan = make(chan *mysql.ThrottleMetric) throttler.mysqlClusterProbesChan = make(chan *mysql.ClusterProbes) throttler.throttlerConfigChan = make(chan *topodatapb.ThrottlerConfig) throttler.serialFuncChan = make(chan func()) @@ -282,7 +282,7 @@ func NewThrottler(env tabletenv.Env, srvTopoServer srvtopo.Server, ts *topo.Serv } throttler.StoreMetricsThreshold(defaultThresholds[base.LagMetricName]) - throttler.readSelfThrottleMetrics = func(ctx context.Context) mysql.MySQLThrottleMetrics { + throttler.readSelfThrottleMetrics = func(ctx context.Context) mysql.ThrottleMetrics { return throttler.readSelfThrottleMetricsInternal(ctx) } @@ -727,8 +727,8 @@ func (throttler *Throttler) stimulatePrimaryThrottler(ctx context.Context, tmCli return nil } -func (throttler *Throttler) readSelfLoadAvgPerCore(ctx context.Context) *mysql.MySQLThrottleMetric { - metric := &mysql.MySQLThrottleMetric{ +func (throttler *Throttler) readSelfLoadAvgPerCore(ctx context.Context) *mysql.ThrottleMetric { + metric := &mysql.ThrottleMetric{ Scope: base.SelfScope, Alias: throttler.tabletAlias, } @@ -779,9 +779,9 @@ func (throttler *Throttler) readSelfLoadAvgPerCore(ctx context.Context) *mysql.M return metric } -// readSelfMySQLThrottleMetric reads the mysql metric from thi very tablet's backend mysql. -func (throttler *Throttler) readSelfMySQLThrottleMetric(ctx context.Context, query string) *mysql.MySQLThrottleMetric { - metric := &mysql.MySQLThrottleMetric{ +// readSelfThrottleMetric reads the mysql metric from thi very tablet's backend mysql. +func (throttler *Throttler) readSelfThrottleMetric(ctx context.Context, query string) *mysql.ThrottleMetric { + metric := &mysql.ThrottleMetric{ Scope: base.SelfScope, Alias: throttler.tabletAlias, } @@ -800,7 +800,7 @@ func (throttler *Throttler) readSelfMySQLThrottleMetric(ctx context.Context, que } row := tm.Named().Row() if row == nil { - return metric.WithError(fmt.Errorf("no results for readSelfMySQLThrottleMetric")) + return metric.WithError(fmt.Errorf("no results for readSelfThrottleMetric")) } metricsQueryType := mysql.GetMetricsQueryType(query) @@ -963,7 +963,7 @@ func (throttler *Throttler) Operate(ctx context.Context, wg *sync.WaitGroup) { throttler.collectShardMySQLMetrics(ctx, tmClient) } } - case metric := <-throttler.mysqlThrottleMetricChan: + case metric := <-throttler.throttleMetricChan: // incoming MySQL metric, frequent, as result of collectMySQLMetrics() metricResultsMap, ok := throttler.mysqlInventory.TabletMetrics[metric.GetTabletAlias()] if !ok { @@ -997,11 +997,11 @@ func (throttler *Throttler) Operate(ctx context.Context, wg *sync.WaitGroup) { }() } -func (throttler *Throttler) generateTabletProbeFunction(scope base.Scope, tmClient tmclient.TabletManagerClient, probe *mysql.Probe) (probeFunc func(context.Context) mysql.MySQLThrottleMetrics) { - metricsWithError := func(err error) mysql.MySQLThrottleMetrics { - metrics := mysql.MySQLThrottleMetrics{} +func (throttler *Throttler) generateTabletProbeFunction(scope base.Scope, tmClient tmclient.TabletManagerClient, probe *mysql.Probe) (probeFunc func(context.Context) mysql.ThrottleMetrics) { + metricsWithError := func(err error) mysql.ThrottleMetrics { + metrics := mysql.ThrottleMetrics{} for _, metricName := range base.KnownMetricNames { - metrics[metricName] = &mysql.MySQLThrottleMetric{ + metrics[metricName] = &mysql.ThrottleMetric{ Name: metricName, Scope: scope, Alias: probe.Alias, @@ -1010,30 +1010,30 @@ func (throttler *Throttler) generateTabletProbeFunction(scope base.Scope, tmClie } return metrics } - return func(ctx context.Context) mysql.MySQLThrottleMetrics { + return func(ctx context.Context) mysql.ThrottleMetrics { // Some reasonable timeout, to ensure we release connections even if they're hanging (otherwise grpc-go keeps polling those connections forever) ctx, cancel := context.WithTimeout(ctx, 4*activeCollectInterval) defer cancel() - // Hit a tablet's `check-self` via HTTP, and convert its CheckResult JSON output into a MySQLThrottleMetric - mySQLThrottleMetric := mysql.NewMySQLThrottleMetric() - mySQLThrottleMetric.Name = base.DefaultMetricName - mySQLThrottleMetric.Scope = scope - mySQLThrottleMetric.Alias = probe.Alias + // Hit a tablet's `check-self` via HTTP, and convert its CheckResult JSON output into a ThrottleMetric + throttleMetric := mysql.NewThrottleMetric() + throttleMetric.Name = base.DefaultMetricName + throttleMetric.Scope = scope + throttleMetric.Alias = probe.Alias if probe.Tablet == nil { return metricsWithError(fmt.Errorf("found nil tablet reference for alias '%v'", probe.Alias)) } - metrics := make(mysql.MySQLThrottleMetrics) + metrics := make(mysql.ThrottleMetrics) req := &tabletmanagerdatapb.CheckThrottlerRequest{MultiMetricsEnabled: true} // We leave AppName empty; it will default to VitessName anyway, and we can save some proto space resp, gRPCErr := tmClient.CheckThrottler(ctx, probe.Tablet, req) if gRPCErr != nil { return metricsWithError(fmt.Errorf("gRPC error accessing tablet %v. Err=%v", probe.Alias, gRPCErr)) } - mySQLThrottleMetric.Value = resp.Value + throttleMetric.Value = resp.Value if resp.StatusCode == http.StatusInternalServerError { - mySQLThrottleMetric.Err = fmt.Errorf("Status code: %d", resp.StatusCode) + throttleMetric.Err = fmt.Errorf("Status code: %d", resp.StatusCode) } if resp.RecentlyChecked { // We have just probed a tablet, and it reported back that someone just recently "check"ed it. @@ -1043,7 +1043,7 @@ func (throttler *Throttler) generateTabletProbeFunction(scope base.Scope, tmClie } for name, metric := range resp.Metrics { metricName := base.MetricName(name) - metrics[metricName] = &mysql.MySQLThrottleMetric{ + metrics[metricName] = &mysql.ThrottleMetric{ Name: metricName, Scope: scope, Alias: probe.Alias, @@ -1055,28 +1055,28 @@ func (throttler *Throttler) generateTabletProbeFunction(scope base.Scope, tmClie } if len(resp.Metrics) == 0 { // Backwards compatibility to v20. v20 does not report multi metrics. - mySQLThrottleMetric.Name = throttler.metricNameUsedAsDefault() - metrics[mySQLThrottleMetric.Name] = mySQLThrottleMetric + throttleMetric.Name = throttler.metricNameUsedAsDefault() + metrics[throttleMetric.Name] = throttleMetric } return metrics } } -func (throttler *Throttler) readSelfThrottleMetricsInternal(ctx context.Context) mysql.MySQLThrottleMetrics { +func (throttler *Throttler) readSelfThrottleMetricsInternal(ctx context.Context) mysql.ThrottleMetrics { - writeMetric := func(metricName base.MetricName, metric *mysql.MySQLThrottleMetric) { + writeMetric := func(metricName base.MetricName, metric *mysql.ThrottleMetric) { metric.Name = metricName select { case <-ctx.Done(): return - case throttler.mysqlThrottleMetricChan <- metric: + case throttler.throttleMetricChan <- metric: } } - go writeMetric(base.LagMetricName, throttler.readSelfMySQLThrottleMetric(ctx, sqlparser.BuildParsedQuery(defaultReplicationLagQuery, sidecar.GetIdentifier()).Query)) - go writeMetric(base.ThreadsRunningMetricName, throttler.readSelfMySQLThrottleMetric(ctx, threadsRunningQuery)) - go writeMetric(base.CustomMetricName, throttler.readSelfMySQLThrottleMetric(ctx, throttler.GetCustomMetricsQuery())) + go writeMetric(base.LagMetricName, throttler.readSelfThrottleMetric(ctx, sqlparser.BuildParsedQuery(defaultReplicationLagQuery, sidecar.GetIdentifier()).Query)) + go writeMetric(base.ThreadsRunningMetricName, throttler.readSelfThrottleMetric(ctx, threadsRunningQuery)) + go writeMetric(base.CustomMetricName, throttler.readSelfThrottleMetric(ctx, throttler.GetCustomMetricsQuery())) go writeMetric(base.LoadAvgMetricName, throttler.readSelfLoadAvgPerCore(ctx)) return nil } @@ -1124,7 +1124,7 @@ func (throttler *Throttler) collectShardMySQLMetrics(ctx context.Context, tmClie select { case <-ctx.Done(): return - case throttler.mysqlThrottleMetricChan <- metric: + case throttler.throttleMetricChan <- metric: } } }(probe) diff --git a/go/vt/vttablet/tabletserver/throttle/throttler_test.go b/go/vt/vttablet/tabletserver/throttle/throttler_test.go index f2151e3b50f..367bc9761ac 100644 --- a/go/vt/vttablet/tabletserver/throttle/throttler_test.go +++ b/go/vt/vttablet/tabletserver/throttle/throttler_test.go @@ -47,26 +47,26 @@ import ( ) var ( - selfMetrics = mysql.MySQLThrottleMetrics{ - base.LagMetricName: &mysql.MySQLThrottleMetric{ + selfMetrics = mysql.ThrottleMetrics{ + base.LagMetricName: &mysql.ThrottleMetric{ Scope: base.SelfScope, Alias: "", Value: 0.3, Err: nil, }, - base.ThreadsRunningMetricName: &mysql.MySQLThrottleMetric{ + base.ThreadsRunningMetricName: &mysql.ThrottleMetric{ Scope: base.SelfScope, Alias: "", Value: 26, Err: nil, }, - base.CustomMetricName: &mysql.MySQLThrottleMetric{ + base.CustomMetricName: &mysql.ThrottleMetric{ Scope: base.SelfScope, Alias: "", Value: 17, Err: nil, }, - base.LoadAvgMetricName: &mysql.MySQLThrottleMetric{ + base.LoadAvgMetricName: &mysql.ThrottleMetric{ Scope: base.SelfScope, Alias: "", Value: 2.718, @@ -246,7 +246,7 @@ func newTestThrottler() *Throttler { throttler.MetricsThreshold.Store(math.Float64bits(0.75)) throttler.configSettings = config.NewConfigurationSettings() throttler.initConfig() - throttler.mysqlThrottleMetricChan = make(chan *mysql.MySQLThrottleMetric) + throttler.throttleMetricChan = make(chan *mysql.ThrottleMetric) throttler.mysqlClusterProbesChan = make(chan *mysql.ClusterProbes) throttler.throttlerConfigChan = make(chan *topodatapb.ThrottlerConfig) throttler.serialFuncChan = make(chan func()) @@ -272,12 +272,12 @@ func newTestThrottler() *Throttler { throttler.recentCheckDormantDiff = int64(throttler.dormantPeriod / recentCheckRateLimiterInterval) throttler.recentCheckDiff = int64(3 * time.Second / recentCheckRateLimiterInterval) - throttler.readSelfThrottleMetrics = func(ctx context.Context) mysql.MySQLThrottleMetrics { + throttler.readSelfThrottleMetrics = func(ctx context.Context) mysql.ThrottleMetrics { for _, metric := range selfMetrics { go func() { select { case <-ctx.Done(): - case throttler.mysqlThrottleMetricChan <- metric: + case throttler.throttleMetricChan <- metric: } }() } From c9ac150a9d74f46c191d625149aa803b7b880687 Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Thu, 11 Jul 2024 10:18:59 +0300 Subject: [PATCH 07/20] renamed files Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- .../throttle/mysql/{mysql_inventory.go => inventory.go} | 0 .../throttle/mysql/{mysql_inventory_test.go => inventory_test.go} | 0 .../mysql/{mysql_throttle_metric.go => throttle_metric.go} | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename go/vt/vttablet/tabletserver/throttle/mysql/{mysql_inventory.go => inventory.go} (100%) rename go/vt/vttablet/tabletserver/throttle/mysql/{mysql_inventory_test.go => inventory_test.go} (100%) rename go/vt/vttablet/tabletserver/throttle/mysql/{mysql_throttle_metric.go => throttle_metric.go} (100%) diff --git a/go/vt/vttablet/tabletserver/throttle/mysql/mysql_inventory.go b/go/vt/vttablet/tabletserver/throttle/mysql/inventory.go similarity index 100% rename from go/vt/vttablet/tabletserver/throttle/mysql/mysql_inventory.go rename to go/vt/vttablet/tabletserver/throttle/mysql/inventory.go diff --git a/go/vt/vttablet/tabletserver/throttle/mysql/mysql_inventory_test.go b/go/vt/vttablet/tabletserver/throttle/mysql/inventory_test.go similarity index 100% rename from go/vt/vttablet/tabletserver/throttle/mysql/mysql_inventory_test.go rename to go/vt/vttablet/tabletserver/throttle/mysql/inventory_test.go diff --git a/go/vt/vttablet/tabletserver/throttle/mysql/mysql_throttle_metric.go b/go/vt/vttablet/tabletserver/throttle/mysql/throttle_metric.go similarity index 100% rename from go/vt/vttablet/tabletserver/throttle/mysql/mysql_throttle_metric.go rename to go/vt/vttablet/tabletserver/throttle/mysql/throttle_metric.go From dd3868f3feb9eef2a827b9893b72330d99c0e0af Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Thu, 11 Jul 2024 11:02:55 +0300 Subject: [PATCH 08/20] rename file Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- .../mysql/{throttle_metric.go => throttle_metric_cache.go} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename go/vt/vttablet/tabletserver/throttle/mysql/{throttle_metric.go => throttle_metric_cache.go} (100%) diff --git a/go/vt/vttablet/tabletserver/throttle/mysql/throttle_metric.go b/go/vt/vttablet/tabletserver/throttle/mysql/throttle_metric_cache.go similarity index 100% rename from go/vt/vttablet/tabletserver/throttle/mysql/throttle_metric.go rename to go/vt/vttablet/tabletserver/throttle/mysql/throttle_metric_cache.go From 2886bf3a83ddf5ab0c8deb535d01ab8709ac19bc Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Thu, 11 Jul 2024 11:16:21 +0300 Subject: [PATCH 09/20] eliminatye throttle/mysql package; move everything under throttle/base Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- .../throttle/{mysql => base}/inventory.go | 8 +-- .../{mysql => base}/inventory_test.go | 10 ++- .../throttle/{mysql => base}/probe.go | 2 +- .../throttle/{mysql => base}/probe_test.go | 2 +- .../{mysql => base}/throttle_metric_cache.go | 9 ++- go/vt/vttablet/tabletserver/throttle/mysql.go | 3 +- .../tabletserver/throttle/mysql_test.go | 7 +- .../tabletserver/throttle/throttler.go | 71 +++++++++---------- .../tabletserver/throttle/throttler_test.go | 29 ++++---- 9 files changed, 65 insertions(+), 76 deletions(-) rename go/vt/vttablet/tabletserver/throttle/{mysql => base}/inventory.go (94%) rename go/vt/vttablet/tabletserver/throttle/{mysql => base}/inventory_test.go (86%) rename go/vt/vttablet/tabletserver/throttle/{mysql => base}/probe.go (99%) rename go/vt/vttablet/tabletserver/throttle/{mysql => base}/probe_test.go (99%) rename go/vt/vttablet/tabletserver/throttle/{mysql => base}/throttle_metric_cache.go (96%) diff --git a/go/vt/vttablet/tabletserver/throttle/mysql/inventory.go b/go/vt/vttablet/tabletserver/throttle/base/inventory.go similarity index 94% rename from go/vt/vttablet/tabletserver/throttle/mysql/inventory.go rename to go/vt/vttablet/tabletserver/throttle/base/inventory.go index f8ae0e26f11..d4776bf19b2 100644 --- a/go/vt/vttablet/tabletserver/throttle/mysql/inventory.go +++ b/go/vt/vttablet/tabletserver/throttle/base/inventory.go @@ -39,14 +39,10 @@ limitations under the License. SOFTWARE. */ -package mysql - -import ( - "vitess.io/vitess/go/vt/vttablet/tabletserver/throttle/base" -) +package base // TabletResultMap maps a tablet to a result -type TabletResultMap map[string]base.MetricResultMap +type TabletResultMap map[string]MetricResultMap func (m TabletResultMap) Split(alias string) (withAlias TabletResultMap, all TabletResultMap) { withAlias = make(TabletResultMap) diff --git a/go/vt/vttablet/tabletserver/throttle/mysql/inventory_test.go b/go/vt/vttablet/tabletserver/throttle/base/inventory_test.go similarity index 86% rename from go/vt/vttablet/tabletserver/throttle/mysql/inventory_test.go rename to go/vt/vttablet/tabletserver/throttle/base/inventory_test.go index fe6204a36c2..2850a3b3035 100644 --- a/go/vt/vttablet/tabletserver/throttle/mysql/inventory_test.go +++ b/go/vt/vttablet/tabletserver/throttle/base/inventory_test.go @@ -14,22 +14,20 @@ See the License for the specific language governing permissions and limitations under the License. */ -package mysql +package base import ( "testing" "github.com/stretchr/testify/assert" "golang.org/x/exp/maps" - - "vitess.io/vitess/go/vt/vttablet/tabletserver/throttle/base" ) func TestTabletResultMapSplit(t *testing.T) { tabletResultMap := TabletResultMap{ - "a": make(base.MetricResultMap), - "b": make(base.MetricResultMap), - "c": make(base.MetricResultMap), + "a": make(MetricResultMap), + "b": make(MetricResultMap), + "c": make(MetricResultMap), } { withAlias, all := tabletResultMap.Split("b") diff --git a/go/vt/vttablet/tabletserver/throttle/mysql/probe.go b/go/vt/vttablet/tabletserver/throttle/base/probe.go similarity index 99% rename from go/vt/vttablet/tabletserver/throttle/mysql/probe.go rename to go/vt/vttablet/tabletserver/throttle/base/probe.go index af0d660096e..0fe813d571e 100644 --- a/go/vt/vttablet/tabletserver/throttle/mysql/probe.go +++ b/go/vt/vttablet/tabletserver/throttle/base/probe.go @@ -39,7 +39,7 @@ limitations under the License. SOFTWARE. */ -package mysql +package base import ( "fmt" diff --git a/go/vt/vttablet/tabletserver/throttle/mysql/probe_test.go b/go/vt/vttablet/tabletserver/throttle/base/probe_test.go similarity index 99% rename from go/vt/vttablet/tabletserver/throttle/mysql/probe_test.go rename to go/vt/vttablet/tabletserver/throttle/base/probe_test.go index 8f489f39258..af1b09ec181 100644 --- a/go/vt/vttablet/tabletserver/throttle/mysql/probe_test.go +++ b/go/vt/vttablet/tabletserver/throttle/base/probe_test.go @@ -39,7 +39,7 @@ limitations under the License. SOFTWARE. */ -package mysql +package base import ( "testing" diff --git a/go/vt/vttablet/tabletserver/throttle/mysql/throttle_metric_cache.go b/go/vt/vttablet/tabletserver/throttle/base/throttle_metric_cache.go similarity index 96% rename from go/vt/vttablet/tabletserver/throttle/mysql/throttle_metric_cache.go rename to go/vt/vttablet/tabletserver/throttle/base/throttle_metric_cache.go index d4bd079572a..8695cb83229 100644 --- a/go/vt/vttablet/tabletserver/throttle/mysql/throttle_metric_cache.go +++ b/go/vt/vttablet/tabletserver/throttle/base/throttle_metric_cache.go @@ -39,7 +39,7 @@ limitations under the License. SOFTWARE. */ -package mysql +package base import ( "context" @@ -49,7 +49,6 @@ import ( "github.com/patrickmn/go-cache" "vitess.io/vitess/go/stats" - "vitess.io/vitess/go/vt/vttablet/tabletserver/throttle/base" ) // MetricsQueryType indicates the type of metrics query on MySQL backend. See following. @@ -111,14 +110,14 @@ func GetMetricsQueryType(query string) MetricsQueryType { // ThrottleMetric has the probed metric for a tablet type ThrottleMetric struct { // nolint:revive - Name base.MetricName - Scope base.Scope + Name MetricName + Scope Scope Alias string Value float64 Err error } -type ThrottleMetrics map[base.MetricName]*ThrottleMetric // nolint:revive +type ThrottleMetrics map[MetricName]*ThrottleMetric // nolint:revive // NewThrottleMetric creates a new ThrottleMetric func NewThrottleMetric() *ThrottleMetric { diff --git a/go/vt/vttablet/tabletserver/throttle/mysql.go b/go/vt/vttablet/tabletserver/throttle/mysql.go index ee24bf38b40..c952c644638 100644 --- a/go/vt/vttablet/tabletserver/throttle/mysql.go +++ b/go/vt/vttablet/tabletserver/throttle/mysql.go @@ -46,13 +46,12 @@ import ( "sort" "vitess.io/vitess/go/vt/vttablet/tabletserver/throttle/base" - "vitess.io/vitess/go/vt/vttablet/tabletserver/throttle/mysql" ) func aggregateMetricResults( ctx context.Context, metricName base.MetricName, - tabletResultsMap mysql.TabletResultMap, + tabletResultsMap base.TabletResultMap, ignoreHostsCount int, IgnoreDialTCPErrors bool, ignoreHostsThreshold float64, diff --git a/go/vt/vttablet/tabletserver/throttle/mysql_test.go b/go/vt/vttablet/tabletserver/throttle/mysql_test.go index 8fb25f0929d..ade8a6e6e0f 100644 --- a/go/vt/vttablet/tabletserver/throttle/mysql_test.go +++ b/go/vt/vttablet/tabletserver/throttle/mysql_test.go @@ -46,7 +46,6 @@ import ( "testing" "vitess.io/vitess/go/vt/vttablet/tabletserver/throttle/base" - "vitess.io/vitess/go/vt/vttablet/tabletserver/throttle/mysql" "github.com/stretchr/testify/assert" ) @@ -80,7 +79,7 @@ func noSuchMetricMap() base.MetricResultMap { func TestAggregateMetricResultsNoErrors(t *testing.T) { ctx := context.Background() - tabletResultsMap := mysql.TabletResultMap{ + tabletResultsMap := base.TabletResultMap{ alias1: newMetricResultMap(1.2), alias2: newMetricResultMap(1.7), alias3: newMetricResultMap(0.3), @@ -128,7 +127,7 @@ func TestAggregateMetricResultsNoErrors(t *testing.T) { func TestAggregateMetricResultsNoErrorsIgnoreHostsThreshold(t *testing.T) { ctx := context.Background() - tabletResultsMap := mysql.TabletResultMap{ + tabletResultsMap := base.TabletResultMap{ alias1: newMetricResultMap(1.2), alias2: newMetricResultMap(1.7), alias3: newMetricResultMap(0.3), @@ -176,7 +175,7 @@ func TestAggregateMetricResultsNoErrorsIgnoreHostsThreshold(t *testing.T) { func TestAggregateMetricResultsWithErrors(t *testing.T) { ctx := context.Background() - tabletResultsMap := mysql.TabletResultMap{ + tabletResultsMap := base.TabletResultMap{ alias1: newMetricResultMap(1.2), alias2: newMetricResultMap(1.7), alias3: newMetricResultMap(0.3), diff --git a/go/vt/vttablet/tabletserver/throttle/throttler.go b/go/vt/vttablet/tabletserver/throttle/throttler.go index ab19e119aa9..6055d0fa487 100644 --- a/go/vt/vttablet/tabletserver/throttle/throttler.go +++ b/go/vt/vttablet/tabletserver/throttle/throttler.go @@ -78,7 +78,6 @@ import ( "vitess.io/vitess/go/vt/vttablet/tabletserver/tabletenv" "vitess.io/vitess/go/vt/vttablet/tabletserver/throttle/base" "vitess.io/vitess/go/vt/vttablet/tabletserver/throttle/config" - "vitess.io/vitess/go/vt/vttablet/tabletserver/throttle/mysql" "vitess.io/vitess/go/vt/vttablet/tabletserver/throttle/throttlerapp" "vitess.io/vitess/go/vt/vttablet/tmclient" ) @@ -180,12 +179,12 @@ type Throttler struct { throttleTabletTypesMap map[topodatapb.TabletType]bool - throttleMetricChan chan *mysql.ThrottleMetric - mysqlClusterProbesChan chan *mysql.ClusterProbes + throttleMetricChan chan *base.ThrottleMetric + mysqlClusterProbesChan chan *base.ClusterProbes throttlerConfigChan chan *topodatapb.ThrottlerConfig serialFuncChan chan func() // Used by unit tests to inject non-racy behavior - mysqlInventory *mysql.Inventory + mysqlInventory *base.Inventory metricsQuery atomic.Value customMetricsQuery atomic.Value @@ -205,7 +204,7 @@ type Throttler struct { cancelEnableContext context.CancelFunc throttledAppsMutex sync.Mutex - readSelfThrottleMetrics func(context.Context) mysql.ThrottleMetrics // overwritten by unit test + readSelfThrottleMetrics func(context.Context) base.ThrottleMetrics // overwritten by unit test httpClient *http.Client @@ -251,11 +250,11 @@ func NewThrottler(env tabletenv.Env, srvTopoServer srvtopo.Server, ts *topo.Serv }), } - throttler.throttleMetricChan = make(chan *mysql.ThrottleMetric) - throttler.mysqlClusterProbesChan = make(chan *mysql.ClusterProbes) + throttler.throttleMetricChan = make(chan *base.ThrottleMetric) + throttler.mysqlClusterProbesChan = make(chan *base.ClusterProbes) throttler.throttlerConfigChan = make(chan *topodatapb.ThrottlerConfig) throttler.serialFuncChan = make(chan func()) - throttler.mysqlInventory = mysql.NewInventory() + throttler.mysqlInventory = base.NewInventory() throttler.throttledApps = cache.New(cache.NoExpiration, 0) throttler.metricThresholds = cache.New(cache.NoExpiration, 0) @@ -282,7 +281,7 @@ func NewThrottler(env tabletenv.Env, srvTopoServer srvtopo.Server, ts *topo.Serv } throttler.StoreMetricsThreshold(defaultThresholds[base.LagMetricName]) - throttler.readSelfThrottleMetrics = func(ctx context.Context) mysql.ThrottleMetrics { + throttler.readSelfThrottleMetrics = func(ctx context.Context) base.ThrottleMetrics { return throttler.readSelfThrottleMetricsInternal(ctx) } @@ -727,8 +726,8 @@ func (throttler *Throttler) stimulatePrimaryThrottler(ctx context.Context, tmCli return nil } -func (throttler *Throttler) readSelfLoadAvgPerCore(ctx context.Context) *mysql.ThrottleMetric { - metric := &mysql.ThrottleMetric{ +func (throttler *Throttler) readSelfLoadAvgPerCore(ctx context.Context) *base.ThrottleMetric { + metric := &base.ThrottleMetric{ Scope: base.SelfScope, Alias: throttler.tabletAlias, } @@ -780,8 +779,8 @@ func (throttler *Throttler) readSelfLoadAvgPerCore(ctx context.Context) *mysql.T } // readSelfThrottleMetric reads the mysql metric from thi very tablet's backend mysql. -func (throttler *Throttler) readSelfThrottleMetric(ctx context.Context, query string) *mysql.ThrottleMetric { - metric := &mysql.ThrottleMetric{ +func (throttler *Throttler) readSelfThrottleMetric(ctx context.Context, query string) *base.ThrottleMetric { + metric := &base.ThrottleMetric{ Scope: base.SelfScope, Alias: throttler.tabletAlias, } @@ -803,15 +802,15 @@ func (throttler *Throttler) readSelfThrottleMetric(ctx context.Context, query st return metric.WithError(fmt.Errorf("no results for readSelfThrottleMetric")) } - metricsQueryType := mysql.GetMetricsQueryType(query) + metricsQueryType := base.GetMetricsQueryType(query) switch metricsQueryType { - case mysql.MetricsQueryTypeSelect: + case base.MetricsQueryTypeSelect: // We expect a single row, single column result. // The "for" iteration below is just a way to get first result without knowing column name for k := range row { metric.Value, metric.Err = row.ToFloat64(k) } - case mysql.MetricsQueryTypeShowGlobal: + case base.MetricsQueryTypeShowGlobal: metric.Value, metric.Err = strconv.ParseFloat(row["Value"].ToString(), 64) default: metric.Err = fmt.Errorf("Unsupported metrics query type for query: %s", throttler.GetMetricsQuery()) @@ -997,11 +996,11 @@ func (throttler *Throttler) Operate(ctx context.Context, wg *sync.WaitGroup) { }() } -func (throttler *Throttler) generateTabletProbeFunction(scope base.Scope, tmClient tmclient.TabletManagerClient, probe *mysql.Probe) (probeFunc func(context.Context) mysql.ThrottleMetrics) { - metricsWithError := func(err error) mysql.ThrottleMetrics { - metrics := mysql.ThrottleMetrics{} +func (throttler *Throttler) generateTabletProbeFunction(scope base.Scope, tmClient tmclient.TabletManagerClient, probe *base.Probe) (probeFunc func(context.Context) base.ThrottleMetrics) { + metricsWithError := func(err error) base.ThrottleMetrics { + metrics := base.ThrottleMetrics{} for _, metricName := range base.KnownMetricNames { - metrics[metricName] = &mysql.ThrottleMetric{ + metrics[metricName] = &base.ThrottleMetric{ Name: metricName, Scope: scope, Alias: probe.Alias, @@ -1010,13 +1009,13 @@ func (throttler *Throttler) generateTabletProbeFunction(scope base.Scope, tmClie } return metrics } - return func(ctx context.Context) mysql.ThrottleMetrics { + return func(ctx context.Context) base.ThrottleMetrics { // Some reasonable timeout, to ensure we release connections even if they're hanging (otherwise grpc-go keeps polling those connections forever) ctx, cancel := context.WithTimeout(ctx, 4*activeCollectInterval) defer cancel() // Hit a tablet's `check-self` via HTTP, and convert its CheckResult JSON output into a ThrottleMetric - throttleMetric := mysql.NewThrottleMetric() + throttleMetric := base.NewThrottleMetric() throttleMetric.Name = base.DefaultMetricName throttleMetric.Scope = scope throttleMetric.Alias = probe.Alias @@ -1024,7 +1023,7 @@ func (throttler *Throttler) generateTabletProbeFunction(scope base.Scope, tmClie if probe.Tablet == nil { return metricsWithError(fmt.Errorf("found nil tablet reference for alias '%v'", probe.Alias)) } - metrics := make(mysql.ThrottleMetrics) + metrics := make(base.ThrottleMetrics) req := &tabletmanagerdatapb.CheckThrottlerRequest{MultiMetricsEnabled: true} // We leave AppName empty; it will default to VitessName anyway, and we can save some proto space resp, gRPCErr := tmClient.CheckThrottler(ctx, probe.Tablet, req) @@ -1043,7 +1042,7 @@ func (throttler *Throttler) generateTabletProbeFunction(scope base.Scope, tmClie } for name, metric := range resp.Metrics { metricName := base.MetricName(name) - metrics[metricName] = &mysql.ThrottleMetric{ + metrics[metricName] = &base.ThrottleMetric{ Name: metricName, Scope: scope, Alias: probe.Alias, @@ -1063,9 +1062,9 @@ func (throttler *Throttler) generateTabletProbeFunction(scope base.Scope, tmClie } } -func (throttler *Throttler) readSelfThrottleMetricsInternal(ctx context.Context) mysql.ThrottleMetrics { +func (throttler *Throttler) readSelfThrottleMetricsInternal(ctx context.Context) base.ThrottleMetrics { - writeMetric := func(metricName base.MetricName, metric *mysql.ThrottleMetric) { + writeMetric := func(metricName base.MetricName, metric *base.ThrottleMetric) { metric.Name = metricName select { case <-ctx.Done(): @@ -1096,7 +1095,7 @@ func (throttler *Throttler) collectSelfMySQLMetrics(ctx context.Context, tmClien defer atomic.StoreInt64(&probe.QueryInProgress, 0) // Throttler is probing its own tablet's metrics: - _ = mysql.ReadThrottleMetrics(ctx, probe, throttler.readSelfThrottleMetrics) + _ = base.ReadThrottleMetrics(ctx, probe, throttler.readSelfThrottleMetrics) }() } @@ -1108,7 +1107,7 @@ func (throttler *Throttler) collectShardMySQLMetrics(ctx context.Context, tmClie // We skip collecting our own metrics continue } - go func(probe *mysql.Probe) { + go func(probe *base.Probe) { // Avoid querying the same server twice at the same time. If previous read is still there, // we avoid re-reading it. if !atomic.CompareAndSwapInt64(&probe.QueryInProgress, 0, 1) { @@ -1119,7 +1118,7 @@ func (throttler *Throttler) collectShardMySQLMetrics(ctx context.Context, tmClie // Throttler probing other tablets: throttleMetricFunc := throttler.generateTabletProbeFunction(base.ShardScope, tmClient, probe) - throttleMetrics := mysql.ReadThrottleMetrics(ctx, probe, throttleMetricFunc) + throttleMetrics := base.ReadThrottleMetrics(ctx, probe, throttleMetricFunc) for _, metric := range throttleMetrics { select { case <-ctx.Done(): @@ -1134,7 +1133,7 @@ func (throttler *Throttler) collectShardMySQLMetrics(ctx context.Context, tmClie // refreshMySQLInventory will re-structure the inventory based on reading config settings func (throttler *Throttler) refreshMySQLInventory(ctx context.Context) error { // distribute the query/threshold from the throttler down to the cluster settings and from there to the probes - addProbe := func(alias string, tablet *topodatapb.Tablet, scope base.Scope, mysqlSettings *config.MySQLConfigurationSettings, probes mysql.Probes) bool { + addProbe := func(alias string, tablet *topodatapb.Tablet, scope base.Scope, mysqlSettings *config.MySQLConfigurationSettings, probes base.Probes) bool { for _, ignore := range mysqlSettings.IgnoreHosts { if strings.Contains(alias, ignore) { log.Infof("Throttler: tablet ignored: %+v", alias) @@ -1152,7 +1151,7 @@ func (throttler *Throttler) refreshMySQLInventory(ctx context.Context) error { } } - probe := &mysql.Probe{ + probe := &base.Probe{ Alias: alias, Tablet: tablet, CacheMillis: mysqlSettings.CacheMillis, @@ -1161,7 +1160,7 @@ func (throttler *Throttler) refreshMySQLInventory(ctx context.Context) error { return true } - attemptWriteProbes := func(clusterProbes *mysql.ClusterProbes) error { + attemptWriteProbes := func(clusterProbes *base.ClusterProbes) error { select { case <-ctx.Done(): return ctx.Err() @@ -1188,9 +1187,9 @@ func (throttler *Throttler) refreshMySQLInventory(ctx context.Context) error { // config may dynamically change, but internal structure (config.Settings().MySQLStore.Clusters in our case) // is immutable and can only be _replaced_. Hence, it's safe to read in a goroutine: collect := func() error { - clusterProbes := &mysql.ClusterProbes{ + clusterProbes := &base.ClusterProbes{ IgnoreHostsCount: clusterSettingsCopy.IgnoreHostsCount, - TabletProbes: mysql.NewProbes(), + TabletProbes: base.NewProbes(), } // self tablet addProbe(throttler.tabletAlias, nil, base.SelfScope, &clusterSettingsCopy, clusterProbes.TabletProbes) @@ -1233,7 +1232,7 @@ func (throttler *Throttler) refreshMySQLInventory(ctx context.Context) error { } // synchronous update of inventory -func (throttler *Throttler) updateMySQLClusterProbes(ctx context.Context, clusterProbes *mysql.ClusterProbes) error { +func (throttler *Throttler) updateMySQLClusterProbes(ctx context.Context, clusterProbes *base.ClusterProbes) error { throttler.mysqlInventory.ClustersProbes = clusterProbes.TabletProbes throttler.mysqlInventory.IgnoreHostsCount = clusterProbes.IgnoreHostsCount throttler.mysqlInventory.IgnoreHostsThreshold = clusterProbes.IgnoreHostsThreshold @@ -1250,7 +1249,7 @@ func (throttler *Throttler) metricNameUsedAsDefault() base.MetricName { // synchronous aggregation of collected data func (throttler *Throttler) aggregateMySQLMetrics(ctx context.Context) error { metricNameUsedAsDefault := throttler.metricNameUsedAsDefault() - aggregateTabletsMetrics := func(scope base.Scope, metricName base.MetricName, tabletResultsMap mysql.TabletResultMap) { + aggregateTabletsMetrics := func(scope base.Scope, metricName base.MetricName, tabletResultsMap base.TabletResultMap) { ignoreHostsCount := throttler.mysqlInventory.IgnoreHostsCount ignoreHostsThreshold := throttler.mysqlInventory.IgnoreHostsThreshold ignoreDialTCPErrors := throttler.configSettings.MySQLStore.IgnoreDialTCPErrors diff --git a/go/vt/vttablet/tabletserver/throttle/throttler_test.go b/go/vt/vttablet/tabletserver/throttle/throttler_test.go index 367bc9761ac..c9025ca7e1f 100644 --- a/go/vt/vttablet/tabletserver/throttle/throttler_test.go +++ b/go/vt/vttablet/tabletserver/throttle/throttler_test.go @@ -38,7 +38,6 @@ import ( "vitess.io/vitess/go/vt/vttablet/tabletserver/tabletenv" "vitess.io/vitess/go/vt/vttablet/tabletserver/throttle/base" "vitess.io/vitess/go/vt/vttablet/tabletserver/throttle/config" - "vitess.io/vitess/go/vt/vttablet/tabletserver/throttle/mysql" "vitess.io/vitess/go/vt/vttablet/tabletserver/throttle/throttlerapp" "vitess.io/vitess/go/vt/vttablet/tmclient" @@ -47,26 +46,26 @@ import ( ) var ( - selfMetrics = mysql.ThrottleMetrics{ - base.LagMetricName: &mysql.ThrottleMetric{ + selfMetrics = base.ThrottleMetrics{ + base.LagMetricName: &base.ThrottleMetric{ Scope: base.SelfScope, Alias: "", Value: 0.3, Err: nil, }, - base.ThreadsRunningMetricName: &mysql.ThrottleMetric{ + base.ThreadsRunningMetricName: &base.ThrottleMetric{ Scope: base.SelfScope, Alias: "", Value: 26, Err: nil, }, - base.CustomMetricName: &mysql.ThrottleMetric{ + base.CustomMetricName: &base.ThrottleMetric{ Scope: base.SelfScope, Alias: "", Value: 17, Err: nil, }, - base.LoadAvgMetricName: &mysql.ThrottleMetric{ + base.LoadAvgMetricName: &base.ThrottleMetric{ Scope: base.SelfScope, Alias: "", Value: 2.718, @@ -234,10 +233,10 @@ func newTestThrottler() *Throttler { env := tabletenv.NewEnv(vtenv.NewTestEnv(), nil, "TabletServerTest") throttler := &Throttler{ - mysqlClusterProbesChan: make(chan *mysql.ClusterProbes), + mysqlClusterProbesChan: make(chan *base.ClusterProbes), heartbeatWriter: &FakeHeartbeatWriter{}, ts: &FakeTopoServer{}, - mysqlInventory: mysql.NewInventory(), + mysqlInventory: base.NewInventory(), pool: connpool.NewPool(env, "ThrottlerPool", tabletenv.ConnPoolConfig{}), tabletTypeFunc: func() topodatapb.TabletType { return topodatapb.TabletType_PRIMARY }, overrideTmClient: &fakeTMClient{}, @@ -246,11 +245,11 @@ func newTestThrottler() *Throttler { throttler.MetricsThreshold.Store(math.Float64bits(0.75)) throttler.configSettings = config.NewConfigurationSettings() throttler.initConfig() - throttler.throttleMetricChan = make(chan *mysql.ThrottleMetric) - throttler.mysqlClusterProbesChan = make(chan *mysql.ClusterProbes) + throttler.throttleMetricChan = make(chan *base.ThrottleMetric) + throttler.mysqlClusterProbesChan = make(chan *base.ClusterProbes) throttler.throttlerConfigChan = make(chan *topodatapb.ThrottlerConfig) throttler.serialFuncChan = make(chan func()) - throttler.mysqlInventory = mysql.NewInventory() + throttler.mysqlInventory = base.NewInventory() throttler.throttledApps = cache.New(cache.NoExpiration, 0) throttler.metricThresholds = cache.New(cache.NoExpiration, 0) @@ -272,7 +271,7 @@ func newTestThrottler() *Throttler { throttler.recentCheckDormantDiff = int64(throttler.dormantPeriod / recentCheckRateLimiterInterval) throttler.recentCheckDiff = int64(3 * time.Second / recentCheckRateLimiterInterval) - throttler.readSelfThrottleMetrics = func(ctx context.Context) mysql.ThrottleMetrics { + throttler.readSelfThrottleMetrics = func(ctx context.Context) base.ThrottleMetrics { for _, metric := range selfMetrics { go func() { select { @@ -902,10 +901,10 @@ func TestRefreshMySQLInventory(t *testing.T) { configSettings := config.NewConfigurationSettings() throttler := &Throttler{ - mysqlClusterProbesChan: make(chan *mysql.ClusterProbes), + mysqlClusterProbesChan: make(chan *base.ClusterProbes), metricThresholds: cache.New(cache.NoExpiration, 0), ts: &FakeTopoServer{}, - mysqlInventory: mysql.NewInventory(), + mysqlInventory: base.NewInventory(), } throttler.metricsQuery.Store(metricsQuery) throttler.configSettings = configSettings @@ -916,7 +915,7 @@ func TestRefreshMySQLInventory(t *testing.T) { testName := fmt.Sprintf("leader=%t", throttler.isLeader.Load()) t.Run(testName, func(t *testing.T) { // validateProbesCount expects number of probes according to cluster name and throttler's leadership status - validateProbesCount := func(t *testing.T, probes mysql.Probes) { + validateProbesCount := func(t *testing.T, probes base.Probes) { if throttler.isLeader.Load() { assert.Equal(t, 3, len(probes)) } else { From f6e8a5546f2a8a2cab0a9cf5c22301130b5cf9a1 Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Thu, 11 Jul 2024 11:32:53 +0300 Subject: [PATCH 10/20] Remove unused type Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- go/vt/vttablet/tabletserver/throttle/check.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/go/vt/vttablet/tabletserver/throttle/check.go b/go/vt/vttablet/tabletserver/throttle/check.go index 1287ef945ed..069a1c275f5 100644 --- a/go/vt/vttablet/tabletserver/throttle/check.go +++ b/go/vt/vttablet/tabletserver/throttle/check.go @@ -62,8 +62,6 @@ var ( statsThrottlerCheckAnyError = stats.GetOrNewCounter("ThrottlerCheckAnyError", "total number of failed checks") ) -type ThrottlePriority int - // CheckFlags provide hints for a check type CheckFlags struct { Scope base.Scope From 1ea1b5133589caecc5aab9e1cb4cf5082fcbdbdd Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Thu, 11 Jul 2024 11:38:31 +0300 Subject: [PATCH 11/20] remove ctx argument Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- go/vt/vttablet/tabletserver/throttle/mysql.go | 2 - .../tabletserver/throttle/mysql_test.go | 42 +++++++++---------- .../tabletserver/throttle/throttler.go | 2 +- 3 files changed, 20 insertions(+), 26 deletions(-) diff --git a/go/vt/vttablet/tabletserver/throttle/mysql.go b/go/vt/vttablet/tabletserver/throttle/mysql.go index c952c644638..d28a234a087 100644 --- a/go/vt/vttablet/tabletserver/throttle/mysql.go +++ b/go/vt/vttablet/tabletserver/throttle/mysql.go @@ -42,14 +42,12 @@ limitations under the License. package throttle import ( - "context" "sort" "vitess.io/vitess/go/vt/vttablet/tabletserver/throttle/base" ) func aggregateMetricResults( - ctx context.Context, metricName base.MetricName, tabletResultsMap base.TabletResultMap, ignoreHostsCount int, diff --git a/go/vt/vttablet/tabletserver/throttle/mysql_test.go b/go/vt/vttablet/tabletserver/throttle/mysql_test.go index ade8a6e6e0f..182cf6b0cea 100644 --- a/go/vt/vttablet/tabletserver/throttle/mysql_test.go +++ b/go/vt/vttablet/tabletserver/throttle/mysql_test.go @@ -42,7 +42,6 @@ limitations under the License. package throttle import ( - "context" "testing" "vitess.io/vitess/go/vt/vttablet/tabletserver/throttle/base" @@ -78,7 +77,6 @@ func noSuchMetricMap() base.MetricResultMap { } func TestAggregateMetricResultsNoErrors(t *testing.T) { - ctx := context.Background() tabletResultsMap := base.TabletResultMap{ alias1: newMetricResultMap(1.2), alias2: newMetricResultMap(1.7), @@ -88,37 +86,37 @@ func TestAggregateMetricResultsNoErrors(t *testing.T) { } { - worstMetric := aggregateMetricResults(ctx, base.DefaultMetricName, tabletResultsMap, 0, false, 0) + worstMetric := aggregateMetricResults(base.DefaultMetricName, tabletResultsMap, 0, false, 0) value, err := worstMetric.Get() assert.NoError(t, err) assert.Equal(t, value, 1.7) } { - worstMetric := aggregateMetricResults(ctx, base.DefaultMetricName, tabletResultsMap, 1, false, 0) + worstMetric := aggregateMetricResults(base.DefaultMetricName, tabletResultsMap, 1, false, 0) value, err := worstMetric.Get() assert.NoError(t, err) assert.Equal(t, value, 1.2) } { - worstMetric := aggregateMetricResults(ctx, base.DefaultMetricName, tabletResultsMap, 2, false, 0) + worstMetric := aggregateMetricResults(base.DefaultMetricName, tabletResultsMap, 2, false, 0) value, err := worstMetric.Get() assert.NoError(t, err) assert.Equal(t, value, 1.1) } { - worstMetric := aggregateMetricResults(ctx, base.DefaultMetricName, tabletResultsMap, 3, false, 0) + worstMetric := aggregateMetricResults(base.DefaultMetricName, tabletResultsMap, 3, false, 0) value, err := worstMetric.Get() assert.NoError(t, err) assert.Equal(t, value, 0.6) } { - worstMetric := aggregateMetricResults(ctx, base.DefaultMetricName, tabletResultsMap, 4, false, 0) + worstMetric := aggregateMetricResults(base.DefaultMetricName, tabletResultsMap, 4, false, 0) value, err := worstMetric.Get() assert.NoError(t, err) assert.Equal(t, value, 0.3) } { - worstMetric := aggregateMetricResults(ctx, base.DefaultMetricName, tabletResultsMap, 5, false, 0) + worstMetric := aggregateMetricResults(base.DefaultMetricName, tabletResultsMap, 5, false, 0) value, err := worstMetric.Get() assert.NoError(t, err) assert.Equal(t, value, 0.3) @@ -126,7 +124,6 @@ func TestAggregateMetricResultsNoErrors(t *testing.T) { } func TestAggregateMetricResultsNoErrorsIgnoreHostsThreshold(t *testing.T) { - ctx := context.Background() tabletResultsMap := base.TabletResultMap{ alias1: newMetricResultMap(1.2), alias2: newMetricResultMap(1.7), @@ -136,37 +133,37 @@ func TestAggregateMetricResultsNoErrorsIgnoreHostsThreshold(t *testing.T) { } { - worstMetric := aggregateMetricResults(ctx, base.DefaultMetricName, tabletResultsMap, 0, false, 1.0) + worstMetric := aggregateMetricResults(base.DefaultMetricName, tabletResultsMap, 0, false, 1.0) value, err := worstMetric.Get() assert.NoError(t, err) assert.Equal(t, value, 1.7) } { - worstMetric := aggregateMetricResults(ctx, base.DefaultMetricName, tabletResultsMap, 1, false, 1.0) + worstMetric := aggregateMetricResults(base.DefaultMetricName, tabletResultsMap, 1, false, 1.0) value, err := worstMetric.Get() assert.NoError(t, err) assert.Equal(t, value, 1.2) } { - worstMetric := aggregateMetricResults(ctx, base.DefaultMetricName, tabletResultsMap, 2, false, 1.0) + worstMetric := aggregateMetricResults(base.DefaultMetricName, tabletResultsMap, 2, false, 1.0) value, err := worstMetric.Get() assert.NoError(t, err) assert.Equal(t, value, 1.1) } { - worstMetric := aggregateMetricResults(ctx, base.DefaultMetricName, tabletResultsMap, 3, false, 1.0) + worstMetric := aggregateMetricResults(base.DefaultMetricName, tabletResultsMap, 3, false, 1.0) value, err := worstMetric.Get() assert.NoError(t, err) assert.Equal(t, value, 0.6) } { - worstMetric := aggregateMetricResults(ctx, base.DefaultMetricName, tabletResultsMap, 4, false, 1.0) + worstMetric := aggregateMetricResults(base.DefaultMetricName, tabletResultsMap, 4, false, 1.0) value, err := worstMetric.Get() assert.NoError(t, err) assert.Equal(t, value, 0.6) } { - worstMetric := aggregateMetricResults(ctx, base.DefaultMetricName, tabletResultsMap, 5, false, 1.0) + worstMetric := aggregateMetricResults(base.DefaultMetricName, tabletResultsMap, 5, false, 1.0) value, err := worstMetric.Get() assert.NoError(t, err) assert.Equal(t, value, 0.6) @@ -174,7 +171,6 @@ func TestAggregateMetricResultsNoErrorsIgnoreHostsThreshold(t *testing.T) { } func TestAggregateMetricResultsWithErrors(t *testing.T) { - ctx := context.Background() tabletResultsMap := base.TabletResultMap{ alias1: newMetricResultMap(1.2), alias2: newMetricResultMap(1.7), @@ -184,25 +180,25 @@ func TestAggregateMetricResultsWithErrors(t *testing.T) { } t.Run("nonexistent", func(t *testing.T) { - worstMetric := aggregateMetricResults(ctx, nonexistentMetricName, tabletResultsMap, 0, false, 0) + worstMetric := aggregateMetricResults(nonexistentMetricName, tabletResultsMap, 0, false, 0) _, err := worstMetric.Get() assert.Error(t, err) assert.Equal(t, base.ErrNoSuchMetric, err) }) t.Run("no ignore", func(t *testing.T) { - worstMetric := aggregateMetricResults(ctx, base.DefaultMetricName, tabletResultsMap, 0, false, 0) + worstMetric := aggregateMetricResults(base.DefaultMetricName, tabletResultsMap, 0, false, 0) _, err := worstMetric.Get() assert.Error(t, err) assert.Equal(t, base.ErrNoSuchMetric, err) }) t.Run("ignore 1", func(t *testing.T) { - worstMetric := aggregateMetricResults(ctx, base.DefaultMetricName, tabletResultsMap, 1, false, 0) + worstMetric := aggregateMetricResults(base.DefaultMetricName, tabletResultsMap, 1, false, 0) value, err := worstMetric.Get() assert.NoError(t, err) assert.Equal(t, 1.7, value) }) t.Run("ignore 2", func(t *testing.T) { - worstMetric := aggregateMetricResults(ctx, base.DefaultMetricName, tabletResultsMap, 2, false, 0) + worstMetric := aggregateMetricResults(base.DefaultMetricName, tabletResultsMap, 2, false, 0) value, err := worstMetric.Get() assert.NoError(t, err) assert.Equal(t, 1.2, value) @@ -210,19 +206,19 @@ func TestAggregateMetricResultsWithErrors(t *testing.T) { tabletResultsMap[alias1][base.DefaultMetricName] = base.NoSuchMetric t.Run("no such metric", func(t *testing.T) { - worstMetric := aggregateMetricResults(ctx, base.DefaultMetricName, tabletResultsMap, 0, false, 0) + worstMetric := aggregateMetricResults(base.DefaultMetricName, tabletResultsMap, 0, false, 0) _, err := worstMetric.Get() assert.Error(t, err) assert.Equal(t, base.ErrNoSuchMetric, err) }) t.Run("no such metric, ignore 1", func(t *testing.T) { - worstMetric := aggregateMetricResults(ctx, base.DefaultMetricName, tabletResultsMap, 1, false, 0) + worstMetric := aggregateMetricResults(base.DefaultMetricName, tabletResultsMap, 1, false, 0) _, err := worstMetric.Get() assert.Error(t, err) assert.Equal(t, base.ErrNoSuchMetric, err) }) t.Run("metric found", func(t *testing.T) { - worstMetric := aggregateMetricResults(ctx, base.DefaultMetricName, tabletResultsMap, 2, false, 0) + worstMetric := aggregateMetricResults(base.DefaultMetricName, tabletResultsMap, 2, false, 0) value, err := worstMetric.Get() assert.NoError(t, err) assert.Equal(t, value, 1.7) diff --git a/go/vt/vttablet/tabletserver/throttle/throttler.go b/go/vt/vttablet/tabletserver/throttle/throttler.go index 6055d0fa487..9f98baec667 100644 --- a/go/vt/vttablet/tabletserver/throttle/throttler.go +++ b/go/vt/vttablet/tabletserver/throttle/throttler.go @@ -1254,7 +1254,7 @@ func (throttler *Throttler) aggregateMySQLMetrics(ctx context.Context) error { ignoreHostsThreshold := throttler.mysqlInventory.IgnoreHostsThreshold ignoreDialTCPErrors := throttler.configSettings.MySQLStore.IgnoreDialTCPErrors - aggregatedMetric := aggregateMetricResults(ctx, metricName, tabletResultsMap, ignoreHostsCount, ignoreDialTCPErrors, ignoreHostsThreshold) + aggregatedMetric := aggregateMetricResults(metricName, tabletResultsMap, ignoreHostsCount, ignoreDialTCPErrors, ignoreHostsThreshold) aggregatedMetricName := metricName.AggregatedName(scope) throttler.aggregatedMetrics.Set(aggregatedMetricName, aggregatedMetric, cache.DefaultExpiration) if metricName == metricNameUsedAsDefault { From 1bddcc019c35b58e88dc507116a39995ed1ddf4a Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Thu, 11 Jul 2024 11:41:23 +0300 Subject: [PATCH 12/20] rename aggregateMetricResults -> aggregateTabletMetricResults Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- go/vt/vttablet/tabletserver/throttle/mysql.go | 2 +- .../tabletserver/throttle/mysql_test.go | 44 +++++++++---------- .../tabletserver/throttle/throttler.go | 2 +- 3 files changed, 24 insertions(+), 24 deletions(-) diff --git a/go/vt/vttablet/tabletserver/throttle/mysql.go b/go/vt/vttablet/tabletserver/throttle/mysql.go index d28a234a087..cc49163d52b 100644 --- a/go/vt/vttablet/tabletserver/throttle/mysql.go +++ b/go/vt/vttablet/tabletserver/throttle/mysql.go @@ -47,7 +47,7 @@ import ( "vitess.io/vitess/go/vt/vttablet/tabletserver/throttle/base" ) -func aggregateMetricResults( +func aggregateTabletMetricResults( metricName base.MetricName, tabletResultsMap base.TabletResultMap, ignoreHostsCount int, diff --git a/go/vt/vttablet/tabletserver/throttle/mysql_test.go b/go/vt/vttablet/tabletserver/throttle/mysql_test.go index 182cf6b0cea..fe320d569be 100644 --- a/go/vt/vttablet/tabletserver/throttle/mysql_test.go +++ b/go/vt/vttablet/tabletserver/throttle/mysql_test.go @@ -76,7 +76,7 @@ func noSuchMetricMap() base.MetricResultMap { return result } -func TestAggregateMetricResultsNoErrors(t *testing.T) { +func TestAggregateTabletMetricResultsNoErrors(t *testing.T) { tabletResultsMap := base.TabletResultMap{ alias1: newMetricResultMap(1.2), alias2: newMetricResultMap(1.7), @@ -86,44 +86,44 @@ func TestAggregateMetricResultsNoErrors(t *testing.T) { } { - worstMetric := aggregateMetricResults(base.DefaultMetricName, tabletResultsMap, 0, false, 0) + worstMetric := aggregateTabletMetricResults(base.DefaultMetricName, tabletResultsMap, 0, false, 0) value, err := worstMetric.Get() assert.NoError(t, err) assert.Equal(t, value, 1.7) } { - worstMetric := aggregateMetricResults(base.DefaultMetricName, tabletResultsMap, 1, false, 0) + worstMetric := aggregateTabletMetricResults(base.DefaultMetricName, tabletResultsMap, 1, false, 0) value, err := worstMetric.Get() assert.NoError(t, err) assert.Equal(t, value, 1.2) } { - worstMetric := aggregateMetricResults(base.DefaultMetricName, tabletResultsMap, 2, false, 0) + worstMetric := aggregateTabletMetricResults(base.DefaultMetricName, tabletResultsMap, 2, false, 0) value, err := worstMetric.Get() assert.NoError(t, err) assert.Equal(t, value, 1.1) } { - worstMetric := aggregateMetricResults(base.DefaultMetricName, tabletResultsMap, 3, false, 0) + worstMetric := aggregateTabletMetricResults(base.DefaultMetricName, tabletResultsMap, 3, false, 0) value, err := worstMetric.Get() assert.NoError(t, err) assert.Equal(t, value, 0.6) } { - worstMetric := aggregateMetricResults(base.DefaultMetricName, tabletResultsMap, 4, false, 0) + worstMetric := aggregateTabletMetricResults(base.DefaultMetricName, tabletResultsMap, 4, false, 0) value, err := worstMetric.Get() assert.NoError(t, err) assert.Equal(t, value, 0.3) } { - worstMetric := aggregateMetricResults(base.DefaultMetricName, tabletResultsMap, 5, false, 0) + worstMetric := aggregateTabletMetricResults(base.DefaultMetricName, tabletResultsMap, 5, false, 0) value, err := worstMetric.Get() assert.NoError(t, err) assert.Equal(t, value, 0.3) } } -func TestAggregateMetricResultsNoErrorsIgnoreHostsThreshold(t *testing.T) { +func TestAggregateTabletMetricResultsNoErrorsIgnoreHostsThreshold(t *testing.T) { tabletResultsMap := base.TabletResultMap{ alias1: newMetricResultMap(1.2), alias2: newMetricResultMap(1.7), @@ -133,44 +133,44 @@ func TestAggregateMetricResultsNoErrorsIgnoreHostsThreshold(t *testing.T) { } { - worstMetric := aggregateMetricResults(base.DefaultMetricName, tabletResultsMap, 0, false, 1.0) + worstMetric := aggregateTabletMetricResults(base.DefaultMetricName, tabletResultsMap, 0, false, 1.0) value, err := worstMetric.Get() assert.NoError(t, err) assert.Equal(t, value, 1.7) } { - worstMetric := aggregateMetricResults(base.DefaultMetricName, tabletResultsMap, 1, false, 1.0) + worstMetric := aggregateTabletMetricResults(base.DefaultMetricName, tabletResultsMap, 1, false, 1.0) value, err := worstMetric.Get() assert.NoError(t, err) assert.Equal(t, value, 1.2) } { - worstMetric := aggregateMetricResults(base.DefaultMetricName, tabletResultsMap, 2, false, 1.0) + worstMetric := aggregateTabletMetricResults(base.DefaultMetricName, tabletResultsMap, 2, false, 1.0) value, err := worstMetric.Get() assert.NoError(t, err) assert.Equal(t, value, 1.1) } { - worstMetric := aggregateMetricResults(base.DefaultMetricName, tabletResultsMap, 3, false, 1.0) + worstMetric := aggregateTabletMetricResults(base.DefaultMetricName, tabletResultsMap, 3, false, 1.0) value, err := worstMetric.Get() assert.NoError(t, err) assert.Equal(t, value, 0.6) } { - worstMetric := aggregateMetricResults(base.DefaultMetricName, tabletResultsMap, 4, false, 1.0) + worstMetric := aggregateTabletMetricResults(base.DefaultMetricName, tabletResultsMap, 4, false, 1.0) value, err := worstMetric.Get() assert.NoError(t, err) assert.Equal(t, value, 0.6) } { - worstMetric := aggregateMetricResults(base.DefaultMetricName, tabletResultsMap, 5, false, 1.0) + worstMetric := aggregateTabletMetricResults(base.DefaultMetricName, tabletResultsMap, 5, false, 1.0) value, err := worstMetric.Get() assert.NoError(t, err) assert.Equal(t, value, 0.6) } } -func TestAggregateMetricResultsWithErrors(t *testing.T) { +func TestAggregateTabletMetricResultsWithErrors(t *testing.T) { tabletResultsMap := base.TabletResultMap{ alias1: newMetricResultMap(1.2), alias2: newMetricResultMap(1.7), @@ -180,25 +180,25 @@ func TestAggregateMetricResultsWithErrors(t *testing.T) { } t.Run("nonexistent", func(t *testing.T) { - worstMetric := aggregateMetricResults(nonexistentMetricName, tabletResultsMap, 0, false, 0) + worstMetric := aggregateTabletMetricResults(nonexistentMetricName, tabletResultsMap, 0, false, 0) _, err := worstMetric.Get() assert.Error(t, err) assert.Equal(t, base.ErrNoSuchMetric, err) }) t.Run("no ignore", func(t *testing.T) { - worstMetric := aggregateMetricResults(base.DefaultMetricName, tabletResultsMap, 0, false, 0) + worstMetric := aggregateTabletMetricResults(base.DefaultMetricName, tabletResultsMap, 0, false, 0) _, err := worstMetric.Get() assert.Error(t, err) assert.Equal(t, base.ErrNoSuchMetric, err) }) t.Run("ignore 1", func(t *testing.T) { - worstMetric := aggregateMetricResults(base.DefaultMetricName, tabletResultsMap, 1, false, 0) + worstMetric := aggregateTabletMetricResults(base.DefaultMetricName, tabletResultsMap, 1, false, 0) value, err := worstMetric.Get() assert.NoError(t, err) assert.Equal(t, 1.7, value) }) t.Run("ignore 2", func(t *testing.T) { - worstMetric := aggregateMetricResults(base.DefaultMetricName, tabletResultsMap, 2, false, 0) + worstMetric := aggregateTabletMetricResults(base.DefaultMetricName, tabletResultsMap, 2, false, 0) value, err := worstMetric.Get() assert.NoError(t, err) assert.Equal(t, 1.2, value) @@ -206,19 +206,19 @@ func TestAggregateMetricResultsWithErrors(t *testing.T) { tabletResultsMap[alias1][base.DefaultMetricName] = base.NoSuchMetric t.Run("no such metric", func(t *testing.T) { - worstMetric := aggregateMetricResults(base.DefaultMetricName, tabletResultsMap, 0, false, 0) + worstMetric := aggregateTabletMetricResults(base.DefaultMetricName, tabletResultsMap, 0, false, 0) _, err := worstMetric.Get() assert.Error(t, err) assert.Equal(t, base.ErrNoSuchMetric, err) }) t.Run("no such metric, ignore 1", func(t *testing.T) { - worstMetric := aggregateMetricResults(base.DefaultMetricName, tabletResultsMap, 1, false, 0) + worstMetric := aggregateTabletMetricResults(base.DefaultMetricName, tabletResultsMap, 1, false, 0) _, err := worstMetric.Get() assert.Error(t, err) assert.Equal(t, base.ErrNoSuchMetric, err) }) t.Run("metric found", func(t *testing.T) { - worstMetric := aggregateMetricResults(base.DefaultMetricName, tabletResultsMap, 2, false, 0) + worstMetric := aggregateTabletMetricResults(base.DefaultMetricName, tabletResultsMap, 2, false, 0) value, err := worstMetric.Get() assert.NoError(t, err) assert.Equal(t, value, 1.7) diff --git a/go/vt/vttablet/tabletserver/throttle/throttler.go b/go/vt/vttablet/tabletserver/throttle/throttler.go index 9f98baec667..973c39dd842 100644 --- a/go/vt/vttablet/tabletserver/throttle/throttler.go +++ b/go/vt/vttablet/tabletserver/throttle/throttler.go @@ -1254,7 +1254,7 @@ func (throttler *Throttler) aggregateMySQLMetrics(ctx context.Context) error { ignoreHostsThreshold := throttler.mysqlInventory.IgnoreHostsThreshold ignoreDialTCPErrors := throttler.configSettings.MySQLStore.IgnoreDialTCPErrors - aggregatedMetric := aggregateMetricResults(metricName, tabletResultsMap, ignoreHostsCount, ignoreDialTCPErrors, ignoreHostsThreshold) + aggregatedMetric := aggregateTabletMetricResults(metricName, tabletResultsMap, ignoreHostsCount, ignoreDialTCPErrors, ignoreHostsThreshold) aggregatedMetricName := metricName.AggregatedName(scope) throttler.aggregatedMetrics.Set(aggregatedMetricName, aggregatedMetric, cache.DefaultExpiration) if metricName == metricNameUsedAsDefault { From ec62bbebf1aa646b04b01953452a7fa5835769d6 Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Thu, 11 Jul 2024 11:46:55 +0300 Subject: [PATCH 13/20] shuffle code around, moving aggregateTabletMetricResults into 'base' package Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- .../tabletserver/throttle/base/inventory.go | 11 - go/vt/vttablet/tabletserver/throttle/mysql.go | 117 --------- .../tabletserver/throttle/mysql_test.go | 226 ------------------ .../tabletserver/throttle/throttler.go | 2 +- 4 files changed, 1 insertion(+), 355 deletions(-) delete mode 100644 go/vt/vttablet/tabletserver/throttle/mysql.go delete mode 100644 go/vt/vttablet/tabletserver/throttle/mysql_test.go diff --git a/go/vt/vttablet/tabletserver/throttle/base/inventory.go b/go/vt/vttablet/tabletserver/throttle/base/inventory.go index d4776bf19b2..5294caf1115 100644 --- a/go/vt/vttablet/tabletserver/throttle/base/inventory.go +++ b/go/vt/vttablet/tabletserver/throttle/base/inventory.go @@ -41,17 +41,6 @@ limitations under the License. package base -// TabletResultMap maps a tablet to a result -type TabletResultMap map[string]MetricResultMap - -func (m TabletResultMap) Split(alias string) (withAlias TabletResultMap, all TabletResultMap) { - withAlias = make(TabletResultMap) - if val, ok := m[alias]; ok { - withAlias[alias] = val - } - return withAlias, m -} - // Inventory has the operational data about probes, their metrics, and relevant configuration type Inventory struct { ClustersProbes Probes diff --git a/go/vt/vttablet/tabletserver/throttle/mysql.go b/go/vt/vttablet/tabletserver/throttle/mysql.go deleted file mode 100644 index cc49163d52b..00000000000 --- a/go/vt/vttablet/tabletserver/throttle/mysql.go +++ /dev/null @@ -1,117 +0,0 @@ -/* -Copyright 2023 The Vitess Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// This codebase originates from https://github.com/github/freno, See https://github.com/github/freno/blob/master/LICENSE -/* - MIT License - - Copyright (c) 2017 GitHub - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in all - copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. -*/ - -package throttle - -import ( - "sort" - - "vitess.io/vitess/go/vt/vttablet/tabletserver/throttle/base" -) - -func aggregateTabletMetricResults( - metricName base.MetricName, - tabletResultsMap base.TabletResultMap, - ignoreHostsCount int, - IgnoreDialTCPErrors bool, - ignoreHostsThreshold float64, -) (worstMetric base.MetricResult) { - // probes is known not to change. It can be *replaced*, but not changed. - // so it's safe to iterate it - probeValues := []float64{} - for _, tabletMetricResults := range tabletResultsMap { - tabletMetricResult, ok := tabletMetricResults[metricName] - if !ok { - return base.NoSuchMetric - } - if tabletMetricResult == nil { - return base.NoMetricResultYet - } - value, err := tabletMetricResult.Get() - if err != nil { - if IgnoreDialTCPErrors && base.IsDialTCPError(err) { - continue - } - if ignoreHostsCount > 0 { - // ok to skip this error - ignoreHostsCount = ignoreHostsCount - 1 - continue - } - return tabletMetricResult - } - - // No error - probeValues = append(probeValues, value) - } - if len(probeValues) == 0 { - return base.NoHostsMetricResult - } - - // If we got here, that means no errors (or good-to-skip errors) - sort.Float64s(probeValues) - // probeValues sorted ascending (from best, ie smallest, to worst, ie largest) - for ignoreHostsCount > 0 { - goodToIgnore := func() bool { - // Note that these hosts don't have errors - numProbeValues := len(probeValues) - if numProbeValues <= 1 { - // We wish to retain at least one host - return false - } - if ignoreHostsThreshold <= 0 { - // No threshold conditional (or implicitly "any value exceeds the threshold") - return true - } - if worstValue := probeValues[numProbeValues-1]; worstValue > ignoreHostsThreshold { - return true - } - return false - }() - if goodToIgnore { - probeValues = probeValues[0 : len(probeValues)-1] - } - // And, whether ignored or not, we are reducing our tokens - ignoreHostsCount = ignoreHostsCount - 1 - } - worstValue := probeValues[len(probeValues)-1] - worstMetric = base.NewSimpleMetricResult(worstValue) - return worstMetric -} diff --git a/go/vt/vttablet/tabletserver/throttle/mysql_test.go b/go/vt/vttablet/tabletserver/throttle/mysql_test.go deleted file mode 100644 index fe320d569be..00000000000 --- a/go/vt/vttablet/tabletserver/throttle/mysql_test.go +++ /dev/null @@ -1,226 +0,0 @@ -/* -Copyright 2023 The Vitess Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// This codebase originates from https://github.com/github/freno, See https://github.com/github/freno/blob/master/LICENSE -/* - MIT License - - Copyright (c) 2017 GitHub - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in all - copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. -*/ - -package throttle - -import ( - "testing" - - "vitess.io/vitess/go/vt/vttablet/tabletserver/throttle/base" - - "github.com/stretchr/testify/assert" -) - -var ( - alias1 = "zone1-0001" - alias2 = "zone1-0002" - alias3 = "zone1-0003" - alias4 = "zone1-0004" - alias5 = "zone1-0005" -) - -const ( - nonexistentMetricName base.MetricName = "nonexistent" -) - -func newMetricResultMap(val float64) base.MetricResultMap { - return base.MetricResultMap{ - base.DefaultMetricName: base.NewSimpleMetricResult(val), - base.LagMetricName: base.NewSimpleMetricResult(val), - base.LoadAvgMetricName: base.NewSimpleMetricResult(3.14), - } -} -func noSuchMetricMap() base.MetricResultMap { - result := make(base.MetricResultMap) - for _, metricName := range base.KnownMetricNames { - result[metricName] = base.NoSuchMetric - } - return result -} - -func TestAggregateTabletMetricResultsNoErrors(t *testing.T) { - tabletResultsMap := base.TabletResultMap{ - alias1: newMetricResultMap(1.2), - alias2: newMetricResultMap(1.7), - alias3: newMetricResultMap(0.3), - alias4: newMetricResultMap(0.6), - alias5: newMetricResultMap(1.1), - } - - { - worstMetric := aggregateTabletMetricResults(base.DefaultMetricName, tabletResultsMap, 0, false, 0) - value, err := worstMetric.Get() - assert.NoError(t, err) - assert.Equal(t, value, 1.7) - } - { - worstMetric := aggregateTabletMetricResults(base.DefaultMetricName, tabletResultsMap, 1, false, 0) - value, err := worstMetric.Get() - assert.NoError(t, err) - assert.Equal(t, value, 1.2) - } - { - worstMetric := aggregateTabletMetricResults(base.DefaultMetricName, tabletResultsMap, 2, false, 0) - value, err := worstMetric.Get() - assert.NoError(t, err) - assert.Equal(t, value, 1.1) - } - { - worstMetric := aggregateTabletMetricResults(base.DefaultMetricName, tabletResultsMap, 3, false, 0) - value, err := worstMetric.Get() - assert.NoError(t, err) - assert.Equal(t, value, 0.6) - } - { - worstMetric := aggregateTabletMetricResults(base.DefaultMetricName, tabletResultsMap, 4, false, 0) - value, err := worstMetric.Get() - assert.NoError(t, err) - assert.Equal(t, value, 0.3) - } - { - worstMetric := aggregateTabletMetricResults(base.DefaultMetricName, tabletResultsMap, 5, false, 0) - value, err := worstMetric.Get() - assert.NoError(t, err) - assert.Equal(t, value, 0.3) - } -} - -func TestAggregateTabletMetricResultsNoErrorsIgnoreHostsThreshold(t *testing.T) { - tabletResultsMap := base.TabletResultMap{ - alias1: newMetricResultMap(1.2), - alias2: newMetricResultMap(1.7), - alias3: newMetricResultMap(0.3), - alias4: newMetricResultMap(0.6), - alias5: newMetricResultMap(1.1), - } - - { - worstMetric := aggregateTabletMetricResults(base.DefaultMetricName, tabletResultsMap, 0, false, 1.0) - value, err := worstMetric.Get() - assert.NoError(t, err) - assert.Equal(t, value, 1.7) - } - { - worstMetric := aggregateTabletMetricResults(base.DefaultMetricName, tabletResultsMap, 1, false, 1.0) - value, err := worstMetric.Get() - assert.NoError(t, err) - assert.Equal(t, value, 1.2) - } - { - worstMetric := aggregateTabletMetricResults(base.DefaultMetricName, tabletResultsMap, 2, false, 1.0) - value, err := worstMetric.Get() - assert.NoError(t, err) - assert.Equal(t, value, 1.1) - } - { - worstMetric := aggregateTabletMetricResults(base.DefaultMetricName, tabletResultsMap, 3, false, 1.0) - value, err := worstMetric.Get() - assert.NoError(t, err) - assert.Equal(t, value, 0.6) - } - { - worstMetric := aggregateTabletMetricResults(base.DefaultMetricName, tabletResultsMap, 4, false, 1.0) - value, err := worstMetric.Get() - assert.NoError(t, err) - assert.Equal(t, value, 0.6) - } - { - worstMetric := aggregateTabletMetricResults(base.DefaultMetricName, tabletResultsMap, 5, false, 1.0) - value, err := worstMetric.Get() - assert.NoError(t, err) - assert.Equal(t, value, 0.6) - } -} - -func TestAggregateTabletMetricResultsWithErrors(t *testing.T) { - tabletResultsMap := base.TabletResultMap{ - alias1: newMetricResultMap(1.2), - alias2: newMetricResultMap(1.7), - alias3: newMetricResultMap(0.3), - alias4: noSuchMetricMap(), - alias5: newMetricResultMap(1.1), - } - - t.Run("nonexistent", func(t *testing.T) { - worstMetric := aggregateTabletMetricResults(nonexistentMetricName, tabletResultsMap, 0, false, 0) - _, err := worstMetric.Get() - assert.Error(t, err) - assert.Equal(t, base.ErrNoSuchMetric, err) - }) - t.Run("no ignore", func(t *testing.T) { - worstMetric := aggregateTabletMetricResults(base.DefaultMetricName, tabletResultsMap, 0, false, 0) - _, err := worstMetric.Get() - assert.Error(t, err) - assert.Equal(t, base.ErrNoSuchMetric, err) - }) - t.Run("ignore 1", func(t *testing.T) { - worstMetric := aggregateTabletMetricResults(base.DefaultMetricName, tabletResultsMap, 1, false, 0) - value, err := worstMetric.Get() - assert.NoError(t, err) - assert.Equal(t, 1.7, value) - }) - t.Run("ignore 2", func(t *testing.T) { - worstMetric := aggregateTabletMetricResults(base.DefaultMetricName, tabletResultsMap, 2, false, 0) - value, err := worstMetric.Get() - assert.NoError(t, err) - assert.Equal(t, 1.2, value) - }) - - tabletResultsMap[alias1][base.DefaultMetricName] = base.NoSuchMetric - t.Run("no such metric", func(t *testing.T) { - worstMetric := aggregateTabletMetricResults(base.DefaultMetricName, tabletResultsMap, 0, false, 0) - _, err := worstMetric.Get() - assert.Error(t, err) - assert.Equal(t, base.ErrNoSuchMetric, err) - }) - t.Run("no such metric, ignore 1", func(t *testing.T) { - worstMetric := aggregateTabletMetricResults(base.DefaultMetricName, tabletResultsMap, 1, false, 0) - _, err := worstMetric.Get() - assert.Error(t, err) - assert.Equal(t, base.ErrNoSuchMetric, err) - }) - t.Run("metric found", func(t *testing.T) { - worstMetric := aggregateTabletMetricResults(base.DefaultMetricName, tabletResultsMap, 2, false, 0) - value, err := worstMetric.Get() - assert.NoError(t, err) - assert.Equal(t, value, 1.7) - }) -} diff --git a/go/vt/vttablet/tabletserver/throttle/throttler.go b/go/vt/vttablet/tabletserver/throttle/throttler.go index 973c39dd842..f660358ed9f 100644 --- a/go/vt/vttablet/tabletserver/throttle/throttler.go +++ b/go/vt/vttablet/tabletserver/throttle/throttler.go @@ -1254,7 +1254,7 @@ func (throttler *Throttler) aggregateMySQLMetrics(ctx context.Context) error { ignoreHostsThreshold := throttler.mysqlInventory.IgnoreHostsThreshold ignoreDialTCPErrors := throttler.configSettings.MySQLStore.IgnoreDialTCPErrors - aggregatedMetric := aggregateTabletMetricResults(metricName, tabletResultsMap, ignoreHostsCount, ignoreDialTCPErrors, ignoreHostsThreshold) + aggregatedMetric := base.AggregateTabletMetricResults(metricName, tabletResultsMap, ignoreHostsCount, ignoreDialTCPErrors, ignoreHostsThreshold) aggregatedMetricName := metricName.AggregatedName(scope) throttler.aggregatedMetrics.Set(aggregatedMetricName, aggregatedMetric, cache.DefaultExpiration) if metricName == metricNameUsedAsDefault { From c82ea9a713b4c266c85345febfecec50e1ccf92a Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Thu, 11 Jul 2024 11:47:38 +0300 Subject: [PATCH 14/20] remove ctx where unused Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- go/vt/vttablet/tabletserver/throttle/throttler.go | 4 ++-- go/vt/vttablet/tabletserver/throttle/throttler_test.go | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go/vt/vttablet/tabletserver/throttle/throttler.go b/go/vt/vttablet/tabletserver/throttle/throttler.go index f660358ed9f..e35fb288a14 100644 --- a/go/vt/vttablet/tabletserver/throttle/throttler.go +++ b/go/vt/vttablet/tabletserver/throttle/throttler.go @@ -980,7 +980,7 @@ func (throttler *Throttler) Operate(ctx context.Context, wg *sync.WaitGroup) { throttler.updateMySQLClusterProbes(ctx, probes) case <-mysqlAggregateTicker.C: if throttler.IsOpen() { - throttler.aggregateMySQLMetrics(ctx) + throttler.aggregateMySQLMetrics() } case <-throttledAppsTicker.C: if throttler.IsOpen() { @@ -1247,7 +1247,7 @@ func (throttler *Throttler) metricNameUsedAsDefault() base.MetricName { } // synchronous aggregation of collected data -func (throttler *Throttler) aggregateMySQLMetrics(ctx context.Context) error { +func (throttler *Throttler) aggregateMySQLMetrics() error { metricNameUsedAsDefault := throttler.metricNameUsedAsDefault() aggregateTabletsMetrics := func(scope base.Scope, metricName base.MetricName, tabletResultsMap base.TabletResultMap) { ignoreHostsCount := throttler.mysqlInventory.IgnoreHostsCount diff --git a/go/vt/vttablet/tabletserver/throttle/throttler_test.go b/go/vt/vttablet/tabletserver/throttle/throttler_test.go index c9025ca7e1f..ac4e65c304c 100644 --- a/go/vt/vttablet/tabletserver/throttle/throttler_test.go +++ b/go/vt/vttablet/tabletserver/throttle/throttler_test.go @@ -1142,7 +1142,7 @@ func TestProbesWhileOperating(t *testing.T) { // as opposed to choosing the "lag" metric results. throttler.customMetricsQuery.Store("select non_empty") <-runSerialFunction(t, ctx, throttler, func(ctx context.Context) { - throttler.aggregateMySQLMetrics(ctx) + throttler.aggregateMySQLMetrics() }) assert.Equal(t, base.CustomMetricName, throttler.metricNameUsedAsDefault()) // throttler.aggregateMySQLMetrics(ctx) From 342378003a623ea26424e9e668a10d4887b16867 Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Thu, 11 Jul 2024 11:54:29 +0300 Subject: [PATCH 15/20] terminology: remove 'MySQL' where irrelevant. Add where relevant Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- .../tabletserver/throttle/throttler.go | 80 +++++++++---------- .../tabletserver/throttle/throttler_test.go | 69 ++++++++-------- 2 files changed, 74 insertions(+), 75 deletions(-) diff --git a/go/vt/vttablet/tabletserver/throttle/throttler.go b/go/vt/vttablet/tabletserver/throttle/throttler.go index e35fb288a14..266f9c31aa6 100644 --- a/go/vt/vttablet/tabletserver/throttle/throttler.go +++ b/go/vt/vttablet/tabletserver/throttle/throttler.go @@ -179,12 +179,12 @@ type Throttler struct { throttleTabletTypesMap map[topodatapb.TabletType]bool - throttleMetricChan chan *base.ThrottleMetric - mysqlClusterProbesChan chan *base.ClusterProbes - throttlerConfigChan chan *topodatapb.ThrottlerConfig - serialFuncChan chan func() // Used by unit tests to inject non-racy behavior + throttleMetricChan chan *base.ThrottleMetric + clusterProbesChan chan *base.ClusterProbes + throttlerConfigChan chan *topodatapb.ThrottlerConfig + serialFuncChan chan func() // Used by unit tests to inject non-racy behavior - mysqlInventory *base.Inventory + inventory *base.Inventory metricsQuery atomic.Value customMetricsQuery atomic.Value @@ -251,10 +251,10 @@ func NewThrottler(env tabletenv.Env, srvTopoServer srvtopo.Server, ts *topo.Serv } throttler.throttleMetricChan = make(chan *base.ThrottleMetric) - throttler.mysqlClusterProbesChan = make(chan *base.ClusterProbes) + throttler.clusterProbesChan = make(chan *base.ClusterProbes) throttler.throttlerConfigChan = make(chan *topodatapb.ThrottlerConfig) throttler.serialFuncChan = make(chan func()) - throttler.mysqlInventory = base.NewInventory() + throttler.inventory = base.NewInventory() throttler.throttledApps = cache.New(cache.NoExpiration, 0) throttler.metricThresholds = cache.New(cache.NoExpiration, 0) @@ -778,8 +778,8 @@ func (throttler *Throttler) readSelfLoadAvgPerCore(ctx context.Context) *base.Th return metric } -// readSelfThrottleMetric reads the mysql metric from thi very tablet's backend mysql. -func (throttler *Throttler) readSelfThrottleMetric(ctx context.Context, query string) *base.ThrottleMetric { +// readSelfMySQLThrottleMetric reads the metric from this very tablet or from its backend mysql. +func (throttler *Throttler) readSelfMySQLThrottleMetric(ctx context.Context, query string) *base.ThrottleMetric { metric := &base.ThrottleMetric{ Scope: base.SelfScope, Alias: throttler.tabletAlias, @@ -931,9 +931,9 @@ func (throttler *Throttler) Operate(ctx context.Context, wg *sync.WaitGroup) { if throttler.IsOpen() { // frequent // Always collect self metrics: - throttler.collectSelfMySQLMetrics(ctx, tmClient) + throttler.collectSelfMetrics(ctx) if !throttler.isDormant() { - throttler.collectShardMySQLMetrics(ctx, tmClient) + throttler.collectShardMetrics(ctx, tmClient) } // if throttler.recentlyChecked() { @@ -959,28 +959,28 @@ func (throttler *Throttler) Operate(ctx context.Context, wg *sync.WaitGroup) { if throttler.IsOpen() { // infrequent if throttler.isDormant() { - throttler.collectShardMySQLMetrics(ctx, tmClient) + throttler.collectShardMetrics(ctx, tmClient) } } case metric := <-throttler.throttleMetricChan: // incoming MySQL metric, frequent, as result of collectMySQLMetrics() - metricResultsMap, ok := throttler.mysqlInventory.TabletMetrics[metric.GetTabletAlias()] + metricResultsMap, ok := throttler.inventory.TabletMetrics[metric.GetTabletAlias()] if !ok { metricResultsMap = base.NewMetricResultMap() - throttler.mysqlInventory.TabletMetrics[metric.GetTabletAlias()] = metricResultsMap + throttler.inventory.TabletMetrics[metric.GetTabletAlias()] = metricResultsMap } metricResultsMap[metric.Name] = metric case <-mysqlRefreshTicker.C: // sparse if throttler.IsOpen() { - throttler.refreshMySQLInventory(ctx) + throttler.refreshInventory(ctx) } - case probes := <-throttler.mysqlClusterProbesChan: - // incoming structural update, sparse, as result of refreshMySQLInventory() - throttler.updateMySQLClusterProbes(ctx, probes) + case probes := <-throttler.clusterProbesChan: + // incoming structural update, sparse, as result of refreshInventory() + throttler.updateClusterProbes(ctx, probes) case <-mysqlAggregateTicker.C: if throttler.IsOpen() { - throttler.aggregateMySQLMetrics() + throttler.aggregateMetrics() } case <-throttledAppsTicker.C: if throttler.IsOpen() { @@ -1073,15 +1073,15 @@ func (throttler *Throttler) readSelfThrottleMetricsInternal(ctx context.Context) } } - go writeMetric(base.LagMetricName, throttler.readSelfThrottleMetric(ctx, sqlparser.BuildParsedQuery(defaultReplicationLagQuery, sidecar.GetIdentifier()).Query)) - go writeMetric(base.ThreadsRunningMetricName, throttler.readSelfThrottleMetric(ctx, threadsRunningQuery)) - go writeMetric(base.CustomMetricName, throttler.readSelfThrottleMetric(ctx, throttler.GetCustomMetricsQuery())) + go writeMetric(base.LagMetricName, throttler.readSelfMySQLThrottleMetric(ctx, sqlparser.BuildParsedQuery(defaultReplicationLagQuery, sidecar.GetIdentifier()).Query)) + go writeMetric(base.ThreadsRunningMetricName, throttler.readSelfMySQLThrottleMetric(ctx, threadsRunningQuery)) + go writeMetric(base.CustomMetricName, throttler.readSelfMySQLThrottleMetric(ctx, throttler.GetCustomMetricsQuery())) go writeMetric(base.LoadAvgMetricName, throttler.readSelfLoadAvgPerCore(ctx)) return nil } -func (throttler *Throttler) collectSelfMySQLMetrics(ctx context.Context, tmClient tmclient.TabletManagerClient) { - probe := throttler.mysqlInventory.ClustersProbes[throttler.tabletAlias] +func (throttler *Throttler) collectSelfMetrics(ctx context.Context) { + probe := throttler.inventory.ClustersProbes[throttler.tabletAlias] if probe == nil { // probe not created yet return @@ -1099,10 +1099,10 @@ func (throttler *Throttler) collectSelfMySQLMetrics(ctx context.Context, tmClien }() } -func (throttler *Throttler) collectShardMySQLMetrics(ctx context.Context, tmClient tmclient.TabletManagerClient) { +func (throttler *Throttler) collectShardMetrics(ctx context.Context, tmClient tmclient.TabletManagerClient) { // probes is known not to change. It can be *replaced*, but not changed. // so it's safe to iterate it - for _, probe := range throttler.mysqlInventory.ClustersProbes { + for _, probe := range throttler.inventory.ClustersProbes { if probe.Alias == throttler.tabletAlias { // We skip collecting our own metrics continue @@ -1130,8 +1130,8 @@ func (throttler *Throttler) collectShardMySQLMetrics(ctx context.Context, tmClie } } -// refreshMySQLInventory will re-structure the inventory based on reading config settings -func (throttler *Throttler) refreshMySQLInventory(ctx context.Context) error { +// refreshInventory will re-structure the inventory based on reading config settings +func (throttler *Throttler) refreshInventory(ctx context.Context) error { // distribute the query/threshold from the throttler down to the cluster settings and from there to the probes addProbe := func(alias string, tablet *topodatapb.Tablet, scope base.Scope, mysqlSettings *config.MySQLConfigurationSettings, probes base.Probes) bool { for _, ignore := range mysqlSettings.IgnoreHosts { @@ -1164,7 +1164,7 @@ func (throttler *Throttler) refreshMySQLInventory(ctx context.Context) error { select { case <-ctx.Done(): return ctx.Err() - case throttler.mysqlClusterProbesChan <- clusterProbes: + case throttler.clusterProbesChan <- clusterProbes: return nil } } @@ -1198,8 +1198,8 @@ func (throttler *Throttler) refreshMySQLInventory(ctx context.Context) error { // of previous clusters it used to probe. It may have recollection of specific probes for such clusters. // This now ensures any existing cluster probes are overridden with an empty list of probes. // `clusterProbes` was created above as empty, and identifiable via `scope`. This will in turn - // be used to overwrite throttler.mysqlInventory.ClustersProbes[clusterProbes.scope] in - // updateMySQLClusterProbes(). + // be used to overwrite throttler.inventory.ClustersProbes[clusterProbes.scope] in + // updateClusterProbes(). return attemptWriteProbes(clusterProbes) // not the leader (primary tablet)? Then no more work for us. } @@ -1225,17 +1225,17 @@ func (throttler *Throttler) refreshMySQLInventory(ctx context.Context) error { } go func() { if err := collect(); err != nil { - log.Errorf("refreshMySQLInventory: %+v", err) + log.Errorf("refreshInventory: %+v", err) } }() return nil } // synchronous update of inventory -func (throttler *Throttler) updateMySQLClusterProbes(ctx context.Context, clusterProbes *base.ClusterProbes) error { - throttler.mysqlInventory.ClustersProbes = clusterProbes.TabletProbes - throttler.mysqlInventory.IgnoreHostsCount = clusterProbes.IgnoreHostsCount - throttler.mysqlInventory.IgnoreHostsThreshold = clusterProbes.IgnoreHostsThreshold +func (throttler *Throttler) updateClusterProbes(ctx context.Context, clusterProbes *base.ClusterProbes) error { + throttler.inventory.ClustersProbes = clusterProbes.TabletProbes + throttler.inventory.IgnoreHostsCount = clusterProbes.IgnoreHostsCount + throttler.inventory.IgnoreHostsThreshold = clusterProbes.IgnoreHostsThreshold return nil } @@ -1247,11 +1247,11 @@ func (throttler *Throttler) metricNameUsedAsDefault() base.MetricName { } // synchronous aggregation of collected data -func (throttler *Throttler) aggregateMySQLMetrics() error { +func (throttler *Throttler) aggregateMetrics() error { metricNameUsedAsDefault := throttler.metricNameUsedAsDefault() aggregateTabletsMetrics := func(scope base.Scope, metricName base.MetricName, tabletResultsMap base.TabletResultMap) { - ignoreHostsCount := throttler.mysqlInventory.IgnoreHostsCount - ignoreHostsThreshold := throttler.mysqlInventory.IgnoreHostsThreshold + ignoreHostsCount := throttler.inventory.IgnoreHostsCount + ignoreHostsThreshold := throttler.inventory.IgnoreHostsThreshold ignoreDialTCPErrors := throttler.configSettings.MySQLStore.IgnoreDialTCPErrors aggregatedMetric := base.AggregateTabletMetricResults(metricName, tabletResultsMap, ignoreHostsCount, ignoreDialTCPErrors, ignoreHostsThreshold) @@ -1268,7 +1268,7 @@ func (throttler *Throttler) aggregateMySQLMetrics() error { // is to be stored as "default" continue } - selfResultsMap, shardResultsMap := throttler.mysqlInventory.TabletMetrics.Split(throttler.tabletAlias) + selfResultsMap, shardResultsMap := throttler.inventory.TabletMetrics.Split(throttler.tabletAlias) aggregateTabletsMetrics(base.SelfScope, metricName, selfResultsMap) aggregateTabletsMetrics(base.ShardScope, metricName, shardResultsMap) } diff --git a/go/vt/vttablet/tabletserver/throttle/throttler_test.go b/go/vt/vttablet/tabletserver/throttle/throttler_test.go index ac4e65c304c..2e272d79e20 100644 --- a/go/vt/vttablet/tabletserver/throttle/throttler_test.go +++ b/go/vt/vttablet/tabletserver/throttle/throttler_test.go @@ -233,23 +233,23 @@ func newTestThrottler() *Throttler { env := tabletenv.NewEnv(vtenv.NewTestEnv(), nil, "TabletServerTest") throttler := &Throttler{ - mysqlClusterProbesChan: make(chan *base.ClusterProbes), - heartbeatWriter: &FakeHeartbeatWriter{}, - ts: &FakeTopoServer{}, - mysqlInventory: base.NewInventory(), - pool: connpool.NewPool(env, "ThrottlerPool", tabletenv.ConnPoolConfig{}), - tabletTypeFunc: func() topodatapb.TabletType { return topodatapb.TabletType_PRIMARY }, - overrideTmClient: &fakeTMClient{}, + clusterProbesChan: make(chan *base.ClusterProbes), + heartbeatWriter: &FakeHeartbeatWriter{}, + ts: &FakeTopoServer{}, + inventory: base.NewInventory(), + pool: connpool.NewPool(env, "ThrottlerPool", tabletenv.ConnPoolConfig{}), + tabletTypeFunc: func() topodatapb.TabletType { return topodatapb.TabletType_PRIMARY }, + overrideTmClient: &fakeTMClient{}, } throttler.metricsQuery.Store(metricsQuery) throttler.MetricsThreshold.Store(math.Float64bits(0.75)) throttler.configSettings = config.NewConfigurationSettings() throttler.initConfig() throttler.throttleMetricChan = make(chan *base.ThrottleMetric) - throttler.mysqlClusterProbesChan = make(chan *base.ClusterProbes) + throttler.clusterProbesChan = make(chan *base.ClusterProbes) throttler.throttlerConfigChan = make(chan *topodatapb.ThrottlerConfig) throttler.serialFuncChan = make(chan func()) - throttler.mysqlInventory = base.NewInventory() + throttler.inventory = base.NewInventory() throttler.throttledApps = cache.New(cache.NoExpiration, 0) throttler.metricThresholds = cache.New(cache.NoExpiration, 0) @@ -887,12 +887,12 @@ func TestIsAppExempted(t *testing.T) { assert.True(t, throttler.IsAppExempted("schema-tracker")) } -// TestRefreshMySQLInventory tests the behavior of the throttler's RefreshMySQLInventory() function, which +// TestRefreshInventory tests the behavior of the throttler's RefreshInventory() function, which // is called periodically in actual throttler. For a given cluster name, it generates a list of probes // the throttler will use to check metrics. // On a replica tablet, that list is expect to probe the tablet itself. // On the PRIMARY, the list includes all shard tablets, including the PRIMARY itself. -func TestRefreshMySQLInventory(t *testing.T) { +func TestRefreshInventory(t *testing.T) { ctx := context.Background() // for development, replace with ctx := utils.LeakCheckContext(t) ctx, cancel := context.WithCancel(ctx) defer cancel() @@ -901,10 +901,10 @@ func TestRefreshMySQLInventory(t *testing.T) { configSettings := config.NewConfigurationSettings() throttler := &Throttler{ - mysqlClusterProbesChan: make(chan *base.ClusterProbes), - metricThresholds: cache.New(cache.NoExpiration, 0), - ts: &FakeTopoServer{}, - mysqlInventory: base.NewInventory(), + clusterProbesChan: make(chan *base.ClusterProbes), + metricThresholds: cache.New(cache.NoExpiration, 0), + ts: &FakeTopoServer{}, + inventory: base.NewInventory(), } throttler.metricsQuery.Store(metricsQuery) throttler.configSettings = configSettings @@ -927,12 +927,12 @@ func TestRefreshMySQLInventory(t *testing.T) { defer cancel() for { select { - case probes := <-throttler.mysqlClusterProbesChan: + case probes := <-throttler.clusterProbesChan: // Worth noting that in this unit test, the throttler is _closed_ and _disabled_. Its own Operate() function does - // not run, and therefore there is none but us to both populate `mysqlClusterProbesChan` as well as + // not run, and therefore there is none but us to both populate `clusterProbesChan` as well as // read from it. We do not compete here with any other goroutine. assert.NotNil(t, probes) - throttler.updateMySQLClusterProbes(ctx, probes) + throttler.updateClusterProbes(ctx, probes) validateProbesCount(t, probes.TabletProbes) // Achieved our goal return @@ -942,7 +942,7 @@ func TestRefreshMySQLInventory(t *testing.T) { } }) t.Run("validating probes", func(t *testing.T) { - probes := throttler.mysqlInventory.ClustersProbes + probes := throttler.inventory.ClustersProbes validateProbesCount(t, probes) }) }) @@ -950,19 +950,19 @@ func TestRefreshMySQLInventory(t *testing.T) { t.Run("initial, not leader", func(t *testing.T) { throttler.isLeader.Store(false) - throttler.refreshMySQLInventory(ctx) + throttler.refreshInventory(ctx) validateClusterProbes(t, ctx) }) t.Run("promote", func(t *testing.T) { throttler.isLeader.Store(true) - throttler.refreshMySQLInventory(ctx) + throttler.refreshInventory(ctx) validateClusterProbes(t, ctx) }) t.Run("demote, expect cleanup", func(t *testing.T) { throttler.isLeader.Store(false) - throttler.refreshMySQLInventory(ctx) + throttler.refreshInventory(ctx) validateClusterProbes(t, ctx) }) } @@ -1103,7 +1103,7 @@ func TestProbesWhileOperating(t *testing.T) { client := NewBackgroundClient(throttler, testAppName, base.UndefinedScope) t.Run("threshold exceeded", func(t *testing.T) { <-runSerialFunction(t, ctx, throttler, func(ctx context.Context) { - throttler.refreshMySQLInventory(ctx) + throttler.refreshInventory(ctx) }) { checkOK := client.ThrottleCheckOK(ctx, "") @@ -1115,7 +1115,7 @@ func TestProbesWhileOperating(t *testing.T) { t.Run("adjust threshold", func(t *testing.T) { throttler.MetricsThreshold.Store(math.Float64bits(0.95)) <-runSerialFunction(t, ctx, throttler, func(ctx context.Context) { - throttler.refreshMySQLInventory(ctx) + throttler.refreshInventory(ctx) }) { checkOK := client.ThrottleCheckOK(ctx, "") @@ -1125,7 +1125,7 @@ func TestProbesWhileOperating(t *testing.T) { t.Run("restore threshold", func(t *testing.T) { throttler.MetricsThreshold.Store(savedThreshold) <-runSerialFunction(t, ctx, throttler, func(ctx context.Context) { - throttler.refreshMySQLInventory(ctx) + throttler.refreshInventory(ctx) }) client.clearSuccessfulResultsCache() // ensure we don't read the successful result from the test above { @@ -1142,10 +1142,9 @@ func TestProbesWhileOperating(t *testing.T) { // as opposed to choosing the "lag" metric results. throttler.customMetricsQuery.Store("select non_empty") <-runSerialFunction(t, ctx, throttler, func(ctx context.Context) { - throttler.aggregateMySQLMetrics() + throttler.aggregateMetrics() }) assert.Equal(t, base.CustomMetricName, throttler.metricNameUsedAsDefault()) - // throttler.aggregateMySQLMetrics(ctx) aggr := throttler.aggregatedMetricsSnapshot() assert.Equalf(t, 2*len(base.KnownMetricNames), len(aggr), "aggregated: %+v", aggr) // "self" and "shard", per known metric assert.Equal(t, 2*len(base.KnownMetricNames), throttler.aggregatedMetrics.ItemCount()) // flushed upon Disable() @@ -1193,7 +1192,7 @@ func TestProbesWhileOperating(t *testing.T) { client := NewBackgroundClient(throttler, testAppName, base.UndefinedScope) t.Run("threshold exceeded", func(t *testing.T) { <-runSerialFunction(t, ctx, throttler, func(ctx context.Context) { - throttler.refreshMySQLInventory(ctx) + throttler.refreshInventory(ctx) }) { checkOK := client.ThrottleCheckOK(ctx, "") @@ -1205,7 +1204,7 @@ func TestProbesWhileOperating(t *testing.T) { t.Run("adjust threshold, too low", func(t *testing.T) { throttler.MetricsThreshold.Store(math.Float64bits(0.95)) <-runSerialFunction(t, ctx, throttler, func(ctx context.Context) { - throttler.refreshMySQLInventory(ctx) + throttler.refreshInventory(ctx) }) { checkOK := client.ThrottleCheckOK(ctx, "") @@ -1215,7 +1214,7 @@ func TestProbesWhileOperating(t *testing.T) { t.Run("adjust threshold, still too low", func(t *testing.T) { throttler.MetricsThreshold.Store(math.Float64bits(15)) <-runSerialFunction(t, ctx, throttler, func(ctx context.Context) { - throttler.refreshMySQLInventory(ctx) + throttler.refreshInventory(ctx) }) { checkOK := client.ThrottleCheckOK(ctx, "") @@ -1225,7 +1224,7 @@ func TestProbesWhileOperating(t *testing.T) { t.Run("adjust threshold", func(t *testing.T) { throttler.MetricsThreshold.Store(math.Float64bits(18)) <-runSerialFunction(t, ctx, throttler, func(ctx context.Context) { - throttler.refreshMySQLInventory(ctx) + throttler.refreshInventory(ctx) }) { checkOK := client.ThrottleCheckOK(ctx, "") @@ -1235,7 +1234,7 @@ func TestProbesWhileOperating(t *testing.T) { t.Run("restore threshold", func(t *testing.T) { throttler.MetricsThreshold.Store(savedThreshold) <-runSerialFunction(t, ctx, throttler, func(ctx context.Context) { - throttler.refreshMySQLInventory(ctx) + throttler.refreshInventory(ctx) }) client.clearSuccessfulResultsCache() // ensure we don't read the successful result from the test above { @@ -1340,7 +1339,7 @@ func TestProbesPostDisable(t *testing.T) { throttler := newTestThrottler() runThrottler(t, ctx, throttler, 2*time.Second, nil) - probes := throttler.mysqlInventory.ClustersProbes + probes := throttler.inventory.ClustersProbes <-time.After(1 * time.Second) // throttler's context was cancelled, but still some functionality needs to complete t.Run("probes", func(t *testing.T) { @@ -1360,7 +1359,7 @@ func TestProbesPostDisable(t *testing.T) { }) t.Run("metrics", func(t *testing.T) { - assert.Equal(t, 3, len(throttler.mysqlInventory.TabletMetrics)) // 1 self tablet + 2 shard tablets + assert.Equal(t, 3, len(throttler.inventory.TabletMetrics)) // 1 self tablet + 2 shard tablets }) t.Run("aggregated", func(t *testing.T) { @@ -1868,7 +1867,7 @@ func TestReplica(t *testing.T) { // Change custom threshold throttler.MetricsThreshold.Store(math.Float64bits(0.1)) <-runSerialFunction(t, ctx, throttler, func(ctx context.Context) { - throttler.refreshMySQLInventory(ctx) + throttler.refreshInventory(ctx) }) checkResult = throttler.Check(ctx, testAppName.String(), base.KnownMetricNames, flags) require.NotNil(t, checkResult) From 1f584a1faf45a6bf6208c0239bd9a27dad063878 Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Thu, 11 Jul 2024 11:55:54 +0300 Subject: [PATCH 16/20] terminology: remove 'MySQL' where irrelevant Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- .../tabletserver/throttle/throttler.go | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/go/vt/vttablet/tabletserver/throttle/throttler.go b/go/vt/vttablet/tabletserver/throttle/throttler.go index 266f9c31aa6..564651fff94 100644 --- a/go/vt/vttablet/tabletserver/throttle/throttler.go +++ b/go/vt/vttablet/tabletserver/throttle/throttler.go @@ -861,10 +861,10 @@ func (throttler *Throttler) Operate(ctx context.Context, wg *sync.WaitGroup) { return t } leaderCheckTicker := addTicker(throttler.leaderCheckInterval) - mysqlCollectTicker := addTicker(throttler.activeCollectInterval) - mysqlDormantCollectTicker := addTicker(throttler.dormantCollectInterval) - mysqlRefreshTicker := addTicker(throttler.inventoryRefreshInterval) - mysqlAggregateTicker := addTicker(throttler.metricsAggregateInterval) + activeCollectTicker := addTicker(throttler.activeCollectInterval) + dormantCollectTicker := addTicker(throttler.dormantCollectInterval) + inventoryRefreshTicker := addTicker(throttler.inventoryRefreshInterval) + metricsAggregateTicker := addTicker(throttler.metricsAggregateInterval) throttledAppsTicker := addTicker(throttler.throttledAppsSnapshotInterval) primaryStimulatorRateLimiter := timer.NewRateLimiter(throttler.dormantPeriod) throttler.recentCheckRateLimiter = timer.NewRateLimiter(recentCheckRateLimiterInterval) @@ -923,11 +923,11 @@ func (throttler *Throttler) Operate(ctx context.Context, wg *sync.WaitGroup) { if transitionedIntoLeader { // transitioned into leadership, let's speed up the next 'refresh' and 'collect' ticks - go mysqlRefreshTicker.TickNow() + go inventoryRefreshTicker.TickNow() throttler.requestHeartbeats() } }() - case <-mysqlCollectTicker.C: + case <-activeCollectTicker.C: if throttler.IsOpen() { // frequent // Always collect self metrics: @@ -955,7 +955,7 @@ func (throttler *Throttler) Operate(ctx context.Context, wg *sync.WaitGroup) { } } - case <-mysqlDormantCollectTicker.C: + case <-dormantCollectTicker.C: if throttler.IsOpen() { // infrequent if throttler.isDormant() { @@ -963,14 +963,14 @@ func (throttler *Throttler) Operate(ctx context.Context, wg *sync.WaitGroup) { } } case metric := <-throttler.throttleMetricChan: - // incoming MySQL metric, frequent, as result of collectMySQLMetrics() + // incoming metric, frequent, as result of collectMetrics() metricResultsMap, ok := throttler.inventory.TabletMetrics[metric.GetTabletAlias()] if !ok { metricResultsMap = base.NewMetricResultMap() throttler.inventory.TabletMetrics[metric.GetTabletAlias()] = metricResultsMap } metricResultsMap[metric.Name] = metric - case <-mysqlRefreshTicker.C: + case <-inventoryRefreshTicker.C: // sparse if throttler.IsOpen() { throttler.refreshInventory(ctx) @@ -978,7 +978,7 @@ func (throttler *Throttler) Operate(ctx context.Context, wg *sync.WaitGroup) { case probes := <-throttler.clusterProbesChan: // incoming structural update, sparse, as result of refreshInventory() throttler.updateClusterProbes(ctx, probes) - case <-mysqlAggregateTicker.C: + case <-metricsAggregateTicker.C: if throttler.IsOpen() { throttler.aggregateMetrics() } From 85994ed79de19caca6ee3f5c713db38a95f344c5 Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Thu, 11 Jul 2024 11:57:02 +0300 Subject: [PATCH 17/20] renamed getMySQLStoreMetric -> getScopedMetric Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- go/vt/vttablet/tabletserver/throttle/check.go | 2 +- go/vt/vttablet/tabletserver/throttle/throttler.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/go/vt/vttablet/tabletserver/throttle/check.go b/go/vt/vttablet/tabletserver/throttle/check.go index 069a1c275f5..e43c4cab043 100644 --- a/go/vt/vttablet/tabletserver/throttle/check.go +++ b/go/vt/vttablet/tabletserver/throttle/check.go @@ -163,7 +163,7 @@ func (check *ThrottlerCheck) Check(ctx context.Context, appName string, scope ba } metricResultFunc := func() (metricResult base.MetricResult, threshold float64) { - return check.throttler.getMySQLStoreMetric(ctx, metricScope, metricName) + return check.throttler.getScopedMetric(metricScope, metricName) } metricCheckResult := check.checkAppMetricResult(ctx, appName, metricResultFunc, flags) diff --git a/go/vt/vttablet/tabletserver/throttle/throttler.go b/go/vt/vttablet/tabletserver/throttle/throttler.go index 564651fff94..49a817c5952 100644 --- a/go/vt/vttablet/tabletserver/throttle/throttler.go +++ b/go/vt/vttablet/tabletserver/throttle/throttler.go @@ -1282,7 +1282,7 @@ func (throttler *Throttler) getAggregatedMetric(aggregatedName string) base.Metr return base.NoSuchMetric } -func (throttler *Throttler) getMySQLStoreMetric(ctx context.Context, scope base.Scope, metricName base.MetricName) (base.MetricResult, float64) { +func (throttler *Throttler) getScopedMetric(scope base.Scope, metricName base.MetricName) (base.MetricResult, float64) { thresholdVal, found := throttler.metricThresholds.Get(metricName.String()) if !found { return base.NoSuchMetric, 0 From 2492d6d9504b50af35ef2861179c33faa7cbf848 Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Thu, 11 Jul 2024 12:53:20 +0300 Subject: [PATCH 18/20] comment wording Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- go/vt/vttablet/tabletserver/throttle/throttler.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go/vt/vttablet/tabletserver/throttle/throttler.go b/go/vt/vttablet/tabletserver/throttle/throttler.go index 49a817c5952..73458974dcb 100644 --- a/go/vt/vttablet/tabletserver/throttle/throttler.go +++ b/go/vt/vttablet/tabletserver/throttle/throttler.go @@ -1527,7 +1527,7 @@ func (throttler *Throttler) AppRequestMetricResult(ctx context.Context, appName return metricResultFunc() } -// checkScope checks the aggregated value of given MySQL store +// checkScope checks the aggregated value of given store func (throttler *Throttler) checkScope(ctx context.Context, appName string, scope base.Scope, metricNames base.MetricNames, flags *CheckFlags) (checkResult *CheckResult) { if !throttler.IsRunning() { return okMetricCheckResult From 8c204835af4da80afacf75b51fb7c43ab02e7d04 Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Thu, 11 Jul 2024 15:36:50 +0300 Subject: [PATCH 19/20] adding missing files Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- .../throttle/base/tablet_results.go | 99 +++++++++ .../throttle/base/tablet_results_test.go | 199 ++++++++++++++++++ 2 files changed, 298 insertions(+) create mode 100644 go/vt/vttablet/tabletserver/throttle/base/tablet_results.go create mode 100644 go/vt/vttablet/tabletserver/throttle/base/tablet_results_test.go diff --git a/go/vt/vttablet/tabletserver/throttle/base/tablet_results.go b/go/vt/vttablet/tabletserver/throttle/base/tablet_results.go new file mode 100644 index 00000000000..88e958e884e --- /dev/null +++ b/go/vt/vttablet/tabletserver/throttle/base/tablet_results.go @@ -0,0 +1,99 @@ +/* +Copyright 2023 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package base + +import "sort" + +// TabletResultMap maps a tablet to a result +type TabletResultMap map[string]MetricResultMap + +func (m TabletResultMap) Split(alias string) (withAlias TabletResultMap, all TabletResultMap) { + withAlias = make(TabletResultMap) + if val, ok := m[alias]; ok { + withAlias[alias] = val + } + return withAlias, m +} + +func AggregateTabletMetricResults( + metricName MetricName, + tabletResultsMap TabletResultMap, + ignoreHostsCount int, + IgnoreDialTCPErrors bool, + ignoreHostsThreshold float64, +) (worstMetric MetricResult) { + // probes is known not to change. It can be *replaced*, but not changed. + // so it's safe to iterate it + probeValues := []float64{} + for _, tabletMetricResults := range tabletResultsMap { + tabletMetricResult, ok := tabletMetricResults[metricName] + if !ok { + return NoSuchMetric + } + if tabletMetricResult == nil { + return NoMetricResultYet + } + value, err := tabletMetricResult.Get() + if err != nil { + if IgnoreDialTCPErrors && IsDialTCPError(err) { + continue + } + if ignoreHostsCount > 0 { + // ok to skip this error + ignoreHostsCount = ignoreHostsCount - 1 + continue + } + return tabletMetricResult + } + + // No error + probeValues = append(probeValues, value) + } + if len(probeValues) == 0 { + return NoHostsMetricResult + } + + // If we got here, that means no errors (or good-to-skip errors) + sort.Float64s(probeValues) + // probeValues sorted ascending (from best, ie smallest, to worst, ie largest) + for ignoreHostsCount > 0 { + goodToIgnore := func() bool { + // Note that these hosts don't have errors + numProbeValues := len(probeValues) + if numProbeValues <= 1 { + // We wish to retain at least one host + return false + } + if ignoreHostsThreshold <= 0 { + // No threshold conditional (or implicitly "any value exceeds the threshold") + return true + } + if worstValue := probeValues[numProbeValues-1]; worstValue > ignoreHostsThreshold { + return true + } + return false + }() + if goodToIgnore { + probeValues = probeValues[0 : len(probeValues)-1] + } + // And, whether ignored or not, we are reducing our tokens + ignoreHostsCount = ignoreHostsCount - 1 + } + worstValue := probeValues[len(probeValues)-1] + worstMetric = NewSimpleMetricResult(worstValue) + return worstMetric +} diff --git a/go/vt/vttablet/tabletserver/throttle/base/tablet_results_test.go b/go/vt/vttablet/tabletserver/throttle/base/tablet_results_test.go new file mode 100644 index 00000000000..0cf953700e8 --- /dev/null +++ b/go/vt/vttablet/tabletserver/throttle/base/tablet_results_test.go @@ -0,0 +1,199 @@ +/* +Copyright 2023 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package base + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +var ( + alias1 = "zone1-0001" + alias2 = "zone1-0002" + alias3 = "zone1-0003" + alias4 = "zone1-0004" + alias5 = "zone1-0005" +) + +const ( + nonexistentMetricName MetricName = "nonexistent" +) + +func newMetricResultMap(val float64) MetricResultMap { + return MetricResultMap{ + DefaultMetricName: NewSimpleMetricResult(val), + LagMetricName: NewSimpleMetricResult(val), + LoadAvgMetricName: NewSimpleMetricResult(3.14), + } +} +func noSuchMetricMap() MetricResultMap { + result := make(MetricResultMap) + for _, metricName := range KnownMetricNames { + result[metricName] = NoSuchMetric + } + return result +} + +func TestAggregateTabletMetricResultsNoErrors(t *testing.T) { + tabletResultsMap := TabletResultMap{ + alias1: newMetricResultMap(1.2), + alias2: newMetricResultMap(1.7), + alias3: newMetricResultMap(0.3), + alias4: newMetricResultMap(0.6), + alias5: newMetricResultMap(1.1), + } + + { + worstMetric := AggregateTabletMetricResults(DefaultMetricName, tabletResultsMap, 0, false, 0) + value, err := worstMetric.Get() + assert.NoError(t, err) + assert.Equal(t, value, 1.7) + } + { + worstMetric := AggregateTabletMetricResults(DefaultMetricName, tabletResultsMap, 1, false, 0) + value, err := worstMetric.Get() + assert.NoError(t, err) + assert.Equal(t, value, 1.2) + } + { + worstMetric := AggregateTabletMetricResults(DefaultMetricName, tabletResultsMap, 2, false, 0) + value, err := worstMetric.Get() + assert.NoError(t, err) + assert.Equal(t, value, 1.1) + } + { + worstMetric := AggregateTabletMetricResults(DefaultMetricName, tabletResultsMap, 3, false, 0) + value, err := worstMetric.Get() + assert.NoError(t, err) + assert.Equal(t, value, 0.6) + } + { + worstMetric := AggregateTabletMetricResults(DefaultMetricName, tabletResultsMap, 4, false, 0) + value, err := worstMetric.Get() + assert.NoError(t, err) + assert.Equal(t, value, 0.3) + } + { + worstMetric := AggregateTabletMetricResults(DefaultMetricName, tabletResultsMap, 5, false, 0) + value, err := worstMetric.Get() + assert.NoError(t, err) + assert.Equal(t, value, 0.3) + } +} + +func TestAggregateTabletMetricResultsNoErrorsIgnoreHostsThreshold(t *testing.T) { + tabletResultsMap := TabletResultMap{ + alias1: newMetricResultMap(1.2), + alias2: newMetricResultMap(1.7), + alias3: newMetricResultMap(0.3), + alias4: newMetricResultMap(0.6), + alias5: newMetricResultMap(1.1), + } + + { + worstMetric := AggregateTabletMetricResults(DefaultMetricName, tabletResultsMap, 0, false, 1.0) + value, err := worstMetric.Get() + assert.NoError(t, err) + assert.Equal(t, value, 1.7) + } + { + worstMetric := AggregateTabletMetricResults(DefaultMetricName, tabletResultsMap, 1, false, 1.0) + value, err := worstMetric.Get() + assert.NoError(t, err) + assert.Equal(t, value, 1.2) + } + { + worstMetric := AggregateTabletMetricResults(DefaultMetricName, tabletResultsMap, 2, false, 1.0) + value, err := worstMetric.Get() + assert.NoError(t, err) + assert.Equal(t, value, 1.1) + } + { + worstMetric := AggregateTabletMetricResults(DefaultMetricName, tabletResultsMap, 3, false, 1.0) + value, err := worstMetric.Get() + assert.NoError(t, err) + assert.Equal(t, value, 0.6) + } + { + worstMetric := AggregateTabletMetricResults(DefaultMetricName, tabletResultsMap, 4, false, 1.0) + value, err := worstMetric.Get() + assert.NoError(t, err) + assert.Equal(t, value, 0.6) + } + { + worstMetric := AggregateTabletMetricResults(DefaultMetricName, tabletResultsMap, 5, false, 1.0) + value, err := worstMetric.Get() + assert.NoError(t, err) + assert.Equal(t, value, 0.6) + } +} + +func TestAggregateTabletMetricResultsWithErrors(t *testing.T) { + tabletResultsMap := TabletResultMap{ + alias1: newMetricResultMap(1.2), + alias2: newMetricResultMap(1.7), + alias3: newMetricResultMap(0.3), + alias4: noSuchMetricMap(), + alias5: newMetricResultMap(1.1), + } + + t.Run("nonexistent", func(t *testing.T) { + worstMetric := AggregateTabletMetricResults(nonexistentMetricName, tabletResultsMap, 0, false, 0) + _, err := worstMetric.Get() + assert.Error(t, err) + assert.Equal(t, ErrNoSuchMetric, err) + }) + t.Run("no ignore", func(t *testing.T) { + worstMetric := AggregateTabletMetricResults(DefaultMetricName, tabletResultsMap, 0, false, 0) + _, err := worstMetric.Get() + assert.Error(t, err) + assert.Equal(t, ErrNoSuchMetric, err) + }) + t.Run("ignore 1", func(t *testing.T) { + worstMetric := AggregateTabletMetricResults(DefaultMetricName, tabletResultsMap, 1, false, 0) + value, err := worstMetric.Get() + assert.NoError(t, err) + assert.Equal(t, 1.7, value) + }) + t.Run("ignore 2", func(t *testing.T) { + worstMetric := AggregateTabletMetricResults(DefaultMetricName, tabletResultsMap, 2, false, 0) + value, err := worstMetric.Get() + assert.NoError(t, err) + assert.Equal(t, 1.2, value) + }) + + tabletResultsMap[alias1][DefaultMetricName] = NoSuchMetric + t.Run("no such metric", func(t *testing.T) { + worstMetric := AggregateTabletMetricResults(DefaultMetricName, tabletResultsMap, 0, false, 0) + _, err := worstMetric.Get() + assert.Error(t, err) + assert.Equal(t, ErrNoSuchMetric, err) + }) + t.Run("no such metric, ignore 1", func(t *testing.T) { + worstMetric := AggregateTabletMetricResults(DefaultMetricName, tabletResultsMap, 1, false, 0) + _, err := worstMetric.Get() + assert.Error(t, err) + assert.Equal(t, ErrNoSuchMetric, err) + }) + t.Run("metric found", func(t *testing.T) { + worstMetric := AggregateTabletMetricResults(DefaultMetricName, tabletResultsMap, 2, false, 0) + value, err := worstMetric.Get() + assert.NoError(t, err) + assert.Equal(t, value, 1.7) + }) +} From a8eeea748a1c62baff9072436a172f35b3b7f523 Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Mon, 15 Jul 2024 07:55:51 +0300 Subject: [PATCH 20/20] update copyright year Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- .../vttablet/tabletserver/throttle/base/tablet_results_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go/vt/vttablet/tabletserver/throttle/base/tablet_results_test.go b/go/vt/vttablet/tabletserver/throttle/base/tablet_results_test.go index 0cf953700e8..98888eebbb8 100644 --- a/go/vt/vttablet/tabletserver/throttle/base/tablet_results_test.go +++ b/go/vt/vttablet/tabletserver/throttle/base/tablet_results_test.go @@ -1,5 +1,5 @@ /* -Copyright 2023 The Vitess Authors. +Copyright 2024 The Vitess Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.