import json import click from loguru import logger from controller.collectors import * from controller.types import * from controller.installers import * from tuner import RuleTuner CONTEXT_SETTINGS = dict(help_option_names=['-h', '--help']) @click.command(context_settings=CONTEXT_SETTINGS) @click.option("-c", "--config", type=str, required=True, help="Controller configuration file") @click.option("-d", "--directory", type=str, default="output", help="Base directory for the result files, default is 'output'") @click.option("-t", "--tune_type", type=str, default="rule", help="Tuner algorithm type") def auto_tuning(**args): logger.info("Experiment output directory is set to: '%s'" % args["directory"]) try: # parse controller configuration with open(args["config"], "r") as fr: config_str = fr.read() if not JsonSchemaType.is_valid_json(JsonSchemaType.CONFIG, config_str): raise RuntimeError("Controller config is invalid") controller_config = json.loads(config_str) # collect metrics and parameters before experiment collector = get_collector(controller_config) logger.info("Collect metrics before experiment") before_metrics = collector.collect_metrics() if not JsonSchemaType.is_valid_json(JsonSchemaType.OUTPUT, before_metrics): raise RuntimeError("Metrics output is invalid") logger.info("Collect parameters before experiment") before_parameters = collector.collect_parameters() if not JsonSchemaType.is_valid_json(JsonSchemaType.OUTPUT, before_parameters): raise RuntimeError("Parameters output is invalid") # run the tuner logger.info("Starting the experiment ...") instances = collector.collect_component_instances() tuner = get_tuner(args["tune_type"], instances) recommendation_parameters = tuner.tune() installer = get_parameters_installer(args["config"], controller_config) installer.change_conf(recommendation_parameters) logger.info("Done running the experiment") # collect metrics and parameters after experiment collector = get_collector(controller_config) logger.info("Collect metrics after experiment") after_metrics = collector.collect_metrics() if not JsonSchemaType.is_valid_json(JsonSchemaType.OUTPUT, after_metrics): raise RuntimeError("Metrics output is invalid") logger.info("Collect parameters after experiment") after_parameters = collector.collect_parameters() if not JsonSchemaType.is_valid_json(JsonSchemaType.OUTPUT, after_parameters): raise RuntimeError("Parameters output is invalid") except Exception as e: logger.error(e) def get_tuner(tune_type, instances): if tune_type == "rule": return RuleTuner(instances) else: raise RuntimeError("Invalid tune type error") def get_parameters_installer(config_file, config): db_type = config["database_type"] if db_type == "tidb": return TiDBInstaller(config_file, config) elif db_type == "mysql": return MysqlInstaller(config_file, config) else: raise RuntimeError("Invalid database type error") def get_collector(config): db_type = config["database_type"] db_url = config["database_url"] username = config["username"] password = config["password"] if db_type == "tidb": return TiDBCollector(db_url, username, password) elif db_type == "mysql": return MysqlCollector(db_url, username, password) else: raise RuntimeError("Invalid database type error") if __name__ == "__main__": auto_tuning()