文章摘要
文章介绍了通过逆向工程GitHub Actions缓存机制,成功将缓存请求透明地路由到更快的本地缓存系统,从而在不修改代码或维护上游分支的情况下,为部分客户带来了高达10倍的缓存性能提升。这一改进解决了之前维护分支的高成本和用户体验问题。
文章总结
标题:通过逆向工程优化GitHub Actions缓存速度 | Blacksmith
主要内容:
Blacksmith团队通过逆向工程GitHub Actions缓存的内部机制,成功将缓存请求透明地路由到他们更快的、本地化的缓存系统中,从而为部分客户带来了高达10倍的缓存性能提升。这一改进无需用户更改代码,也无需维护上游Actions的分支。
在开始这项工作之前,Blacksmith已经拥有一个比GitHub Actions缓存更快的替代方案。他们的方法是通过分叉每个依赖Actions缓存的流行第一方Actions,将其指向他们的本地化缓存。然而,这种方法需要用户更改一行代码,且维护这些分叉逐渐变得繁琐,最终导致操作成本过高。
为了解决这些问题,团队决定逆向工程GitHub Actions缓存本身,目标是使其变得更快,且无需维护分叉或要求用户更改代码。他们首先深入了解了GitHub Actions缓存的内部工作原理,并利用新的Twirp服务(基于Azure Blob Storage SDK)进行了重新设计。通过使用Claude(一种LLM工具),他们成功解析了GitHub的控制平面请求,并生成了Actions服务的proto定义。
由于GitHub系统转向了Azure Blob Storage,而Blacksmith的缓存后端运行在自托管的MinIO集群上(兼容S3的Blob存储),团队需要解决请求格式的差异。他们通过配置轻量级的NGINX服务器在虚拟机(VM)内部代理请求,确保缓存相关请求被重定向到他们的主机代理,而其他GitHub控制平面请求则直接发送到其通常目的地。
为了与Azure SDK兼容,团队进行了内核级别的网络调整,并构建了自己的Azure-like URL,通过主机代理将其转换为S3兼容的端点。他们还使用了nftables(Linux上的新标准包过滤工具)来管理每个VM的规则,确保相关请求通过主机代理流动。
最终,Blacksmith的本地化缓存系统显著提升了客户工作流的缓存速度,且无需更改工作流文件中的代码。通过这一系列优化,Blacksmith成功实现了缓存性能的显著提升,为客户带来了更高效的CI体验。
评论总结
关于GitHub Actions的缓存和工具改进:
- 一些开发者通过外部工具(如Blacksmith、Depot等)来优化GitHub Actions的缓存和性能,但有人认为这种分叉生态系统的做法并非长期解决方案。
- "Forking the ecosystem of actions to plug in your cache backed isn’t a good long term solution."(kylegalbraith)
- "It's pretty amazing to see what Blacksmith, Depot, Actuated, etc. have been able to build on top of GitHub Actions."(tagraves)
- 一些开发者通过外部工具(如Blacksmith、Depot等)来优化GitHub Actions的缓存和性能,但有人认为这种分叉生态系统的做法并非长期解决方案。
关于CI/CD复杂性的讨论:
- 有开发者认为复杂的CI/CD流程可以通过简化技术栈来避免,例如使用容器和托管服务。
- "I am struggling with justification for CI/CD pipelines that are so complex this kind of additional tooling becomes necessary."(bob1029)
- "The use of containers and hosted SQL where neither are required can instantly 10x+ the complexity of deploying your software."(bob1029)
- 有开发者认为复杂的CI/CD流程可以通过简化技术栈来避免,例如使用容器和托管服务。
关于iptables和Docker的挑战:
- 使用iptables和Docker时,开发者遇到了规则管理复杂性和并发问题,最终导致项目被放弃。
- "Iptables was VERY fragile. Aside from the fact it didn't even have a stable programmatic interface, it was also a race condition nightmare."(junon)
- "Docker itself had a slew of ridiculous behavior, we ended up scratching the project."(junon)
- 使用iptables和Docker时,开发者遇到了规则管理复杂性和并发问题,最终导致项目被放弃。
关于GitHub Actions Cache的技术细节:
- GitHub Actions Cache的V2版本基于Azure Blob Storage,开发者通过逆向工程实现了对新API的支持。
- "The new service is a TWIRP-based system where you directly store things into Azure using signed URLs from the TWIRP side."(jchw)
- "I used append blobs instead of block blobs. Why? ... Because it was simpler."(jchw)
- GitHub Actions Cache的V2版本基于Azure Blob Storage,开发者通过逆向工程实现了对新API的支持。
关于缓存性能的优化:
- 缓存性能在不同提供商之间存在差异,GitHub Actions Cache V2在GitHub管理的runner上表现良好。
- "GitHub Actions Cache v2 is actually very good in terms of download/upload speed right now, when running from GitHub managed runners."(crohr)
- "The low speed Blacksmith was seeing before is just due to their slow (Hetzner?) network."(crohr)
- 缓存性能在不同提供商之间存在差异,GitHub Actions Cache V2在GitHub管理的runner上表现良好。
关于容器化CI/CD的最佳实践:
- 使用容器化技术可以显著提升CI/CD的性能,建议通过预构建的容器镜像来减少依赖安装时间。
- "Perf: don't use 'install X' tasks. Create a container image with all your deps and use that instead."(zamalek)
- "Our CI builds are stupid fast. Comparatively speaking."(zamalek)
- 使用容器化技术可以显著提升CI/CD的性能,建议通过预构建的容器镜像来减少依赖安装时间。
总结:评论中讨论了GitHub Actions的缓存优化、CI/CD流程的简化、iptables和Docker的挑战、GitHub Actions Cache的技术细节、缓存性能的优化以及容器化CI/CD的最佳实践。开发者们提出了不同的解决方案和优化建议,反映了在实际应用中遇到的各种技术挑战和应对策略。