upyun/upx

关于 --delete 参数没有生效

john-h3 opened this issue · 8 comments

环境:
使用的是 coding.net 提供的持续集成环境 ubuntu

upx 版本是 0.3.2

同步命令如下:

/upx/upx --auth ****** sync docs/.vuepress/dist/ / -w 50 --delete

按照我对文档中的说明理解(这里不知道是否理解正确)
--delete 参数会将上次同步后删除的文件删除

那么我每次构建项目,都会新生成全新的 js 文件,js 后面跟的 hash 不同,这里有输出:

+ ls -l docs/.vuepress/dist/assets/js/
total 1028
-rw-r--r-- 1 root root   2269 Jan 14 09:53 10.eee54edc.js
-rw-r--r-- 1 root root   1577 Jan 14 09:53 11.696307ce.js
-rw-r--r-- 1 root root  31715 Jan 14 09:53 12.917b4eaa.js
-rw-r--r-- 1 root root   2146 Jan 14 09:53 13.7aff667e.js
-rw-r--r-- 1 root root    995 Jan 14 09:53 14.0b9c3534.js
-rw-r--r-- 1 root root   1400 Jan 14 09:53 15.80d08ed2.js
-rw-r--r-- 1 root root   1790 Jan 14 09:53 16.5945bf0e.js
-rw-r--r-- 1 root root   1077 Jan 14 09:53 17.4b468caa.js
...

但是同步命令并未删除旧的的 js 文件

+ /upx/upx --auth ****** sync docs/.vuepress/dist/ / -w 50 --delete
sync /root/workspace/docs/.vuepress/dist/assets/js/53.48625820.js to /assets/js/53.48625820.js OK
sync /root/workspace/docs/.vuepress/dist/assets/js/10.eee54edc.js to /assets/js/10.eee54edc.js OK
sync /root/workspace/docs/.vuepress/dist/assets/js/37.3828e393.js to /assets/js/37.3828e393.js OK
sync /root/workspace/docs/.vuepress/dist/assets/js/14.0b9c3534.js to /assets/js/14.0b9c3534.js OK
...
...
+=============+=========+===========+================+===========+=============+
| SYNC_EXISTS | SYNC_OK | SYNC_FAIL | SYNC_NOT_FOUND | DELETE_OK | DELETE_FAIL |
+-------------+---------+-----------+----------------+-----------+-------------+
|           0 |     120 |         0 |              0 |         0 |           0 |
+-------------+---------+-----------+----------------+-----------+-------------+

我是在 upyun 的 web 上的文件管理中发现占用空间过大发现的,事实也的确如此,在 js 的目录下,存在多个版本的文件

文件名 文件类型 文件大小 更新时间 操作
10.041913dc.js application/javascript 1.54 KB 2021-01-13 11:56:12  
10.4e4aefb3.js application/javascript 30.97 KB 2021-01-12 22:33:17  
10.82219fb5.js application/javascript 30.97 KB 2021-01-12 14:23:27  
10.dec1ddf1.js application/javascript 30.97 KB 2021-01-07 00:42:23  
10.eee54edc.js application/javascript 2.22 KB 2021-01-14 09:13:37
10.efa08f3e.js application/javascript 30.97 KB 2021-01-11 00:24:28

现在能确定的是,每次构建会将旧的版本 js 文件清除掉,也就是说同步时只有最新版本的 js 文件,按照我的理解同步时会检查到目录下旧版本的文件被删除掉,但是并没有发生,这一点也能从 delete_ok = 0 发现

服务名是哪个,我们排查下

服务名是哪个,我们排查下

john-note

Jan 13, 2021 @ 11:56:12.000 | john-note | /john-note/assets/js/10.041913dc.js | PUT | 200 | upx/v0.3.2
Jan 13, 2021 @ 00:21:26.000 | john-note | /john-note/assets/js/10.041913dc.js | PUT | 200 | upx/v0.3.2
Jan 13, 2021 @ 00:18:37.000 | john-note | /john-note/assets/js/10.041913dc.js | PUT | 200 | upx/v0.3.2

从最近的记录来看,这些文件会被重复提交(而不是全新的文件),所以应该是你上传环境下,这样的文件一直存在,所以才会没有删除

不,重复提交是我触发多次构建同一版本造成的

如果我的上传环境下有旧版本的文件,那么 sync_exist 应该不会为 0

可以提供一个复现的步骤吗,我这边测试了下删除本地文件是可以同步的

