루트로 Linux 파일 시스템을 탐색하는 것이 더 빠릅니까?

루트로 Linux 파일 시스템을 탐색하는 것이 더 빠릅니까?

파일 수가 많은 파일 시스템을 순회할 때 root다른 사용자에 비해 속도가 빠른가요?

예를 들어, 아래에 수백만 개의 파일이 있고 속한 경우 /data재귀 /datagrep이 user123for보다 더 빠르게 완료됩니까?rootuser123

권한 확인을 건너뛰는 최적화가 있는지 또는 stat모든 파일에 대해 a가 수행되므로 확인은 단지 조건일 뿐인지 궁금합니다. 그리고 이것이 보편적으로 적용됩니까, 아니면 파일 시스템을 통해 적용됩니까?

나는 속도를 높이기 위해 이와 같은 매우 큰 작업을 실행하는 미신적인 습관을 개발했지만 root실제로 도움이 되는지 테스트할 좋은 방법을 찾지 못했습니다.

답변1

Linux에서는 루트에 대한 특별한 처리가 없습니다. 루트는 액세스 모드 변경, ACL 수정, SELinux 적용 비활성화 등의 권한을 가질 수 있지만 사용자는아직이러한 제약이 적용됩니다. 따라서 실제로 커널은 어떤 지름길도 사용할 수 없습니다. (이것은 Linux UID 네임스페이스에서 작업한다는 것이 무엇을 의미하는지 생각하면 상황을 더욱 복잡하게 만듭니다. 보편적인 강력한 루트: 실행 중인 프로세스의 관점에서는 존재하지 않을 수도 있습니다.)

또는 각 파일에 대해 통계를 수행하려면

stat이것은 사용자 모드가 파일에 대해 더 많은 것을 배우기 위해 수행하는 작업입니다. 재귀 grep이 이를 수행할 필요조차 없다는 것은 확실하지 않습니다. 모든 디렉토리 항목을 가져온 다음 각 항목에 대해 개별적으로 수행하는 비효율성으로 인해 두 getdents(64). 결과에는 접근 정보가 포함되어 있지 않으나, 이렇게 찾은 파일에 접근하기 전에 현재 사용자가 접근할 수 있는지 여부를 확인하기보다는 계속 시도하는 것이 현명하다. 실패하면 접근할 수 없다. 이렇게 하면 파일당 하나의 컨텍스트 스위치가 저장됩니다.

그래서 뭐할 수 있다재귀를 더 빠르게 만들기 위해 실제로 급진적 권한을 활용합니까 grep?

대답은 사용자 영역 grep과 커널 골드 시스템 기능 간의 컨텍스트 전환을 최소화하는 데 있을 수 있습니다. 모든 파일과 디렉토리를 열지 않도록(가능한 경우) Linux 커널을 확장하는 즉각적이고 깔끔한 방법은 보이지 않습니다. Linux에는 모든 동시성, 안전성, 종료 및 메모리 할당 동작을 잘 정의된(파일 핸들을 소유한 프로세스에 의해) 의미 체계로 변환하기 위해 실제로 사용자 공간에서 파일에 액세스하는 모델이 있습니다.

답변2

, 하지만아니요

음 – 시도하기 전에 추론하지 마세요.

sudo -i; cd etc; time ls -R >/dev/nullsudo로 전환하지 않고 같은 방법을 사용했습니다 . 캐시 영향 가능성을 줄이기 위해 xterms와 bash를 2회 실행했습니다. 나는 sudo로 시작하여 몇 가지 측정을 수행하고 사용자와 함께 반복했습니다. CPU는 8개이고 로드 평균은 약 1입니다.

시간은 동일하며 루트는 0.014, 0.014, 0.16이고 나는 0.015 3번입니다.

이상치를 배제하려면 여러 번 측정해야 하지만 이상치를 볼 수는 없습니다. 출력 시간은 아마도 이 유형의 작업에서 가장 큰 시간을 차지하는 것이기 때문에 출력은 /dev/null로 리디렉션됩니다. 내 타이밍(루트) 의 경우 ls -R /usr리디렉션이 없으면 11.5초, 리디렉션이 있으면 약 1.5초였습니다.

루트의 경우 연속 3회 호출에 대한 값은 1.5, 1.1, 1.1이고, 사용자의 경우에는 5.2, 1.1, 1.1이다. 어쩌면 두 번째 및 세 번째 호출에 대한 캐싱 효과일 수도 있습니다.

