云原生场景下实现编译加速
作者:京东零售 王雷
背景
云原生下的流水线是通过启动容器来运行具体的功能步骤,每次运行流水线可能会被调度到不同的计算节点上。这会导致一个问题:容器运行完是不会保存数据的,每当流水线重新运行时,又会重新拉取代码、编译代码、下载依赖包
等等。在云原生场景下,不存在本地宿主机编译代码、构建镜像时缓存的作用
,大大延长了流水线运行时间,浪费很多不必要的时间、网络和计算成本。
在许多流水线场景中,同一条流水线的多次执行之间是有关联的。如果能够用到上一次的执行结果,则可以大幅缩短执行时间。为了提高用户使用流水线的体验,我们加入支持缓存的功能,挂接远程储存管理构建缓存,可以实现同一个项目的编译依赖复用,在同一条流水线的多次运行中,共享同一份缓存。
目标
通过实现云原生流水线的缓存技术,实现代码编译的缓存复用,平均加速流水线3~5倍;
实现方案
我们将需要进行缓存的文件,使用zstd的方式进行压缩,通过远程挂载cfs,将构建的缓存持久化到cfs上的指定位置。当下一次构建开始的时候,判断缓存是否被命中,如果命中缓存,我们从cfs上的指定位置pull对应的缓存压缩包,解压到相应目录下。
所用工具-cfs+zstd
非用户自定义镜像,将需要的工具打到引擎的基础镜像中,作为所有镜像的基础工具。
用户自定义镜像,不和用户镜像进行强绑定,如果需要使用缓存功能,可以使用Restore缓存原子和Save缓存原子,设置缓存key和缓存目录,实现缓存功能。
1 cfs远程挂载
•将工具和启动脚本,配置文件打到基础镜像
•在开启缓存的位置,启动脚本,开始挂载cfs
_, err = c.ScriptAction.Sh([]string{ "sh", "-c", "modprobe fuse;cd /export/servers/tools/cfs;sudo ./cfs-client-randomwrite -c fuse.json", })
2 zstd压缩
针对现有的几种压缩方式进行了性能对比,最后选用了zstd进行压缩。
Zstd,全称 Zstandard,是 Facebook 于 2016 年开源的新无损压缩算法。Zstd 还可以以压缩速度为代价提供更强的压缩比,速度与压缩率的比重可通过增量进行配置。与 zlib、lz4、xz 等当前流行的压缩算法不同,Zstd 寻求一种压缩性能与压缩率通吃的方案,而实际上它也确实做到了。在由官方所列出的表格中,可以看到,Zstd 不仅具备优秀的压缩性能,在压缩率上也有非常亮眼的表现。在过去的两年里,Linux内核、HTTP协议、以及一系列的大数据工具(包括Hadoop 3.0.0,HBase 2.0.0,Spark 2.3.0,Kafka 2.1.0)等都已经加入了对zstd的支持。
常见的压缩算法性能对比:
压缩包大小对比:
依赖包的大小 | 465M | 压缩效率 |
---|---|---|
tar压缩 | 423M | 14s左右 |
zstd压缩 | 205M | 1s左右 |
缓存的实现
我们借鉴了github cache action,zadig,gitlab等缓存的处理方式,同时结合服务自身的特点
将整体分成三步
•检查是否命中缓存:根据缓存key,判断缓存是否命中
缓存key | 缓存的唯一标识 |
---|---|
不同语言编译原子 | 根据下载代码的代码库地址自动获取 设置的缓存key:home_auth/home-auth-center |
用户自定义镜像 | 自定义缓存key |
•pull缓存
当缓存命中后,根据缓存路径,找到挂载到cfs上的缓存压缩包,解压到指定的缓存目录下
•push缓存:将依赖包进行压缩,放到cfs的挂载目录下
依赖包的大小 | 465M |
---|---|
tar压缩 | 423M |
zstd压缩 | 205M |
缓存的使用限制和回收策略
使用限制
目前存储缓存数没有限制,存储库中所有缓存的总大小限制是根据申请的cfs的大小限制:20G。
回收策略
我们会删除7天内未被访问的任何缓存。利用etcd的watch机制,实现缓存的回收。
etcd可以Watch
指定的键、前缀目录的更改,并对更改时间进行通知。BASE引擎中,缓存的清除策略借助etcd来实现。
缓存过期策略:在编译加速的实现中,每个需要缓存的项目都有对应的缓存key,通过etcd监控key,并且设置过期时间,例如7天,如果在7天之内再次命中key,则通过lease进行续约;7天之内key都没有被使用,key就会过期删除,通过监听对应的前缀,在过期删除的时候,调用删除缓存的方法。
storage.Watch("cache/", func(id string) { //do nothing }, func(id string) { CleanCache(id) })
不同技术栈的最佳实践
1 Java
以Maven构建工具为例,其默认配置文件位于conf/settings.xml文件中,默认指定环境变量$M2_HOME来设置缓存目录,这样同一条流水线多次执行可以复用 ${M2_HOME}/.m2 目录 (缓存目录),甚至同一个应用下的多个分支之间都可以使用同一个缓存目录,就像本地构建一样。
| BASE执行 |
---|---|
无缓存 | 平均时间:5.26min |
有缓存 | 平均时间:41.462s |
提升效率 | 提升87.3% |
缓存命中率 | 接近100% |
2 NodeJs
在nodejs编译中,我们的缓存目录是当前用户空间,针对node_modules文件进行压缩打包,push到cfs;如果缓存命中,从cfs上pull并且解压到当前用户空间下,恢复缓存。
使用举例
| BASE执行 |
---|---|
无缓存 | 平均时间:58s |
有缓存 | 平均时间:29s |
提升效率 | 提升50% |
缓存命中率 | 接近100% |
3 Golang编译
Golang 缓存路径通过$GOCACHE
环境变量控制,将$GOCACHE
的内容压缩成zstd的包,上传到cfs的指定路径下。pull缓存的时候,拉取到对应的$GOCACHE。
| BASE执行 |
---|---|
无缓存 | 平均时间:117s |
有缓存 | 平均时间:18s |
提升效率 | 提升84.6% |
缓存命中率 | 接近100% |
4 GCC编译
我们使用ccache进行缓存实现。ccache(“compilercache”的缩写)是一个编译器缓存,该工具会高速缓存编译生成的信息,并在编译的特定部分使用高速缓存的信息。ccache的缓存目录:CCACHE_DIR,我们将这个目录下的文件进行压缩,push到cfs,当第二次运行并且命中缓存,从cfs上pull并解压到CCACHE_DIR指定的目录下。
总结
在不同语言的编译原子内部,默认开启缓存的设置。第一次运行流水线的时候,会进行依赖的下载,第二次运行流水线,会命中缓存,无需进行依赖的下载,提高了流水线执行的效率。缓存默认保存7天。
自定义镜像进行缓存的最佳实践
为了满足用户使用自定义镜像的方式触发流水线,我们增加了两个通用的缓存原子。
Restore缓存:恢复缓存
Save缓存:保存缓存
在编译之前,添加Restore缓存原子
在编译之后,添加Save缓存原子
使用举例
在maven编译原子中,默认开启了maven编译的缓存;同时还有nodejs的编译构建,所以我们增加了restore原子和save原子
| BASE执行 |
---|---|
无缓存 | 平均时间:21min57s 其中maven: 17min83s nodejs: 4min19s |
有缓存 | 平均时间:4min20s 其中maven: 1min10s nodejs: 2min36s |
缓存效率提升 | maven: 93.7% nodejs:39.8%(nodejs编译中有包含单元测试) |
缓存命中率 | 接近100% |
未来规划
•不同编译原子,向用户开放配置,如是否开启缓存,设置缓存key
•实现不同语言编译原子增量push缓存功能

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
Django 存在拒绝服务漏洞漏洞
漏洞描述 Django是Django基金会的一套基于Python语言的开源Web应用框架。 由于Django会缓存Accept-Language标头的解析值,以避免重复解析,当攻击者发送内存较大的标头值时,会导致过度使用内存而引起拒绝服务。 漏洞名称 Django 存在拒绝服务漏洞漏洞 漏洞类型 拒绝服务 发现时间 2023-02-02 漏洞影响广度 小 MPS编号 MPS-2023-2240 CVE编号 CVE-2023-23969 CNVD编号 - 影响范围 django@[3.2, 3.2.17) django@[4.0, 4.0.9) django@[4.1, 4.1.6) 修复方案 升级django到 3.2.17、 4.0.9、4.1.6或更高版本 参考链接 https://www.oscs1024.com/hd/MPS-2023-2240 NVD 免费情报订阅&代码安全检测 OSCS是国内首个开源软件供应链安全社区,社区联合开发者帮助全球顶级开源项目解决安全问题,并提供实时的安全漏洞情报,同时提供专业的代码安全检测工具为开发者免费使用。社区开发者可以通...
- 下一篇
一种基于图片搜索视频的方案
作者:京东零售 谷伟 1.商品搜索 1.1网络购物的搜索手段 随着移动互联网发展,手机端购物已成为人们生活的常态。人们在搜索商品时采用的手段也越来越丰富,当前的主要搜索方式是文本搜索与拍照搜索。 1.2文本搜索 文本搜索应用比较广泛,较为常用的是关键字匹配,针对商品信息的相关描述进行分词,并对分词建立索引库,从而达到查找的目的。随着人工智能的发展,语义搜索得到了快速的发展,它通过用户输入的搜索内容来理解用户真正的意图,从而获得更有价值的内容。其本质是将所有要搜索的内容转化为高维数学向量,用统一的特征向量来描述不同内容,把检索输入的内容向量化,并与要搜索的内容进行向量匹配,把相似度最高的结果展现出来。 1.3拍照搜索 拍照搜索也就是以图搜图,是近几年的视觉AI发展的一个产物。用户登录电商平台,可以通过上传图片,经过图像分析与识别来查找相似的商品主图,从而找出相关的商品。其基本原理是经图像分析抽取图像的颜色、形状、纹理等特征,建立特征索引库,对用户上传的图像进行特征化描述,从索引库中查找出与之近似的特征图像。 2. 现状分析 2.1需要专业人员参与 文本搜索需要文本描述的支持,也就是需要对...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- MySQL8.0.19开启GTID主从同步CentOS8
- CentOS8安装Docker,最新的服务器搭配容器使用
- Linux系统CentOS6、CentOS7手动修改IP地址
- 2048小游戏-低调大师作品
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- CentOS8安装MyCat,轻松搞定数据库的读写分离、垂直分库、水平分库
- CentOS8编译安装MySQL8.0.19
- CentOS6,CentOS7官方镜像安装Oracle11G
- CentOS7,8上快速安装Gitea,搭建Git服务器
- SpringBoot2整合Thymeleaf,官方推荐html解决方案