首先,我发现当我不使用持续集成环境时(在本地使用upx同步),的确是能够在同步的时候进行删除的
所以我怀疑是持续集成环境的问题,多次尝试发现,只要在持续集成环境下,就无法在同步时进行删除
考虑到持续集成是按需分配的资源,即每次构建的机器环境是不同的,于是我尝试了在两台电脑上模拟切换了实例的情况

云存储 H 两台机器 A B
假设 H 上现在有文件 1 2 3

现在我在机器 A 上创建目录 test,然后在目录下创建文件 4,然后增量同步
upx test/ / --delete
会发现同步了 1 个文件到 H 上,按照我的预期,由于此时 test 下不存在 1 2 3,所以会删除,而实际上 H 下文件变为 1 2 3 4

接着,我在机器 B 上进行操作,创建目录 test,然后在目录下创建文件1 2 3 4(全空白文件),然后增量同步
upx test/ / --delete
同步了 4 个文件到 H 上,此时并不会检测是否存在,输出中只有 SYNC_OK=4
到这里,可以知道如果切换了机器,那么第一次进行增量同步只会覆盖(这里猜测是增量同步是在机器上进行增量存储的,切换机器后就丢失增量的信息需要重新建立)
所以我遇到的问题应该就是这个情况

首先,我发现当我不使用持续集成环境时(在本地使用upx同步),的确是能够在同步的时候进行删除的
所以我怀疑是持续集成环境的问题,多次尝试发现,只要在持续集成环境下,就无法在同步时进行删除
考虑到持续集成是按需分配的资源,即每次构建的机器环境是不同的,于是我尝试了在两台电脑上模拟切换了实例的情况

云存储 H 两台机器 A B
假设 H 上现在有文件 1 2 3

现在我在机器 A 上创建目录 test,然后在目录下创建文件 4,然后增量同步
upx test/ / --delete
会发现同步了 1 个文件到 H 上,按照我的预期,由于此时 test 下不存在 1 2 3,所以会删除,而实际上 H 下文件变为 1 2 3 4

接着,我在机器 B 上进行操作,创建目录 test,然后在目录下创建文件1 2 3 4(全空白文件),然后增量同步
upx test/ / --delete
同步了 4 个文件到 H 上,此时并不会检测是否存在,输出中只有 SYNC_OK=4
到这里,可以知道如果切换了机器,那么第一次进行增量同步只会覆盖(这里猜测是增量同步是在机器上进行增量存储的,切换机器后就丢失增量的信息需要重新建立)
所以我遇到的问题应该就是这个情况

   --strong  strong consistency

可以加上这个参数,上传之前和服务器比对文件是否发生变更,默认是会利用本地记录的 sync 信息作为对比

我使用了这个参数,现在文件夹内的文件一定会与服务器比对了

但是,这并没有解决我所遇到的问题
我想,考虑到云存储上有大量的文件,所以遍历云存储是不实际的,所以这里的对比一定是基于本地文件夹里存在的文件来和云上对比的。这么一来,会产生如下效果:

初始云存储 H 无文件

现在机器 A 构建,生成文件 1.a.js 2.a.js 3.a.js 4.a.js
(上述 a 为哈希值,每次构建会对文件计算校验和,如果源文件未发生改动,则不改变)
使用强一致的增量同步 upx sync ... --delete --strong
sync_ok = 4

不改变代码,重新构建,此时在机器 B 上构建,同样生成了 1.a.js 2.a.js 3.a.js 4.a.js
使用强一致的增量同步 upx sync ... --delete --strong
sync_exist = 4
产生了预期的效果

但如果源代码发生了变动,再触发构建,机器 C 上生成了文件 1.b.js 2.a.js 3.a.js 4.a.js(假设此时只改动了 1 对应的源码)
使用强一致的增量同步 upx sync ... --delete --strong
sync_exist = 3 sync_ok = 1
云存储上文件 1.a.js 1.b.js 2.a.js 3.a.js 4.a.js

即 --delete 是无法在本地没有增量信息的情况下执行的,上述情况应该是 1.a.js 被删除 1.b.js 被新增
所以我想这是因为不可能主动去云存储上遍历文件情况,所以 upx 的增量同步机制是与机器强关联的,如果在多台机器上进行增量同步会带来很多的问题,如多台机器的各自的增量存储文件都不同,所以可能会出现无法得到预期的效果

我实践了一个可行的方案,将 ~/.upx.db 也放入项目的代码中,可以与项目放在一起,也可以单独作为一个项目,每次在增量同步前,将其覆盖到 ~/.upx.db,增量同步后,将新版本的增量信息提交到远程,这么一来就能够实现多机器下统一的增量信息。