任务启动过程调用关系简化
2020-09-21 本文已影响0人
王勇1024
背景
两年前入职公司的时候,我们的机器学习任务都是启动在Mesos集群上,当时使用的训练框架还是ps-lite。一个ps-lite训练任务包含两部分:
- 多个worker任务负责执行机器学习任务
- 一个scheduler任务负责协调worker任务的执行进度
历史遗留问题
之前负责机器学习平台的员工的做法是(往下翻有流程图):
- 先用一个脚本 run_scheduler.sh 启动 scheduler 任务
- 在 run_scheduler.sh 中再执行 run_sworker 方法调用 Marathon 的接口来启动多个 worker 任务
- 同时在 scheduler 和 worker 任务中还分别启动一个监听进程,来监听自身及其他任务的健康状态
- 当 scheduler 发现有 worker 任务存在异常时,需要调用 Marathon 的接口把所有 worker 任务重启,再调用 report 脚本发送报警信息
- 当 worker 发现 scheduler 任务存在异常时,需要调用 Marathon 的接口把 scheduler 任务重启,再调用 report 脚本发送报警信息
流程虽然能走通,但这个设计给我们后来的维护和扩展带来的很多困扰:
- 1.scheduler重启worker,或者worker 重启 scheduler的脚本强依赖 Marathon,无法直接升级到 K8s
- 2.报警的逻辑及报警接收人是在脚本里写死的,人员发生变动时修改非常麻烦
- 3.scheduler 和 worker 做了太多与训练无关的工作,比如健康检查、指标监控、报警、重启任务等,导致启动脚本非常的复杂难以理解
- 4.指标上报的逻辑也是写死在脚本里的,依赖的指标服务下线后,指标上报功能就无法使用了
- 6.如果监控进程挂掉了,是无法发现训练进程异常的
更糟糕的情况
这还不是最糟糕的情况!随着技术的变更升级,Mesos+Marathon 组合所用的技术越来越落后,K8s霸主的地位越来越稳固,我们决定用K8s替代 Mesos+Marathon 组合。
当时负责机器学习平台的老员工gy “设计”(假如这也算设计)了在K8s上启动 ps-lite任务的流程,具体流程我也不想用过多的语言描述了,流程图画出来了,光看下面的图相信大家就能了解有多复杂。
看到如此“思路清奇”的启动流程,我也是无语。
重新设计
看到上面那么复杂的调用流程,我无论如何也不能让它变成现实,否则就是我以后工作的一个噩梦呀。于是我果断制止了gy正在写脚本的手指,重新设计了下图的调用流程。
- 简化 run_scheduler 和 run_sworker 两个脚本,只分别负责启动 scheduler 和 worker
- alpha-exptmgr 负责对 scheduler 和 worker 的启停管理
- alpha-monitor 负责对所有任务的健康监控、报警等工作,如果发现任务异常,则通知 alpha-exptmgr 重启任务
这样各个模块的职能都比较简单、清晰,扩展和维护起来也非常方便,并且alpha-monitor部署了多个实例,可以保证4个9的稳定性,不必担心挂掉后无法及时发现训练任务异常。
简化后的调用关系gy看到我的设计后很是不爽(工作中夹杂了太多个人感情),不论好坏就是不想采用。多次沟通失败后,我只好拉上领导一起开会讨论。领导如此聪明,自然一眼就看明白了,于是果断支持我的方案。后来时间也证明我的方案是对的。
总结
- 写代码是最不着急的事,一定要先做好方案设计,没有设计的代码就是没有导航的汽车
- 遇到自己无法解决的问题,要求助领导帮忙解决