수백만 개의 파일 삭제


38

수백만 개의 gif 이미지로 가득 채웠습니다. rm 명령에 비해 너무 많습니다.

다음과 같이 find 명령을 시도했습니다.

find . -name "*.gif" -print0 | xargs -0 rm

문제는 내 컴퓨터가 정말로 나 빠지고 서버이기 때문에 고객에게 시간 초과가 발생한다는 것입니다.

머신을 잠그지 않고 모든 파일을 더 빨리 삭제할 수있는 방법이 있습니까?


아래의 "nice find"명령을 사용하여 약 6GB / hr의 삭제 속도에 있습니다. 모든 파일을 제거하는 데 48 시간이 소요될 것입니다. rm 명령과 함께 "이벤트 호라이즌", 도망갔습니다

3
전체 디렉토리를 제거하는 것이 실질적으로 더 빠르지 않습니까? 남은 파일을
핵 공격

글쎄, 모든 파일은 현재 / dir_old로 옮겨 져서 / dir을 다시 만들었 기 때문에 좋지 않습니다. 그러나 rmdir은 rm *와 같은 제한을 갖지 않습니다.

@Corepuncher : 전체 디렉토리를 제거하는 rm -rf것이 더 빠를 것으로 예상 됩니다. 시도해 볼 가치가 있습니다.
Jason R

현재 디렉토리에서 "rm -rf"를 실행 중입니다. 지금은 20 분 이상 실행되고 있습니다. 디스크 크기는 아직 변경되지 않았습니다. 그러나 또한 "인수 목록이 너무 깁니다"도 자동으로 반환하지 않았습니다. 유일한 문제는 실제로 내 기계를 망치고 다른 것들을 느리게 / 실패하게 만드는 것입니다. 얼마나 오래 갈지 모르겠습니다.

답변:


44

더 빠른 것이 반드시 원하는 것은 아닙니다. 실제로 느리게 실행하고 싶을 때 실행 중에 삭제하면 리소스가 줄어 듭니다.

nice (1) 를 사용 하여 명령의 우선 순위를 낮추십시오.

nice find . -name "*.gif" -delete

I / O 바인딩 프로세스의 경우 nice (1)로는 충분하지 않을 수 있습니다. Linux 스케줄러는 CPU뿐만 아니라 I / O도 고려하지만 I / O 우선 순위를보다 세밀하게 제어 할 수 있습니다.

ionice -c 2 -n 7 find . -name "*.gif" -delete

그렇게하지 않으면 수면을 추가하여 실제로 속도를 늦출 수 있습니다.

find . -name "*.gif" -exec sleep 0.01 \; -delete

3
와우 ... 수면 .1 초의 수백만 파일 ... 864000 파일에는 하루가 필요합니다.
glglgl

7
@glglgl 좋아, 똑똑한 엉덩이. 시간 초과를 변경했습니다. :-P
John Kugelman이 Monica를

28
수면은 좋은 선택이 될 수 있지만 여기서는 태스크가 CPU 바운드가 아니라 IO 바운드이므로 좋지 않습니다. 대신 이온을 시도 할 수 있습니다. 수면이 너무 작 으면 쓸모가 없습니다.
Matteo Italia

3
@glglgl : 요점은 서버에서 서비스 중단을 일으키지 않으려면 천천히 가야한다는 것입니다.이 코드가 잠자기 시간은 서버가 실제로 디스크를 유용하게 사용할 수 있도록합니다.
Matteo Italia

1
sleep추가로 + 1-사용에도 불구하고 IO에서 서버를 질식시키는 데 문제가있었습니다 ionice -c 3. (물론) 파일을 지우는 데 걸리는 시간이 크게
늘어나지 만

22

Linux를 실행 중이고이 작업은 아마도 I / O 바인딩 일 것이므로 다음을 사용하여 명령 유휴 I / O 스케줄러에 우선 순위를 부여하는 것이 좋습니다 ionice(1).

ionice -c3 find . -name '*.gif' -delete

원래 명령과 비교하여 파이프를 피하여 CPU 사이클을 더 많이 절약 할 수 있다고 생각합니다 xargs.


@Braiam 무슨 뜻인가요? 이것은 의미가있는 find ... -exec곳 이 아닙니다 .

오, 미안 내 잘못이야. 당신은 그것이 효율적이라고 확신합니까?
Braiam

1
글쎄, find(1)문서는 그렇게 주장한다. :) 그리고 find파일을 스스로 제거하는 것이 rm명령을 내리는 것보다 효율적 이라는 것이 분명해야합니다 .

1
프로덕션 서버에서 4 백만 개의 파일이있는 폴더에서 여러 가지 제안 된 버전을 시도했지만 이것이 시스템을 방해하지 않는 유일한 버전입니다. ionice -c3그렇지 않으면 IO가 유휴 상태 일 때 prio를 실행하여 그렇지 않으면 이것이 완벽합니다. 이후 있습니다 -delete찾기위한 표준 아니며,이 명령을 사용하여 (작동하는지 피드백 포함) 동일한 기능을 수행 할 수 있습니다 : ionice -c 3 find . -name '*.gif' -exec echo {} \; -exec rm {} \;- 슬로우하지만 중요한 과정없이 iowaits.
Christopher Lörken 2016 년

13

아니.

디스크의 소프트 포맷에서 더 빠른 방법은 없습니다. 파일은 한 번 에 rm 제공되며 (명령 행의 한계까지 설정 될 수 있음 xargs) 각 파일에서 rm을 호출하는 것보다 훨씬 낫습니다. 따라서 더 빠른 방법은 없습니다.

