폴더의 일부 파일을 이동하는 것이 전체 폴더를 이동하는 것보다 더 오래 걸리는 이유는 무엇입니까?


21

우분투 클라우드 서버에 수백만 개의 이미지가 있습니다. mv명령을 사용하여 1200 만 이미지가 포함 된 전체 폴더를 이동하면 거의 즉시 발생합니다. 그러나 mv(폴더가 아닌) 이미지 만 있으면 시간이 걸립니다. 모든 이미지를 폴더처럼 빠르게 이동할 수있는 방법이 있습니까?

이것은 일어나고 있습니다 :

  1. src 폴더에는 1200 만 개의 이미지가 있으며 이것을 사용하여 dst 폴더로 옮깁니다.

    $ mv  src ../dst
    

    즉시 일어난다

  2. src 폴더 내에서 이동하려면 다음과 같이하십시오.

    find -maxdepth 1 -name '*.jpg' -exec mv -t ../../dst/ {} +
    

    시간이 좀 걸립니다.

두 번째 프로세스 속도를 높일 수있는 방법이 있습니까?


1
해결책이 아니라 명확하게 : cmd2는 find를 사용하고 cmd1보다 느리고 결과에 대한 이동을 실행해야합니다. 사전 프로세스없이 직접 이동만큼 빠를 수는 없습니다.
dufte

아마도 dst파티션에 있고 ../../dst다른 파티션에 있을 것 입니다 .
phuclv 2016 년

작성된대로 이것은 유효한 찾기 호출처럼 보이지 않습니다. {}파일 이름이 확장되는 인수 가 없습니다 .
R ..

제목을 변경하는 편집을 제출하여 "이미지"에 대한 참조를 제거하고 중요한 이미지로 대체했습니다. 개별 파일을 이동하는 대신 전체 폴더를 이동하는 것입니다. 담당자가 그것을 받아들이기를 바랍니다.
Monty Harder 2016 년

1
의 올바른 호출이 아닙니다 find. 파일 당 한 번 find ... -exec mv -t ../../dst/ {} \;호출 mv합니다. find ... -exec mv -t ../../dest {} +호출 당 가능한 많은 파일을 가능한 빨리 복사하지만 dadexix86에서 설명한 대로 디렉토리 자체를 이동하는 것만 큼 빠르지는 않습니다 .
chepner 2016 년

답변:


50

TL; DR : 아니오

더 적은 양의 파일의 경우 필요하지 않을 것 find입니다.이 단순화되고 작은 경우에도

mv *.jpg ../../dst/

전체 디렉토리를 한 번에 이동하는 것보다 시간이 더 걸립니다.


왜? 요점은 무엇을 이해하는 것 mv입니다.

간단히 말해, mv숫자 (디렉토리 또는 파일을 식별하는 번호)를 inode (디렉토리가 포함 된 디렉토리)에서 다른 디렉토리로 옮기고이 색인은 파일 시스템의 저널 또는 FAT (파일 시스템의 경우)에서 업데이트됩니다. 그런 식으로 구현됩니다).

소스와 대상이 동일한 파일 시스템에있는 경우 실제 데이터 이동이 없으면 위치와 연결된 지점 만 변경합니다.

따라서 mv 하나의 디렉토리에서이 작업을 한 번 수행하고 있습니다 .

그러나 백만 개의 파일 을 이동 하면이 작업이 백만 번 수행 됩니다.

실제적인 예를 들기 위해 가지가 많은 나무가 있습니다. 특히, 1 백만 개의 지점이 연결된 하나의 노드가 있습니다.
이 가지를 잘라내어 다른 곳으로 옮기려면 각 가지를 잘라서 백만 번 잘라 내거나 노드 바로 앞을 잘라서 한 번만 잘라 내십시오 (파일 이동과 다른 점) 디렉토리).


4
mv동일한 파일 시스템에있는 것은 TOC 항목을 다시 작성하는 것만 포함해야합니다 .
Videonauth

TOC의 의미가 무엇인지 잘 모르겠습니다. 내가 아는 한, ext 파일 시스템, NTFS 또는 btrfs 등에는 테이블이 없습니다. FAT에는 테이블 (이름이 사용됨)이 있지만 ext는 이름과 블록, 부모, 자식 및 기타 정보를 inode에 저장합니다. 당신이 내선 FS가 TOC와 무엇을 위해 사용되는이 할이 설명 일부 참조 날 지점 수 있다면, 나는 기꺼이 :) 읽고 답을 업데이 트됩니다
dadexix86

10
mv *.jpg1200 만 개의 파일이 실패 할 가능성이 높으므로 find를 사용합니다. 대부분의 유닉스, 리눅스는 내가 누군가가 지난 5-10 년 동안 그것을 바꾸지 않는 한 최대 명령 길이가 제한되어 있다고 생각했다. Linux의 경우 오랫동안 64K라고 생각합니다. 환경 변수에도 동일한 제한이 적용됩니다.
Zan Lynx

