5

CI 的根本性问题

 1 year ago
source link: https://www.zenlife.tk/why-ci-slow.md
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

CI 的根本性问题

2023-04-23

TiDB 的 CI 已经慢到快无药可救了。平均合入一个 PR 需要 1 个小时以上,一天合 10 多个 PR 进去,这个速度差不多跟不上每天提 PR 的速度。 主要原因是跑测试特别慢,tidb repo 的单测要跑半个多小时,失败率还贼高,不停失败不停重试。

有个同事提到,是不是可以在本地跑测试,减轻 CI 系统的压力?然后我就想了一想,在本地跑完测试,CI 那边只需要验证本地执行的结果。 这里涉及的只有两个点,一个是统一化的执行环境,另一个是防作弊。前者可以通过 docker 环境搞定,而后者对处理过程做一下单向的 hash,让伪造测试结果的代价大于跑一遍测试就行。

于是和负责 CI 那边的同事讨论了一下,才发现把问题想简单了。CI 的根本性问题,是这套系统本质是一个串行化操作,导致它只能"纵向扩容",无法"横向扩容"。

我们可以把仓库的代码合入的过程,看作是一个事务的原子化操作,commit log 就是持久化的状态。然后呢,同时有非常多的并发 PR,每个 PR 代表一个操作,是对事务状态的修改。 这个过程是原子化的,即是说,每一个 PR 都是想把事务从一个状态修改到另一个状态,这其中只有一个能成功,一旦成功之后,剩下的 PR 全部得 rebase master,重试,这个就相当于事务冲突。

相当于高并发 CAS 操作,CPU 做 CAS 操作很快,但是我们的 CI 做这个事情很慢。 因为只有跑过了测试,PR才能合并。跑测试很半,跑一次半个多小时,只要有一个PR合并了,那剩下的 PR 就得重跑测试。因为它是基于旧的 commit hash,合掉这个 PR,跑测试能成功,不代表基于最新的 commit hash,跑测试能成功。

"跑测试通过"这个执行信息是有时效性的,只要仓库有新的提交,这个信息就无效化了。这也就是为什么只在本地跑测试不可行。 本地跑了半个小时,结果这期间有 PR 合入,那么这个执行结果就白白浪费掉了。只有中心化的 CI 环境,能够知道这样的变化信息,维护 CI 的自动化执行。

于是就只能 "纵向扩容",无法"横向扩容" 了。纵向扩容可以让 CI 的集群机器配置更高,中心化地分配测试地执行过程,比如让测试 3min 以内能跑完,就可以加速 CI 的体验了。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK