在 之前的文章中,我介绍了如何使用 GitHub Webhook 在 ClickHouse 中构建一个包含所有 GitHub Actions 数据的表。我们为 ClickHouse 组织执行此操作,以提供有关工作流作业内部队列的基本指标。
仅仅拥有这些数据而不做任何处理将会浪费宝贵的资源,因此几个月前,这些数据被用来实现一个 Lambda,可以根据需要快速扩展和收缩我们的工作者。这提高了我们作业启动的响应速度,对计划测试的增加做出了反应,并在工作量较低时为我们节省了计算资源。让我们讨论一下我们是如何实现这一点的!
想法
我们拥有工作流作业创建、启动或完成时所有事件的数据库记录。请考虑来自之前文章的这个查询,它返回了自管理 GitHub 运行器当前的 ClickHouse 队列大小。
SELECT last_status, count() AS queue, labels FROM ( SELECT argMax(status, updated_at) AS last_status, labels, id, html_url FROM default.workflow_jobs WHERE has(labels, 'self-hosted') AND (started_at > (now() - toIntervalHour(3))) GROUP BY ALL HAVING last_status != 'completed' ) GROUP BY ALL ORDER BY labels ASC, last_status ASC✎
了解这一点,我们可以主动地扩展运行器以满足需求,或者缩小规模以释放不必要的资源。
新的目标容量根据当前的运行器数量以及正在进行和排队的作业数来计算。如果有不足,我们会按比例增加容量(通常为不足 / 5)。对于不必要的预留,我们快速收缩组(预留 / 2)。
旧系统
AWS 中官方推荐的触发扩展/收缩的方法是将 CloudWatch 警报分配给自动扩展组 (ASG)。因此,只要警报处于警报状态,ASG 就会添加或移除一些实例。
我们过去使用 GitHub 运行器 API 监控每个 ASG 中有多少实例处于繁忙状态。如果超过 97% 的运行器处于繁忙状态超过 5 分钟,就会添加一个新的运行器。对于缩小规模,规则是低于 70%。
该系统反应迟缓,效率低下。对于包含 50 多个运行器的组,预热需要几个小时。
改进和统计数据
切换到新系统后,我们实现了更快的作业启动,并在作业完成后节省了计算时间。您可以从图表中看到它对运行器的影响。
旧系统
新系统
我们可以看到在新系统中繁忙运行器和活动运行器之间的相关性更高,表明已配置的工作者得到更充分的利用。此处使用的代码都可在 我们的仓库中找到。希望其他人也能做出类似的改进和节省!