서버를 방해하지 않고 수백만 개의 파일을 삭제하는 방법


11

nginx 캐시 디렉토리를 삭제하고 싶습니다.이 디렉토리는 빠르게 제거됩니다.

mv cache cache.bak
mkdir cache
service nginx restart

이제 cache.bak2 백만 개의 파일 이있는 폴더가 있습니다. 서버를 방해하지 않고 삭제하고 싶습니다.

간단한 rm -rf cache.bak것은 서버를 휴지통에 버리고, rm이 실행되는 동안 가장 간단한 HTTP 응답조차 16 초가 걸리므로 그렇게 할 수 없습니다.

나는 시도 ionice -c3 rm -rf cache.bak했지만 도움이되지 않았다. 서버에 SSD가 아닌 HDD가있을 수 있습니다. 아마도 SSD에는 문제가되지 않을 수 있습니다.

최고의 솔루션은 nginx의 내장 캐시 관리자와 같은 일종의 조절 기능이라고 생각합니다.

이 문제를 어떻게 해결 하시겠습니까? 정확히이 작업을 수행 할 수있는 도구가 있습니까?

우분투 16.04의 ext4


1
"rm -rf cache.bak"에서 어떻게 복구 했습니까? 이름을 변경했을 때 nginx가 실행중인 것으로 보이므로 파일 디스크립터를 유지 보수하고 새 디렉토리로 전환했을 수도 있습니다. nginx를 완전히 종료하고 캐시를 삭제 한 다음 다시 시작해야한다고 생각합니다.
Jan Steinman

6
나중에 캐시를 별도의 파일 시스템에 고정하십시오. 그렇게하면 파일 시스템을 간단히 압축하여 수백만 개의 파일을 삭제하는 것보다 훨씬 빠릅니다. 몇 년 전에 수십억 개의 파일이 포함 된 hylafax 스풀 디렉토리를 통해이 방법을 배웠습니다.
Dennis Kaarsemaker

nice를rm 사용하여 실행하려고 했습니까 ?
Vladislav Rastrusny

rsync를 사용하여 빠른 삭제-비슷한 경우에 대한 답변 -unix.stackexchange.com/questions/37329/…
kawu

모든 의견에 감사드립니다. 나는 답변을 작성하기 위해 찾은 것을 요약했습니다.
hyperknot

답변:


9

다음과 같이 bash 스크립트를 만드십시오.

#!/bin/bash
rm -- "$*"
sleep 0.5

deleter.sh예를 들어 이름으로 저장하십시오 . 실행 가능 chmod u+x deleter.sh하도록 실행하십시오 .

이 스크립트는 전달 된 모든 파일을 인수로 삭제 한 다음 0.5 초 동안 대기합니다.

그런 다음 실행할 수 있습니다

find cache.bak -print0 | xargs -0 -n 5 deleter.sh

이 명령은 cache.bak의 모든 파일 목록을 검색하고 한 번에 5 개의 파일 이름을 삭제 스크립트로 전달합니다.

따라서 한 번에 삭제되는 파일 수와 각 삭제 작업 사이의 지연 시간을 조정할 수 있습니다.


이 솔루션에 감사드립니다. 전반적인 글에 포함 시켰습니다. 그러나 한 가지 질문은 어떻게 큰 ns를 처리합니까? 일반적으로 큰 디렉토리에서 * 문자에 문제가 발생하여 오류가 발생했습니다.
hyperknot

xargs명령 행의 최대 크기를 이해하고 기본적으로이를 초과하지 않습니다. 이 경로에는 한 번에 5 개를 초과하지 않는 추가 제한이 있습니다.
BowlOfRed

1
초당 10 개 파일의 속도로 2 백만 개의 파일을 삭제하는 데 55 시간이 걸립니다.
Andrew Henle

4

주석에 언급 된대로 마운트 / 마운트 해제 할 수있는 별도의 파일 시스템에 캐시를 저장하는 것을 고려해야합니다. /usr/bin/find /path/to/files/ -type f -print0 -exec sleep 0.2 \; -exec echo \; -delete찾기 바이너리가 / usr / bin 아래에 있고 화면에서 진행률을보고 싶다고 가정 할 때까지이 하나의 라이너를 사용할 수 있습니다 . 그에 따라 수면을 조정하여 HDD에 과도한 스트레스를주지 않도록하십시오.


