와일드카드 일치를 수행해야 할 때 단일 디렉터리에 있는 수십만 개의 파일에서 성능 문제가 발생합니다. 내 응용 프로그램의 관점에서 볼 때 간단한 해결책은 파일을 깊게 중첩된 폴더에 배치하는 것입니다.
전체 계층 구조의 총 폴더 수에 대한 예상 상한은 9^30입니다. 이 한도에 도달한 적이 없다고 가정할 수 있습니다(아래 설명 참조). 파일이 추가될수록 폴더 수는 늘어납니다.
질문: ext4 파일 시스템에 많은 수의 폴더를 생성할 때 파일 시스템 관점에서 어떤 영향이 있습니까? 예를 들어, 얼마나 많은 공간이 소비되는지입니다. 다른 폴더만 포함된 폴더? 메타데이터가 너무 많으면 문제가 발생합니까?
(내 응용 프로그램의 관점에서 볼 때 위의 구조는 더 간단한 계층 구조의 해시 기반 폴더에 비해 특정 이점이 있으며 데이터를 구성하는 "더 나은" 방법을 알고 있습니다.)
답변1
각 폴더는 하나의 inode(256바이트)와 최소 하나의 블록(4096바이트)을 차지합니다. 더 큰 문제는 여러 계층 구조 수준의 액세스 시간일 수 있습니다.
성능 문제는 폴더 크기가 아니라 경로 이름 확장으로 인해 발생할 수 있습니다. 경로 이름 확장에는 두 가지 문제가 있습니다.
- 결과를 정렬합니다(비활성화할 수 없음). 이는 많은 수의 프로젝트에 대해 불편할 정도로 오랜 시간이 걸립니다.
- (사용 유형에 따라) 잘못된 명령줄(항목이 너무 많음)을 생성합니다.
이 문제는 애플리케이션 수준에서 해결해야 합니다. 한 번에 100개의 파일 이름을 읽고(정렬되지 않음, find
또는 사용 ls -U
) 필요한 경우 그룹을 정렬합니다. 또한 디스크 및 CPU 사용량을 병렬로 읽을 수 있습니다.
경로 이름 확장 및/또는 정렬이 정말로 필요한 경우 파일을 해당 (빈) 디렉터리에 정렬된 순서로 추가하여 프로세스 속도를 크게 높일 수 있습니다(파일이 거의 변경되지 않는 경우).
답변2
Ext4는 이전 버전보다 큰 디렉토리를 약간 더 잘 처리하지만 동일한 디렉토리에 10,000개 정도의 파일이 있으면 여전히 정체될 수 있습니다. 디렉터리 계층 구조에서 여러 수준으로 파일을 분리하는 것은 성능을 유지하기 위한 일반적인 솔루션입니다. 각 깊이 증가에는 파일을 찾을 때 추가 간접 참조가 필요하지만 너비는 깊이에 따라 기하급수적으로 증가합니다.
예를 들어, 파일 이름이 문자, 숫자 및 일부 구두점으로만 구성된 경우 이를 모두 동일한 디렉터리에 배치하는 대신 파일 이름의 처음 두 문자를 기반으로 하위 디렉터리를 만듭니다. 즉, 파일은 foobar
에 저장됩니다 fo/foobar
. 하위 디렉터리에 여전히 파일이 너무 많으면 깊이를 늘리세요 fo/ob/foobar
. 분할할 문자 수와 중지할 깊이를 결정하려면 벤치마크를 수행해야 합니다.
잠재적인 디렉토리는 많지만 대부분은 비어 있게 됩니다. 따라서 처음부터 모든 디렉토리를 생성하지 말고 필요에 따라 생성하십시오. 예를 들어 파일을 생성해야 하는 경우 foobar
디렉토리가 fo
아직 없으면 생성한 다음 으로 동일한 작업을 수행한 fo/ba
다음 foobar
에 저장합니다 fo/ba/foobar
.
파일이 매우 작지 않은 한(4kB 미만) 디렉터리가 차지하는 공간은 무시할 수 있습니다. 파일이 작더라도 깊이가 과도하지 않은 한 디렉터리에는 파일보다 훨씬 적은 수의 파일이 포함됩니다. 그러나 작은 파일이 많으면 데이터베이스를 사용해야 합니다.