我正在修复整个目录树(除了两个特定子目录)中的所有权、组成员身份和模式问题,这些目录树只能通过 NFS 访问。此目录树包含数十 TB 的数据,因此修复这些问题的命令需要很长时间才能运行(此时我已经花了整整一天时间执行第一个命令,我不知道如何判断命令的进度)。
我的第一个命令如下,用于修复所有权和组成员身份:
find /share \
\( \
-type d -a \
\( \
-path /share/exclude_dir_1 -o \
-path /share/exclude_dir_2 \
\) -a \
-prune \
\) -o \
\( \
-type d -o \
-type f \
\) \
-exec chown myuser:mygroup {} \;
我目前计划在上述命令完成后执行以下命令来修复模式问题:
find /share \
\( \
-type d -a \
\( \
-path /share/exclude_dir_1 -o \
-path /share/exclude_dir_2 \
\) -a \
-prune \
\) -o \
-type d \
-exec chmod 775 {} \;
find /share \
\( \
-type d -a \
\( \
-path /share/exclude_dir_1 -o \
-path /share/exclude_dir_2 \
\) -a \
-prune \
\) -o \
-type f \
-exec chmod 664 {} \;
我目前与 NFS 共享的连接速度为 1 Gbps。该连接将很快升级到 10 Gbps,但我不确定网络连接是否是瓶颈所在。
我正在使用 Bash,并且可以在 RHEL 6 或 RHEL 7 上执行这些命令。
社区对如何更有效地完成这项工作有何建议?
其次,如果社区对如何衡量这些命令的进度有任何建议,我们也会很感激。
答案1
您正在运行(或计划运行)的命令对每个文件使用一个chown
(或chmod
)。目录“包含数十 TB 的数据”这一事实并不直接相关;总数字文件数才是最重要的。对于少数大文件,您的命令会很快完成。
你远程操作,“连接将很快升级到 10 Gbps”。我认为在修改元数据的情况下,延迟比吞吐量更重要。
可能的改进:
在服务器上本地工作。
比较这个答案:
NFS 使用文件句柄;为了对文件执行某些操作,客户端首先通过 LOOKUP 获取文件句柄,然后使用获取的文件句柄执行其他请求。至少需要两个数据报,并且在特定情况下,它们之间的时间可能非常“长”。
我知道您说的是“我只能通过 NFS 访问”。但一般来说,在服务器上工作而不依赖 NFS 可能比任何其他提示都更有效,尤其是在延迟相对较高的情况下。也许您可以让服务器管理员为您运行一些命令。
同时请求多项操作。
您的代码一次运行一个
chown
(或多个chmod
)。不仅网络延迟(数据包来回传输),而且服务器上的同步也会影响请求更改和成功退出(收到服务器确认后)以及移动到下一个文件之间的总体延迟。请参阅这:假设您设置了(强烈推荐的)导出选项,则所有元数据操作(例如
create
、、等)都将导致服务器将文件元数据刷新到磁盘。如果设置了,服务器还将通过将数据刷新到稳定存储来满足请求。chmod
rename
sync
sync
COMMIT
sync
是一个服务器选项(请参阅man 5 exports
)。想象一下,一个信使在两个前哨之间旅行。如果往返时间很长,那么为独立主题使用许多独立的信使是合理的。对于你的情况:
- 您可以运行几个
find
s,每个 s 都在相关目录树的自己的分支上运行; find
或者您可以将(no-exec
)的输出输入到parallel
或xargs -P
。
笔记:
- 如果您可以在服务器上本地工作那么您就不需要这样的并行化。
- 如果你高估了服务器的性能并同时发送了太多的请求,你可能会无意中执行DoS 攻击。
- 您可以运行几个
所有权映射。
有一种方法可以在客户端映射所有权,而无需在服务器上进行更改。请参阅这个答案。如果链接断开:关键字是
idmapd
或rpcidmapd
。笔记:
- 服务器必须配合。
- 这可能会消除 的需要,
chown
但不会消除 的必要chmod
。 - 如果有其他客户,他们可能也需要这个解决方案。
递归使用
chown
。您的代码
chown
对每个匹配文件运行一个进程。生成进程的成本很高,最好让一个进程处理多个文件。使用chown -R
;该选项是 POSIX 所必需的,因此是可移植的。笔记:
- 在服务器本地工作时这种改进也是合理的。
- 由于目录和常规文件需要不同的模式,因此很难使其
chmod -R
同样有用。 - 需要排除某些目录可能会造成干扰。提示:如果可以,将虚拟(空)目录绑定挂载到要排除的目录上,以将其隐藏起来
chmod -R
。
使用
-exec … {} +
。由于
chmod -R
不符合您的需求,下一个最佳选择是chmod
使用多个操作数运行。而不是-exec chmod 775 {} \;
运行-exec chmod 775 {} +
。不要指望一个人chmod
能完成整个工作,这是有限制的。find
将尊重限制并chmod
根据需要运行尽可能多的 s,仍然将多个操作数传递给每个 s。笔记:
- 在服务器本地工作时这种改进也是合理的。
parallel
或者xargs
可以向 传递多个参数chmod
。我不会对此进行详细说明。