vitess.io/vitess@v0.16.2/go/vt/throttler/max_replication_lag_module_config.go (about)

     1  /*
     2  Copyright 2019 The Vitess Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package throttler
    18  
    19  import (
    20  	"fmt"
    21  	"time"
    22  
    23  	"google.golang.org/protobuf/proto"
    24  
    25  	throttlerdatapb "vitess.io/vitess/go/vt/proto/throttlerdata"
    26  )
    27  
    28  // MaxReplicationLagModuleConfig stores all configuration parameters for
    29  // MaxReplicationLagModule. Internally, the parameters are represented by a
    30  // protobuf message. This message is also used to update the parameters.
    31  type MaxReplicationLagModuleConfig struct {
    32  	*throttlerdatapb.Configuration
    33  }
    34  
    35  func (cfg MaxReplicationLagModuleConfig) Clone() MaxReplicationLagModuleConfig {
    36  	return MaxReplicationLagModuleConfig{
    37  		proto.Clone(cfg.Configuration).(*throttlerdatapb.Configuration),
    38  	}
    39  }
    40  
    41  // Most of the values are based on the assumption that vttablet is started
    42  // with the flag --health_check_interval=20s.
    43  const healthCheckInterval = 20
    44  
    45  var defaultMaxReplicationLagModuleConfig = MaxReplicationLagModuleConfig{
    46  	&throttlerdatapb.Configuration{
    47  		TargetReplicationLagSec: 2,
    48  		MaxReplicationLagSec:    ReplicationLagModuleDisabled,
    49  
    50  		InitialRate: 100,
    51  		// 1 means 100% i.e. double rates by default.
    52  		MaxIncrease:       1,
    53  		EmergencyDecrease: 0.5,
    54  
    55  		// Wait for two health broadcast rounds. Otherwise, the "decrease" mode
    56  		// has less than 2 lag records available to calculate the actual replication rate.
    57  		MinDurationBetweenIncreasesSec: 2 * healthCheckInterval,
    58  		// MaxDurationBetweenIncreasesSec defaults to 60+2 seconds because this
    59  		// corresponds to 3 broadcasts.
    60  		// The 2 extra seconds give us headroom to account for delay in the process.
    61  		MaxDurationBetweenIncreasesSec: 3*healthCheckInterval + 2,
    62  		MinDurationBetweenDecreasesSec: healthCheckInterval,
    63  		SpreadBacklogAcrossSec:         healthCheckInterval,
    64  
    65  		AgeBadRateAfterSec:       3 * 60,
    66  		BadRateIncrease:          0.10,
    67  		MaxRateApproachThreshold: 0.90,
    68  	},
    69  }
    70  
    71  // DefaultMaxReplicationLagModuleConfig returns a copy of the default config object.
    72  func DefaultMaxReplicationLagModuleConfig() MaxReplicationLagModuleConfig {
    73  	return defaultMaxReplicationLagModuleConfig.Clone()
    74  }
    75  
    76  // NewMaxReplicationLagModuleConfig returns a default configuration where
    77  // only "maxReplicationLag" is set.
    78  func NewMaxReplicationLagModuleConfig(maxReplicationLag int64) MaxReplicationLagModuleConfig {
    79  	config := defaultMaxReplicationLagModuleConfig.Clone()
    80  	config.MaxReplicationLagSec = maxReplicationLag
    81  	return config
    82  }
    83  
    84  // TODO(mberlin): Add method which updates the config using a (partially) filled
    85  // in protobuf.
    86  
    87  // Verify returns an error if the config is invalid.
    88  func (cfg MaxReplicationLagModuleConfig) Verify() error {
    89  	if cfg.TargetReplicationLagSec < 1 {
    90  		return fmt.Errorf("target_replication_lag_sec must be >= 1")
    91  	}
    92  	if cfg.MaxReplicationLagSec < 2 {
    93  		return fmt.Errorf("max_replication_lag_sec must be >= 2")
    94  	}
    95  	if cfg.TargetReplicationLagSec > cfg.MaxReplicationLagSec {
    96  		return fmt.Errorf("target_replication_lag_sec must not be higher than max_replication_lag_sec: invalid: %v > %v",
    97  			cfg.TargetReplicationLagSec, cfg.MaxReplicationLagSec)
    98  	}
    99  	if cfg.InitialRate < 1 {
   100  		return fmt.Errorf("initial_rate must be >= 1")
   101  	}
   102  	if cfg.MaxIncrease <= 0 {
   103  		return fmt.Errorf("max_increase must be > 0")
   104  	}
   105  	if cfg.EmergencyDecrease <= 0 {
   106  		return fmt.Errorf("emergency_decrease must be > 0")
   107  	}
   108  	if cfg.MinDurationBetweenIncreasesSec < 1 {
   109  		return fmt.Errorf("min_duration_between_increases_sec must be >= 1")
   110  	}
   111  	if cfg.MaxDurationBetweenIncreasesSec < 1 {
   112  		return fmt.Errorf("max_duration_between_increases_sec must be >= 1")
   113  	}
   114  	if cfg.MinDurationBetweenDecreasesSec < 1 {
   115  		return fmt.Errorf("min_duration_between_decreases_sec must be >= 1")
   116  	}
   117  	if cfg.SpreadBacklogAcrossSec < 1 {
   118  		return fmt.Errorf("spread_backlog_across_sec must be >= 1")
   119  	}
   120  	if cfg.IgnoreNSlowestReplicas < 0 {
   121  		return fmt.Errorf("ignore_n_slowest_replicas must be >= 0")
   122  	}
   123  	if cfg.IgnoreNSlowestRdonlys < 0 {
   124  		return fmt.Errorf("ignore_n_slowest_rdonlys must be >= 0")
   125  	}
   126  	if cfg.AgeBadRateAfterSec < 1 {
   127  		return fmt.Errorf("age_bad_rate_after_sec must be >= 1")
   128  	}
   129  	if cfg.MaxRateApproachThreshold < 0 {
   130  		return fmt.Errorf("max_rate_approach_threshold must be >=0")
   131  	}
   132  	if cfg.MaxRateApproachThreshold > 1 {
   133  		return fmt.Errorf("max_rate_approach_threshold must be <=1")
   134  	}
   135  	return nil
   136  }
   137  
   138  // MinDurationBetweenIncreases is a helper function which returns the respective
   139  // protobuf field as native Go type.
   140  func (cfg MaxReplicationLagModuleConfig) MinDurationBetweenIncreases() time.Duration {
   141  	return time.Duration(cfg.MinDurationBetweenIncreasesSec) * time.Second
   142  }
   143  
   144  // MaxDurationBetweenIncreases is a helper function which returns the respective
   145  // protobuf field as native Go type.
   146  func (cfg MaxReplicationLagModuleConfig) MaxDurationBetweenIncreases() time.Duration {
   147  	return time.Duration(cfg.MaxDurationBetweenIncreasesSec) * time.Second
   148  }
   149  
   150  // MinDurationBetweenDecreases is a helper function which returns the respective
   151  // protobuf field as native Go type.
   152  func (cfg MaxReplicationLagModuleConfig) MinDurationBetweenDecreases() time.Duration {
   153  	return time.Duration(cfg.MinDurationBetweenDecreasesSec) * time.Second
   154  }
   155  
   156  // SpreadBacklogAcross is a helper function which returns the respective
   157  // protobuf field as native Go type.
   158  func (cfg MaxReplicationLagModuleConfig) SpreadBacklogAcross() time.Duration {
   159  	return time.Duration(cfg.SpreadBacklogAcrossSec) * time.Second
   160  }
   161  
   162  // AgeBadRateAfter is a helper function which returns the respective
   163  // protobuf field as native Go type.
   164  func (cfg MaxReplicationLagModuleConfig) AgeBadRateAfter() time.Duration {
   165  	return time.Duration(cfg.AgeBadRateAfterSec) * time.Second
   166  }