1
파일 이동은 파일 이름 이동에 관한 것 입니다. 유닉스 계열 디렉토리 항목은 파일 이름과 아이 노드 번호를 포함하는데, 이는 기본적으로 나머지 메타 데이터를 가리키는 포인터입니다. 디렉토리는 특별한 종류의 파일입니다. 아이 노드 자체는 파일의 실제 데이터를 포함하지 않고 단지 파일을 가리키는 포인터이므로 아이 노드에서 어떤 것이 이동되었다고 말하는 것은 약간 오해의 소지가 있습니다. 반면, 파일 시스템 저널은 일반적으로 충돌 방지에 주로 사용되는 메타 데이터 로그 유형을 나타냅니다.
ilkkachu 2016 년

1
물론이 용어는 여기서 중요한 요점이 아닙니다. 중요한 것은 정확히 말한 것입니다. 파일 시스템 내에서 이동은 메타 데이터 만 터치하면됩니다. 하나의 파일 시스템에서 다른 파일 시스템으로 바로 가기가 없으며 모든 파일을 내용을 포함하여 하나씩 이동 (재 작성)해야합니다. 이 경우 전체 디렉토리를 이동하거나 내부의 파일 만 이동하더라도 문제가되지 않습니다.
ilkkachu 2016 년

13

언급 한 바와 같이 파일 시스템은 각 파일 이름을 새 위치에 다시 연결해야하기 때문에 여전히 느립니다.

그러나 지금 가지고있는 것보다 속도를 높일 수 있습니다.

find 명령은 각 파일마다 한 번씩 exec를 실행합니다. 따라서 mv1200 만 파일에 대해 1,200 만 번 명령을 실행 합니다. 이것은 두 가지 방식으로 향상 될 수 있습니다.

  • 끝에 더하기 추가 :
    find -maxdepth 1 -name '*.jpg' -exec mv -t ../../dst/ +
    맨 페이지를 확인하여 사용중인 버전에서 지원되는지 확인하십시오 find. 효과는 mv각 명령 줄에 맞는 수의 파일 이름으로 일련의 명령 을 실행하는 것입니다.

  • 사용 findxargs함께.
    find -maxdepth 1 -name '*.jpg' -print0 | xargs -0 mv -t ../../dst/
    -print0파일 이름을 구분하기 위해 0 바이트 일명, NUL을 사용합니다. 이 플러스 는 그렇지 않으면 파일 이름에 공백으로 xargs -0발생하는 모든 문제를 해결합니다 xargs. xargs명령에서 파일 이름의 목록을 읽어 find명령을하고 실행 mv에 맞게됩니다 많은 파일 이름으로에 명령을.


7

혼란은 파일 시스템 추상화에서 비롯되어 폴더에는 파일과 다른 폴더가 트리와 같은 방식으로 포함되어 있다고 생각합니다. 이것은 실제로 사실이 아닙니다. 파일 시스템 내의 모든 파일과 디렉토리는 동일한 레벨에 있으며 구현에 따라 여러 종류로 식별됩니다. 디렉토리는 다른 파일 목록을 포함하는 특수 파일입니다.

파일 시스템 내에서 파일을 "이동"하면 실제 파일은 어디에도 가지 않습니다. 오히려 디렉토리 내부의 목록이 변경 사항을 반영하여 업데이트됩니다.

mv src ../dst디렉토리에서 디렉토리 .로 단일 목록 항목을 이동 ../dst하므로 빠릅니다.

find -maxdepth 1 -name '*.jpg' -exec mv -t ../../dst/수백만 개의 항목을 이동해야하므로 속도가 느립니다. mv파일 당 한 번만 호출 하고 한 번만 호출 하지 않으면 속도가 빨라질 mv수 있으며 명령 자체가 한 번에 여러 디렉토리 항목을 이동하도록 최적화 될 수 있지만 단일 디렉토리를 이동할 때만 큼 빠르게 수행 할 수있는 방법은 없습니다 .


4

간단한 답변

파일 이동은 3 단계입니다.

  • 대상 폴더의 inode 목록에 파일에 대한 링크를 추가하십시오.
  • 링크가 성공적으로 추가되었는지 확인
  • 위의 확인이 성공한 경우 소스 폴더의 inode 목록에서 링크를 제거하십시오.

이 프로세스는 파일 또는 폴더에 대해 동일합니다.
1 파일에 대해이 작업을 수행하는 것이 100 파일에 대해 수행하는 것보다 100 빠릅니다.

man link add ()
man unlink는 remove ()가
mv위의 두 명령을 사용하고 중간에 검사를 추가하여 데이터 손실을 방지합니다.


1
또한 rename ()도 있습니다.
ilkkachu 2016 년
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.