openGauss源码解析(158)
openGauss源码解析:AI技术(5)
2. 总体流程解析
入口总体流程在main.py中给出,main函数的核心代码如下:
def main():
…
# 通过命令行参数或连接信息文件构建db_info字典,利用该字典中的信息可以登录到数据库实例和宿主机上
db_info = build_db_info(args)
if not db_info:
parser.print_usage()
return -1
# 解析配置文件中给定的配置项
config = get_config(args.tuner_config_file)
if not config:
return -1
try:
# 当获取到足够的信息后,进入工具的执行流程
return procedure_main(mode, db_info, config)
except Exception as e:
logging.exception(e)
print('FATAL: An exception occurs during program running. '
'The exception information is "%s". '
'For details about the error cause, please see %s.' % (e, config['logfile']),
file=sys.stderr, flush=True)
return -1
可以看到main函数主要是做一些参数、命令行的校验、收集工作,核心流程定义在xtuner.py的procedure_main函数中,该函数的核心代码如下:
def procedure_main(mode, db_info, config):
# 权限最小化
os.umask(0o0077)
# 初始化日志模块
set_logger(config['logfile'])
logging.info('Starting... (mode: %s)', mode)
# 利用new_db_agent函数构造DB_Agent对象,该对象是唯一对数据库操作进行封装的对象
db_agent = new_db_agent(db_info)
# 如果用户没有通过配置文件指定负载类型,则通过预定义的算法或规则进行自动判断
if config['scenario'] in WORKLOAD_TYPE.TYPES:
db_agent.metric.set_scenario(config['scenario'])
else:
config['scenario'] = db_agent.metric.workload_type
# 同上,如果用户设置为自动模式,则使用下述默认规则补充
if config['tune_strategy'] == 'auto':
# If more iterations are allowed, reinforcement learning is preferred.
if config['rl_steps'] * config['max_episode_steps'] > 1500:
config['tune_strategy'] = 'rl'
else:
config['tune_strategy'] = 'gop'
logging.info("Configurations: %s.", config)
# 如果在配置文件中指定了tuning_list配置项,并且非reocmmend模式,则加载该待调优参数列表的配置文件,否则通过recommend_knobs函数智能获取待调优参数列表
if config['tuning_list'].strip() != '' and mode != 'recommend':
knobs = load_knobs_from_json_file(config['tuning_list'])
else:
print("Start to recommend knobs. Just a moment, please.")
knobs = recommend_knobs(mode, db_agent.metric)
if not knobs:
logging.fatal('No recommended best_knobs for the database. Stop the execution.')
return -1
# 如果是调优和训练模式,由于某些数据库参数是需要重启后才生效的,因此可能会伴随着反复的重启过程
if mode != 'recommend': # 不为recommend模式,就只能是tune或者train模式,而这两种模式都是离线过程,需要反复迭代
prompt_restart_risks() # 告知用户调优过程中有数据库重启的风险
# 初始化调优中的记录类
recorder = Recorder(config['recorder_file'])
# 分别读取配置文件中的三个配置项:benchmark_script、benchmark_path以及benchmark_cmd,通过这三个配置项就可以获取到benchmark驱动脚本的实例,可以用它来衡量数据库的性能
bm = benchmark.get_benchmark_instance(config['benchmark_script'],
config['benchmark_path'],
config['benchmark_cmd'],
db_info)
# 初始化数据库调优环境实例,该对象封装了迭代过程,保持与强化学习库gym.Env的接口一致
env = DB_Env(db_agent, benchmark=bm, recorder=recorder,
drop_cache=config['drop_cache'],
mem_penalty=config['used_mem_penalty_term'])
env.set_tuning_knobs(knobs)
# 识别不同的模式,不同模式执行对应的子程序
if mode == 'train':
rl_model('train', env, config)
elif mode == 'tune':
…
# 执行到此处时,已经完成调优过程。下述代码负责将调优结果输出
knobs.output_formatted_knobs()
if config['output_tuning_result'] != '':
with open(config['output_tuning_result'], 'w+') as fp:
# train模式是强化学习独有的模式,在该模式下,只输出调优参数,不输出报告参数(建议参数)。这是因为,在强化学习的tune模式下,待调优参数列表应当与train模式下保存的调优列表需要完全相同,即调优参数名相同、调优范围相同、各个参数的顺序相同,否则会导致输入特征不符合。
knobs.dump(fp, dump_report_knobs=mode != 'train')
logging.info('X-Tuner is executed and ready to exit. '
'Please refer to the log for details of the execution process.')
return 0
综上,调优程序是一个独立于数据库内核之外的工具,需要提供数据库及其所在实例的用户名和登录密码信息,以便控制数据库执行benchmark进行性能测试;在启动调优程序前,要求用户测试环境交互正常,能够正常跑通benchmark测试脚本、能够正常连接数据库。