借助 RAM disk 技术,加快前端工程打包速度

 

背景
以 Jenkins 服务器为例,在构建内部的这个项目时,CE 每部署一次服务,最快 6 分钟,最
慢将近 13 分钟左右。遇到多个项目并发打包会因为资源占用等问题时间会延长,甚至出现过
几次 20 分钟以上的情况。

 

所以经常收到一些友情提示:比如像这样的截图,往往对方只发一张图,却什么都不说:

 

原因
在了解原因之前,我们先回顾一下历史,也就是当年为什么要用 Yarn。从这段历史中,我们
可以分析出来慢的原因。

Yarn 工具没有推出之前,通常是使用 NPM 进行依赖管理的,早期的 NPM 它有一个致命的
缺陷;需要等一个包,完全安装好后,在对下一个包做处理;它没有并发能力,所以才不会
涉及到高 IO 的问题,牺牲的是等待时间。

NPM 遇到相同版本的依赖库时,会重新下载一遍这个包;因为它原生不具备缓存能力,所以
只能重新下载。这也不会涉及 IO 问题,因为它牺牲了下载时间和 node_modules 文件夹的体
(这里是提前引用概念,下面第四条中有介绍)。

 

所以当时,我们引用了 Yarn 工具来提升安装依赖的速度。

(1) 它最特殊的是,具备锁(lock)文件,你从哪下载文件,你团队的人就从哪下载文件,避
免包版本不一致的问题。能解决我线下好使啊,怎么到你那就不行,诸如此类的问题。

(2) 会缓存它下载的每个包,所以无需重复下载。

(3) 具备离线模式,之前安装过的包会被写入缓存目录,以后安装就直接从缓存中复制过来
这样做的本质是减少重复下载,减少不必要的网络请求。

(4) 为了减少 node_modules 体积,会对依赖次数做选举,把引用频率高的类库放到顶级目录。

 

我们已经了解,它是依赖文件缓存的方式,提升了效率问题;仅仅是做选举,就已经引发了
高频 IO 的操作,因为它要分析引用次数来回的移动目录。Webpack 打包构建情况也是类似,
具体就不在展开细说。

 

现象
所以我们有了一个印象,前端工程下载后,会做很多 IO 操作。这对 SSD 磁盘很有效。如果
是机械硬盘,遇到高频读写,性能就会很慢。这是 Yarn 在做依赖库选举而优化磁盘占用时,
机械硬盘所消耗的时间耗时 13 分钟:


这种情况我们很难避免,只有几种选择:
1. 后退,使用 NPM 工具,选择等待牺牲网络下载时间,这条路走不通。
2. Jenkins 更换 SSD 磁盘,更换硬件实际上是最好的方案,短期内也走不通。
3. 优化 Yarn 依赖库的选举方案,Yarn PnP 还不太成熟,我们还在调研中,有坑,也走不通。


解决方案
当时的情况是,正常的方案都无法走通了。直到有一天我的同事提供一个思路,说他当年在 Windows
下片时,为了加快 Copy 速度把内存当磁盘用了,Windows 设置这个东西很简单。你们看看
Linux 支不支持。随后我们就开始调研,本机测试后发现可行。

然后我们以线下的的环境做试点,部署脚本改好了测试近一周,发现可行。

 

优化前,最高 23 分钟(开篇第一张图),现在平均 3 分钟

另一个项目优化前,平均 8 分钟:

优化后,平均 49 秒

 

本次主要是给大家,提供一个解决 IO 问题的思路。我们使用的是 RAM disk 中的 temfs
方案。技术对比看下方链接的文章就行,很简单:

 

参考链接
https://baike.baidu.com/item/tmpfs/1476960?fr=aladdin
https://blog.csdn.net/wz947324/article/details/80007122

posted @ 2019-09-04 18:24  吴佰清  阅读(1045)  评论(1编辑  收藏  举报