나는 /var를 재사용했고 사용자에 대해 0.2, 0.1, 0.1 루트를 얻었습니다( time ls -R /var >/dev/null 2>&1금지된 폴더가 많기 때문에).

따라서 사용자당 캐시가 있는 것처럼 보이지만 이를 더 자세히 조사하려면 각 호출 사이에 다시 시작해야 하고 다른 사용자에 대해 동일한 명령을 반복하지 않아야 할까요? 그런 것 같아요.

일부 디렉터리는 하위 디렉터리를 포함하여 완전히 루트 사용자로 제한되므로 루트는 사용자보다 /var에 있는 더 많은 파일 항목에 액세스할 수 있어야 합니다.

하지만

/usr에 있는 618282개 파일의 경우 완료하는 데 약 1.1초가 걸리며, 실제로 10분의 1마이크로초 이하의 파일을 처리하면 루트를 사용하는 것이 더 빠를 수 있지만 상관없습니다. 예를 들어, 대부분의 시간은 일치 항목을 기반으로 탐색하고 작업하는 데 시간을 소비하게 됩니다.

/etc에서 재귀적으로 GNU를 탐색하는 것은 ls보다 약 40% 더 오래 걸립니다.

참고: 이 테스트는 ext4가 있는 SSD 드라이브에서 수행되었습니다. YMMV.

답변3

모든 프로그램은 일반적으로 사용자 공간에서 실행되므로 사용자 간의 유일한 차이점은 리소스에 액세스할 수 있는 권한입니다. 루트 사용자는 (대부분의 경우) 모든 액세스 권한을 가지므로 시스템 호출 수가 줄어들고 이는 대량 실행을 수행할 때 큰 차이를 만듭니다.

계산을 위해 ls -l다른 사용자와 루트로 실행하여 간단한 테스트를 해본 결과 루트에서 수행하는 시스템 호출이 거의 50% 감소했습니다 ls -l. 뿌리가 직면하는 장애물이 적기 때문에 뿌리가 더 빨리 도달할 수 있다는 점을 제외하면 장애물 코스와 같습니다(단기 프로젝트 및/또는 빈번한 프로젝트의 경우 결과가 다를 수 있음을 기억하십시오).

답변4

명령을 사용하여 이를 테스트할 수 있습니다 time. 귀하의 질문에 대답하자면, 루트는 일반적으로 일반 사용자보다 시스템 리소스에 대해 더 많은 무제한 액세스 권한을 갖기 때문에 루트로서 대규모 작업이 더 빠르게 실행될 수 있습니다. 예약된 디스크 공간은 일반적으로 루트에서 사용할 수 있지만 다른 사용자는 사용할 수 없습니다. 따라서 추가 디스크 공간을 활용할 수 있는 대규모 작업을 수행하는 경우(많은 수의 임시 파일이 생성될 수 있으므로) 작업 속도가 빨라질 수 있습니다. 또한, 일반 사용자는 유사한 시스템 환경에 의해 제한될 수 있습니다 /etc/security/limits.conf. 루트로 실행되는 작업은 액세스 거부 오류를 일으킬 가능성이 낮으며, 이로 인해 작업에 따라 프로세스 속도가 빨라지거나 느려질 수 있습니다.

그러나 보안상의 이유로 일반적으로 가능하면 루트를 사용하지 않아야 합니다.

# 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

이 답변은 근거가 있습니까, 아니면 단지 추측입니까? ——크리스 데이비스

아, 보세요, 무슨 증거가...

캐싱이 실제로 관련된 요소이므로 이전 테스트가 약간 부정확했을 수 있습니다. 그러나 내 테스트에 따르면 루트와 루트가 아닌 경우 처리 시간이 다를 수 있습니다. 그래서 또 다른 테스트를 해보겠습니다. 동일한 명령을 연속으로 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

나는 네 번째이자 마지막 테스트를 했다.

이번에는 EXT2 파일 시스템을 사용하여 포맷된 2개의 파티션을 만들었습니다. 두 파티션 모두 동일한 시스템의 동일한 하드 드라이브에 있으며 둘 다 크기가 100MiB입니다.

두 개의 파일 시스템을 마운트하고 다음과 같은 위험한 스크립트를 사용하여 루트가 아닌 사용자를 사용하여 파일 시스템을 임의의 데이터로 채웠습니다.

수행 중인 작업을 알지 못하는 경우 다음 스크립트를 실행하지 마십시오!

#!/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 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 설치에서는 루트 처리가 비루트 처리보다 빠릅니다.

관련 정보