어디서나 -print0출력을 파이핑 하지 않기 때문에 여기에 필요하지 않습니다 find.
Tero Kilkanen

당신은 rm-ing에 관심이있을 수 있습니다. 그것을 편집증이라고 부르지 만 항상 올바른 파일을 삭제하고 싶습니다.
Alex

아 사실, 나는 명령을 올바르게 해독하지 못했다.
Tero Kilkanen

3

find 명령의 출력을 소비하는 스크립트에서 ionice를 시도 할 수 있습니다. 다음과 같은 것 :

ionice -c3 $(
for file in find cache.bak -type f; do
    rm $file
done
for dir in find cache.bak -depthe -type d -empty; do
    rmdir $dir
done
)

파일 시스템에 따라 각 파일을 삭제하면 해당 디렉토리 전체가 다시 작성 될 수 있습니다. 대히트 될 수있는 큰 디렉토리의 경우. inode 테이블에 추가 업데이트가 필요하며 여유 공간 목록이있을 수 있습니다.

파일 시스템에 저널이 있으면 변경 사항이 저널에 기록됩니다. 적용된; 저널에서 제거되었습니다. 이것은 쓰기 집약적 인 활동에 대한 I / O 요구 사항을 증가시킵니다.

캐시에 대한 저널없이 파일 시스템을 사용할 수 있습니다.

ionice 대신 sleep 명령을 사용하여 동작을 제한 할 수 있습니다. ionice가 작동하지 않더라도 작동하지만 모든 파일을 삭제하는 데 시간이 오래 걸립니다.


2

여기에 많은 유용한 답변 / 의견이 있으며 결론을 내리고 솔루션을 보여주고 싶습니다.

  1. 그렇습니다. 이런 일이 발생 하지 않도록 하는 가장 좋은 방법 은 캐시 디렉토리를 별도의 파일 시스템에 유지하는 것입니다. 파일 시스템의 Nuking / 빠른 포맷은 파일 / 디어의 수와 관계없이 항상 몇 초 (몇 분)가 소요됩니다.

  2. ionice/의 nice삭제 프로세스가 실제로 거의 I / O 발생하기 때문에 솔루션은 아무 짓도하지 않았다. I / O의 원인은 삭제 프로세스에 의해 파일이 너무 빨리 삭제 될 때 커널 / 파일 시스템 레벨 큐 / 버퍼가 채워 진다고 생각했기 때문입니다.

  3. 내가 해결 한 방법은 Tero Kilkanen의 솔루션과 비슷하지만 쉘 스크립트를 호출 할 필요는 없습니다. rsync의 내장 --bwlimit스위치를 사용 하여 삭제 속도를 제한했습니다.

전체 명령은 다음과 같습니다.

mkdir empty_dir
rsync -v -a --delete --bwlimit=1 empty_dir/ cache.bak/

bwlimit는 kilobyes 단위로 대역폭을 지정하며,이 경우 파일 이름 또는 파일 경로에 적용됩니다. 1KBps로 설정하면 시간당 약 100,000 개의 파일 또는 초당 27 개의 파일이 삭제되었습니다. 파일에는 cache.bak/e/c1/db98339573acc5c76bdac4a601f9ec1e47 자 길이의 상대 경로 가 있으므로 초당 1000/47 ~ = 21 파일을 제공하므로 시간당 100,000 파일을 추측하는 것과 비슷합니다.

--bwlimit=1? 나는 다양한 가치를 시도했다.

  • 10000, 1000, 100-> 이전과 같이 시스템 속도가 느려짐
  • 10-> 시스템은 한동안 꽤 잘 작동하지만 1 분에 한 번 정도 부분적으로 느려집니다. HTTP 응답 시간이 여전히 1 초 미만입니다.
  • 1-> 시스템 속도 저하가 전혀 없습니다. 나는 서두르지 않으며이 방법으로 2 백만 개의 파일을 <1 일 안에 삭제할 수 있으므로 선택합니다.

나는 rsync의 내장 메소드의 단순함을 좋아하지만이 솔루션은 상대 경로의 길이에 달려 있습니다. 대부분의 사람들이 시행 착오를 통해 올바른 가치를 발견 할 것이므로 큰 문제는 아닙니다.


"mv cache.dir-old / dev / null"
ivanivan
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.