Rez中文文档15 Package Caching

概述

软件包缓存(Package Caching)是一个将包复制到本地磁盘加快运行环境的功能。

比如你发布的包通常是在共享服务器上,那么运行python进程时,就会从共享存储上获取所有源码。缓存的意义在于将这些内容复制到本地,节省访问网络的时间成本。

启用缓存

软件包缓存功能不是默认启用的。要启用它,需要配置cache_packages_path来指定缓存的路径。

你也可以细致的控制哪些包是需要被缓存的,只需要在它的定义文件(package.py)设置cachable = True 。我们需要单独控制哪些包是可以被缓存的,因为某些编译后的包无法支持重定向(即缓存到本地会丢失作用)。

还有一些配置会在包没有设置cachable=True的情况下缓存包。比如dedefault_cachabledefault_cachable_per_packagedefault_cachable_per_repository

Notes:你也可以使用rez-env --no-pkg-caching来禁用包缓存。

验证

当你解析一个环境后,可以通过rez-context输出的右侧栏中看到缓存标签,查看哪些变体已经被缓存。如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
]$ rez-env Flask

You are now in a rez-configured environment.

requested packages:
Flask
~platform==linux (implicit)
~arch==x86_64 (implicit)
~os==Ubuntu-16.04 (implicit)

resolved packages:
Flask-1.1.2 /home/ajohns/package_cache/Flask/1.1.2/d998/a (cached)
Jinja2-2.11.2 /home/ajohns/package_cache/Jinja2/2.11.2/6087/a (cached)
MarkupSafe-1.1.1 /svr/packages/MarkupSafe/1.1.1/d9e9d80193dcd9578844ec4c2c22c9366ef0b88a
Werkzeug-1.0.1 /home/ajohns/package_cache/Werkzeug/1.0.1/fe76/a (cached)
arch-x86_64 /home/ajohns/package_cache/arch/x86_64/6450/a (cached)
click-7.1.2 /home/ajohns/package_cache/click/7.1.2/0da2/a (cached)
itsdangerous-1.1.0 /home/ajohns/package_cache/itsdangerous/1.1.0/b23f/a (cached)
platform-linux /home/ajohns/package_cache/platform/linux/9d4d/a (cached)
python-3.7.4 /home/ajohns/package_cache/python/3.7.4/ce1c/a

对于引用,缓存的包也会将其原始的位置存储到一个环境变量中:

1
2
]$ echo $REZ_FLASK_ORIG_ROOT
/svr/packages/Flask/1.1.2/88a70aca30cb79a278872594adf043dc6c40af99

工作原理

包缓存实际上缓存的是变体,而不是整个包。当你执行环境解析的时候,或者source一些存在的context时,所需的变体会被异步复制到本地磁盘(如果它们是可缓存的),在一个单独的进程中,进程名为rez-pkg-cache

这意味着在第一次解析时,不一定会用到缓存的变体(因为进程还在持续运行中,完成缓存需要时间,这是一个缓慢的过程)。

注意,包缓存不是一个包仓库,它只是一个变体存储,结构上可以将任何仓库中的变体存储到一个共享缓存中。

被缓存的变体是不可变的,没法检查变体是否有发生变化。所以你不应该在包仓库中使用缓存,因为包可能会覆盖。正因如此,本地包的缓存默认是被禁用的。(参考package_cache_local

命令行

检验

使用rez-pkg-cache来查看缓存的状态,并进行预加载和删除操作。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
]$ rez-pkg-cache
Package cache at /home/ajohns/package_cache:

status package variant uri cache path
------ ------- ----------- ----------
cached Flask-1.1.2 /svr/packages/Flask/1.1.2/package.py[0] /home/ajohns/package_cache/Flask/1.1.2/d998/a
cached Jinja2-2.11.2 /svr/packages/Jinja2/2.11.2/package.py[0] /home/ajohns/package_cache/Jinja2/2.11.2/6087/a
cached Werkzeug-1.0.1 /svr/packages/Werkzeug/1.0.1/package.py[0] /home/ajohns/package_cache/Werkzeug/1.0.1/fe76/a
cached arch-x86_64 /svr/packages/arch/x86_64/package.py[] /home/ajohns/package_cache/arch/x86_64/6450/a
cached click-7.1.2 /svr/packages/click/7.1.2/package.py[0] /home/ajohns/package_cache/click/7.1.2/0da2/a
cached itsdangerous-1.1.0 /svr/packages/itsdangerous/1.1.0/package.py[0] /home/ajohns/package_cache/itsdangerous/1.1.0/b23f/a
cached platform-linux /svr/packages/platform/linux/package.py[] /home/ajohns/package_cache/platform/linux/9d4d/a
copying python-3.7.4 /svr/packages/python/3.7.4/package.py[0] /home/ajohns/package_cache/python/3.7.4/ce1c/a
stalled MarkupSafe-1.1.1 /svr/packages/MarkupSafe/1.1.1/package.py[1] /home/ajohns/package_cache/MarkupSafe/1.1.1/724c/a

每个变体都被存储在一个目录中,这个目录是该变体唯一的标识符。

软件包缓存是具有线程和多进程的,并在必要时使用文件锁来控制访问。

缓存的变体在任何时候都有其中之一的状态:

  • copying:这个变体正在被复制到缓存中,还不能使用。
  • cached:该变体已经被缓存,可以使用。
  • stalled:变体在复制中出现来点问题,缓存中只存在部分副本。

日志

缓存操作存储在缓存目录下的日志文件中:

1
2
3
4
5
6
]$ rez-pkg-cache --logs
rez-pkg-cache 2020-05-23 16:17:45,194 PID-29827 INFO Started daemon
rez-pkg-cache 2020-05-23 16:17:45,201 PID-29827 INFO Started caching of variant /home/ajohns/packages/Werkzeug/1.0.1/package.py[0]...
rez-pkg-cache 2020-05-23 16:17:45,404 PID-29827 INFO Cached variant to /home/ajohns/package_cache/Werkzeug/1.0.1/fe76/a in 0.202576 seconds
rez-pkg-cache 2020-05-23 16:17:45,404 PID-29827 INFO Started caching of variant /home/ajohns/packages/python/3.7.4/package.py[0]...
rez-pkg-cache 2020-05-23 16:17:46,006 PID-29827 INFO Cached variant to /home/ajohns/package_cache/python/3.7.4/ce1c/a in 0.602037 seconds

清理缓存

清理缓存是指删除停滞的或者不再使用的变体。由于我们无法知道一个变体是否在使用,所以有一个可配置的package_cache_max_variant_days设置,它将删除超过X天没有被使用的变体。

你也可以使用rez-pkg-cache -r来手动删除缓存中的变体。需主要这样的操作只是使缓存不可用,但它仍然存储在磁盘上。执行rez-pkg-cache --clean来真正意义上从磁盘删除缓存。

你可以使用package_cache_clean_limit 设置,在每次更新缓存时,异步的执行一些清理工作。如果你不想使用这个设置,建议你设置一个cron或其它形式的定时器来定期运行rez-pkg-cache --clean,否则你的缓存将越积越多。

最后请注意,处于停滞状态的缓存不会尝试重新缓存,直到它被清理或移除操作。

你需要运行rez-pkg-cache --clean来删除停滞的缓存。