当遍历包含大量文件的文件系统时,与root
其他用户相比是否更快?
例如,如果 下有几百万个文件/data
,并且/data
属于,则递归 grep for 会比 foruser123
更快完成吗?root
user123
我很好奇是否存在跳过权限检查的优化,或者是否会对stat
每个文件执行 a ,因此检查只是一个条件。并且,这是否普遍适用,或者通过文件系统。
我养成了一个迷信的习惯,即运行这样一个非常大的操作来root
加速它,但还没有找到一个好的方法来测试它是否真的有帮助。
答案1
Linux 中对 root 没有特殊处理 - 尽管 root 可以拥有更改访问模式、修改 ACL、禁用 SELinux 强制执行等的权力,但用户仍然受这些约束。所以,实际上,内核不能采取任何捷径。 (考虑一下您在 Linux UID 命名空间中工作意味着什么,这会让事情变得更加复杂。那个通用的强大根:从您正在运行的进程的角度来看,它甚至可能不存在。)
或者是否要对每个文件执行统计,
stat
是 s sys all,即用户态为了解有关文件的更多信息而执行的操作。递归 grep 甚至不需要这样做,这并不是理所当然的;获取所有目录条目然后对每个条目单独执行此操作的低效率导致了将两者结合起来的专门调用的存在getdents(64)
。结果不包含任何访问信息,但在访问文件之前,不要检查当前用户是否可以访问以这种方式找到的文件,明智的做法是继续尝试 - 如果失败,则不能。这为每个文件节省了一次上下文切换。
又怎样可以一个人实际上利用根式特权来使递归grep
更快?
答案可能在于尽量减少用户态 grep 和内核黄金系统功能之间的上下文切换。如果没有编写类似内核模块的东西来提供进程能够访问的所有文件的扁平化视图以及将命中位置转换回实际文件路径的一些功能,我没有看到一种立即干净的方法扩展 Linux 内核以避免打开(如果可能的话)读取每个文件和目录。 Linux 有这样的模型,其中文件实际上是从用户空间访问的,以便将所有并发性、安全性、关闭和内存分配行为转化为具有明确定义的(由拥有文件句柄的进程)语义的东西。
答案2
是的, 但不
好吧——尝试之前不要推理。
我使用了sudo -i; cd etc; time ls -R >/dev/null
和 相同的方法,没有切换到 sudo。我使用了 2 次运行 xterms 和 bash 来减少缓存影响的可能性。我从 sudo 开始,进行了一些测量,并与用户重复。有8个cpu,平均负载约为1。
时间相当,root 为 0.014、0.014、0.16,我为 0.015 3 次。
您必须多次测量,以排除异常值,但看不到异常值。输出被重定向到/dev/null,因为输出时间可能是此类任务中最大的时间消耗。对于ls -R /usr
我的计时(root)来说,没有重定向的情况下是 11.5 秒,有重定向的情况下大约是 1.5 秒。
对于 root 来说,连续 3 次调用的值为 1.5、1.1、1.1,对于用户来说,值为 5.2、1.1、1.1。也许这是第二次和第三次调用的缓存效果。
我重复使用 /var 并得到 0.2, 0.1, 0.1 root; 0.5、0.1、0.1 用于用户(带有time ls -R /var >/dev/null 2>&1
,因为有许多禁止的文件夹)。
因此,似乎每个用户都有一个缓存,但为了进一步调查这一点,也许我必须在每次调用之间重新启动,并且不要为不同的用户重复相同的命令?大概吧。
请注意,某些目录完全仅限 root 用户使用,包括子目录,因此 root 必须比用户访问 /var 中更多的文件条目。
但
对于 /usr 中的 618282 个文件,大约需要 1.1 秒才能完成,一旦您真正处理这些文件,即十分之一或更小的微秒,您使用 root 可能会更快,但这并不重要。大多数时候 - 例如 - 您将花费在 grep 中,并根据匹配情况执行某些操作。
仅在 /etc 中递归地 grep 查找 GNU 就比 ls 多花费大约 40% 的时间。
注意:此测试是在带有 ext4 的 SSD 驱动器上进行的。YMMV。
答案3
由于所有程序通常都在用户空间中运行,用户之间的区别只是访问资源的权限。根用户拥有所有访问权限(大多数情况下),从而导致系统调用减少,这在执行大量执行时会产生巨大的差异。
为了计算,我通过ls -l
使用不同的用户和 root 运行来进行了简单的测试,结果是 root 执行的系统调用减少了近 50% ls -l
。这就像障碍赛一样,只是根面临的障碍较少,因此根可以尽早到达(请记住,对于短寿命和/或频繁的项目,结果可能会有所不同)。
答案4
您可以使用命令进行测试time
。为了回答您的问题,大型操作可能以 root 身份运行得更快,因为 root 通常比普通用户对系统资源有更不受限制的访问权限。通常 root 通常能够使用保留的磁盘空间,而其他用户无法使用该空间。因此,在执行大型操作时,可能会受益于额外的磁盘空间(因为它们可能会创建大量临时文件)可能会加快速度。此外,普通用户可能会受到类似系统环境的限制/etc/security/limits.conf
。由 root 运行的操作不太可能导致访问被拒绝失败,这可能会加快或减慢该过程,具体取决于操作。
但出于安全原因,您通常不应尽可能使用 root。
# command find used as non root user
time find / >> /tmp/find_as_non_root.log
real 0m1,506s
user 0m0,202s
sys 0m0,521s
# command find used as root user
time find / >> /tmp/find_as_root.log
real 0m0,673s
user 0m0,194s
sys 0m0,470s
这个答案是有根据的还是只是猜测? ——克里斯·戴维斯
哦,你看,什么证据...
我之前的测试可能有点不准确,因为缓存确实是一个涉及的因素。但我的测试表明,使用 root 用户与使用非 root 用户相比,处理时间可能会有所不同。所以我给你另一个测试,连续运行相同的命令 3 次。顺便说一下,你可以自己尝试一下。
# command find run 3 times in a row as non root user
time find / >> /tmp/find_as_non_root.log
real 0m0,618s
user 0m0,191s
sys 0m0,403s
time find / >> /tmp/find_as_non_root.log
real 0m0,648s
user 0m0,194s
sys 0m0,408s
time find / >> /tmp/find_as_non_root.log
real 0m0,704s
user 0m0,244s
sys 0m0,367s
# command find run 3 times in a row as root user
time find / >> /tmp/find_as_root.log
real 0m0.690s
user 0m0.270s
sys 0m0.412s
time find / >> /tmp/find_as_root.log
real 0m0.693s
user 0m0.210s
sys 0m0.474s
time find / >> /tmp/find_as_root.log
real 0m0.695s
user 0m0.182s
sys 0m0.504s
我还添加了第三个测试:
# non root user
user@opensuse:~> time bash -c "for i in 1 2 3 4 5 6 7 8 9 10; do echo \$i; find / &> /dev/null; done;"
1
2
3
4
5
6
7
8
9
10
real 0m5,212s
user 0m1,833s
sys 0m3,314s
# root user
opensuse:~ # time bash -c "for i in 1 2 3 4 5 6 7 8 9 10; do echo \$i; find / &> /dev/null; done;"
1
2
3
4
5
6
7
8
9
10
real 0m6,214s
user 0m2,113s
sys 0m4,018s
我做了第四次也是最后一次测试。
这次我创建了 2 个分区,使用 EXT2 文件系统格式化,两个分区位于同一台机器上的同一个硬盘上,大小均为 100MiB。
我已经安装了两个文件系统,并使用了以下危险脚本,使用非 root 用户用随机数据填充文件系统。
不要执行以下脚本,除非您知道自己在做什么!
#!/bin/sh
wheatgraindoubled=1
for iteration in $(seq 1 64)
do
echo "Iteration $iteration"
mkdir "$iteration"
cd "$iteration"
wheatgrain=0
while [ "$wheatgrain" -lt "$wheatgraindoubled" ]
do
wheatgrain=$(("$wheatgrain" + 1))
touch "$wheatgrain.dat"
dd if=/dev/urandom of="$wheatgrain.dat" count=8
done
wheatgraindoubled=$(("$wheatgraindoubled" * 2))
done
我等待脚本填充文件系统,直到没有可用空间。
然后我使用相同的命令来测量时间,就像我之前的测试一样:
# non root user
user@opensuse:~> time bash -c "for i in 1 2 3 4 5 6 7 8 9 10; do echo \$i; find 1/ &> /dev/null; done;"
1
2
3
4
5
6
7
8
9
10
real 0m0,277s
user 0m0,101s
sys 0m0,176s
然后我使用cp -r 1 /mnt/roottest/
root 用户复制所有文件并重复相同的测试。
# root user
opensuse:~ # time bash -c "for i in 1 2 3 4 5 6 7 8 9 10; do echo \$i; find 1/ &> /dev/null; done;"
1
2
3
4
5
6
7
8
9
10
real 0m0,263s
user 0m0,100s
sys 0m0,163s
结论,在默认的 opensuse 安装上,root 的处理速度比非 root 的处理速度更快。