사용 nice(또는 renice그이 스케줄링 있기 때문에 실행중인 프로세스에) 부분적으로 만 도움이 CPU의 자원이 아닌 디스크를! CPU 사용량이 매우 적습니다. 이것은 리눅스의 약점입니다. 한 프로세스가 디스크를 "먹으면"(즉, 많은 작업을 할 경우) 전체 머신이 멈 춥니 다. 실시간 사용을 위해 수정 된 커널이 해결책이 될 수 있습니다.

서버에서 수행 할 작업은 다른 프로세스가 수동으로 작업을 수행하도록하는 것입니다. 서버를 "호흡"상태로 유지하기위한 일시 중지를 포함합니다.

find . -name "*.gif" > files
split -l 100 files files.
for F in files.* do
    cat $F | xargs rm
    sleep 5 
done

파일 100 개마다 5 초간 기다립니다. 시간이 훨씬 오래 걸리지 만 고객은 지체하지 않아야합니다.


쉘이에 주문하면 - 그래서 "파일이 (최대 명령 줄의 한계에 한 번에 RM에게 주어집니다" rm *, 그것은 확장 *파일 이름을 모두 가진 선으로 그것을 위해 통과 rm? 그건 믿을 수 없을만큼 바보. 왜 것 와일드 카드를 확장?

:-D @Joker_vD, 이름에서 알 수 있듯이 농담하고 있습니까? :-)
Tomas

2
@Joker_vD : 1970 년 이후의 유닉스 결정과의 호환성. Windows는 그렇지 않습니다. 여기에서 프로그램은 와일드 카드를 FindNextFile / FindNextFile에 전달할 수 있으므로 한 번에 하나씩 결과를 얻습니다.
MSalters

@Tomas이 경우에는 아닙니다. 솔직히, 나는 그러한 디자인에서 즉시 두 가지 문제를 볼 수 있습니다. 첫째, 커맨드 라인은 고무가 아닙니다. 둘째, 프로그램은 호출 된 경우 말할 수 없습니다 *또는 /*사용자의 이러한 결정에 의심의 여지를 제공합니다.

1
@Joker_vD 와일드 카드 확장을 수행하는 쉘에는 좋은 점이 많이 있습니다. Windows와는 다르지만 익숙한 것과 다르기 때문에 믿을 수 없을 정도로 어리 석다는 결론으로 ​​넘어 가지 마십시오. 자세한 내용을 알고 싶다면 Google에 문의하거나 관련 Stack Exchange 사이트에 질문을 게시하십시오. 이 의견 영역에 큰 영향을 미칩니다.
John Kugelman은 Monica

5

삭제 될 파일 수가 남은 파일보다 훨씬 많은 경우, 삭제 될 파일 트리를 걷고 모든 파일 시스템 업데이트를 수행하는 것이 가장 효율적인 방법은 아닙니다. (서투른 참조 카운트 메모리 관리를 수행하는 것과 유사합니다. 큰 트리의 모든 객체를 방문하여 참조를 삭제하는 대신 모든 것을 원치 않는 쓰레기로 만드는 대신 한 번에 정리할 수있는 항목을 청소합니다.)

즉, 다른 볼륨에 보관 될 트리 부분을 복제하십시오. 원래 볼륨에서 새로운 빈 파일 시스템을 다시 작성하십시오. 보유 된 파일을 원래 경로로 다시 복사하십시오. 이것은 가비지 콜렉션 복사 와 모호합니다 .

다운 타임이 있지만 지속적인 성능 저하 및 서비스 중단보다 더 나을 수 있습니다.

그것은 당신의 시스템과 상황에서 실용적이지 않을 수 있지만, 이것이 갈 길인 명백한 경우를 상상하기는 쉽습니다.

예를 들어, 파일 시스템에서 모든 파일 을 삭제하려고한다고 가정하십시오 . 하나씩 반복해서 삭제하는 요점은 무엇입니까? 그냥 마운트를 해제하고 빈 파일 시스템을 만들기 위해 파티션 위에서 "mkfs"를하십시오.

또는 6 가지 중요한 파일을 제외한 모든 파일을 삭제하고 싶다고 가정 해보십시오. 거기에서 십여 개를 가져 와서 "mkfs"를 맨 위로 가져옵니다.

결국 충분한 파일이 남아있을 때 중단 시간과 같은 다른 비용을 고려하여 재귀 삭제를 수행하는 것이 더 저렴 해지는 손익 분기점이 발생합니다.


4

시도해 보셨습니까?

find . -name "*.gif" -exec rm {} +

끝에있는 + 기호는 find가 단일 rm 명령을 실행하기 위해 더 많은 파일을 포함하게합니다. 자세한 내용은 이 질문 을 확인 하십시오.


-print0 |보다 훨씬 빠르게 실행됩니다. 모든 파일에 대해 rm 프로세스가 호출되지 않고 많은 파일 세트에 대해 xargs 솔루션이 실행되므로로드가 줄어 듭니다.

@JohnKugelman 정확하지만 기본 find 명령으로 항상 사용할 수있는 GNU 확장은 아닙니다 .
CodeGnome

좋아, 흥미롭지 만 이것은 -delete항상 거기에있을 필요는없는 아주 새로운 것입니다 .
Tomas

그러나 이것은 OP의 솔루션과 비교할 때 분명히 더 나은 것은 없습니다.
Tomas
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.