우리는 임의의 컬렉션을 압축하여 서비스로 제공할 수 있다는 목표로 수백만 개의 텍스트 파일을 Linux 파일 시스템에 저장하려고 합니다. 키/값 데이터베이스와 같은 다른 솔루션을 시도했지만 동시성 및 병렬성에 대한 요구 사항으로 인해 기본 파일 시스템을 사용하는 것이 최선의 선택이었습니다.
가장 간단한 방법은 모든 파일을 폴더에 저장하는 것입니다.
$ ls text_files/
1.txt
2.txt
3.txt
어느EXT4 파일 시스템에서 작동해야 함, 폴더의 파일 수에는 제한이 없습니다.
두 개의 FS 프로세스는 다음과 같습니다.
- 웹에서 스크랩하여 텍스트 파일에 씁니다(폴더의 파일 수에 영향을 받지 않아야 함).
- 파일 이름 목록에 따라 선택한 파일을 압축합니다.
내 질문은 하나의 폴더에 최대 천만 개의 파일을 저장하면 위 작업의 성능이나 일반적인 시스템 성능에 영향을 미치나요? 파일이 있는 하위 폴더 트리를 만드는 것과 다른가요?
답변1
이것은 의견 기반 질문/답변에 매우 가깝지만 몇 가지 사실과 내 의견을 제공하려고 노력할 것입니다.
- 폴더에 많은 수의 파일이 있는 경우 해당 파일을 열거하려는 셸 기반 작업(예:
mv * /somewhere/else
)이 와일드카드를 성공적으로 확장하지 못하거나 결과가 너무 커서 사용할 수 없을 수 있습니다. ls
많은 수의 파일을 열거하는 것은 적은 수의 파일을 열거하는 것보다 시간이 더 오래 걸립니다.- 파일 시스템은 단일 디렉터리에서 수백만 개의 파일을 처리할 수 있지만 사람들은 어려움을 겪을 수 있습니다.
한 가지 제안은 파일 이름을 2, 3, 4개의 문자 단위로 분할하여 하위 디렉터리로 사용하는 것입니다. 예를 들어 숫자 이름을 사용하는 경우 왼쪽에서 오른쪽으로 분할하는 대신 오른쪽에서 왼쪽으로 분할하여 분포가 더 균등하게 somefilename.txt
저장될 수 있습니다 . 예 를 som/efi/somefilename.txt
들어 .12345.txt
345/12/12345.txt
동등한 zip -j zipfile.zip path1/file1 path2/file2 ...
.
웹 서버에서 이러한 파일을 제공하는 경우(이것이 관련성이 있는지 확실하지 않음) Apache2의 다시 쓰기 규칙을 사용하여 가상 디렉터리를 위해 이 구조를 숨기는 것이 쉽습니다. Nginx도 마찬가지라고 생각합니다.
답변2
명령 ls
, 심지어 쉘의 TAB 완성 또는 와일드카드 확장도 일반적으로 결과를 영숫자 순서로 표시합니다. 이를 위해서는 전체 디렉토리 목록을 읽고 정렬해야 합니다. 단일 디렉터리에 있는 천만 개의 파일에 대해 이 정렬 작업은 무시할 수 없는 시간이 걸립니다.
압축하려는 파일의 전체 이름을 쓰는 등 TAB 완료에 대한 충동을 억제할 수 있다면 문제가 없을 것입니다.
와일드카드의 또 다른 문제는 와일드카드 확장으로 인해 명령줄의 최대 길이보다 더 많은 파일 이름이 생성될 수 있다는 것입니다. 일반적인 최대 명령줄 길이는 대부분의 경우 충분하지만 단일 디렉터리에 있는 수백만 개의 파일에 대해 이야기할 때 이는 더 이상 안전한 가정이 아닙니다. 와일드카드 확장이 최대 명령줄 길이를 초과하면 대부분의 쉘은 전체 명령줄을 실행하지 않고 실패합니다.
이 문제는 다음을 사용하여 와일드카드 작업을 수행하여 해결할 수 있습니다 find
.
find <directory> -name '<wildcard expression>' -exec <command> {} \+
또는 가능하면 유사한 구문을 사용하십시오. 최대 명령줄 길이는 자동으로 고려 되며 find ... -exec ... \+
각 명령줄에 최대 파일 이름 수를 맞추는 동안 필요한 만큼 명령이 실행됩니다.
답변3
저는 영화, TV, 비디오 게임 데이터베이스를 관리하는 웹사이트를 운영하고 있습니다. 이들 각각에 대해 TV에는 여러 이미지가 있으며 각 프로그램에는 수십 개의 이미지(예: 에피소드 스냅샷 등)가 포함되어 있습니다.
결국에는 많은 이미지 파일이 생성됩니다. 250,000+ 범위. 이는 합리적인 액세스 시간으로 마운트된 블록 저장 장치에 저장됩니다.
이미지를 저장하려는 첫 번째 시도는 폴더에 있었습니다./mnt/images/UUID.jpg
나는 다음과 같은 문제에 직면했습니다.
ls
원격 터미널을 통해 그냥 중단됩니다. 프로세스는 단단해지며CTRL+C
깨지지 않습니다.- 해당 지점에 도달하기 전에 모든
ls
명령은 출력 버퍼를 빠르게 채우고CTRL+C
끝없는 스크롤을 멈추지 않습니다. - 폴더에서 250,000개의 파일을 압축하는 데 약 2시간이 걸립니다. 터미널과 별도로 zip 명령을 실행해야 합니다. 그렇지 않으면 연결이 중단되면 다시 시작해야 합니다.
- Windows에서 zip 파일을 사용하려고 시도할 위험은 없습니다.
- 폴더는 곧인간의 허락 없이구역.
결국 하위 폴더에 파일을 저장할 경로를 만드는 데 생성 시간을 사용해야 했습니다. 예를 들어 /mnt/images/YYYY/MM/DD/UUID.jpg
. 이를 통해 위의 모든 문제가 해결되고 날짜별 zip 파일을 생성할 수 있습니다.
고유 식별자가 숫자인 파일이 있고 해당 숫자는 순차적으로 실행되는 경향이 있습니다. 100000
, 및 으로 10000
그룹화하면 어떨까요 1000
?
예를 들어, path라는 파일이 있는 경우 384295.txt
:
/mnt/file/300000/80000/4000/295.txt
알았더라면 수백만 명에 이르렀을 것입니다. 0
1,000,000개의 접두사 사용
/mnt/file/000000/300000/80000/4000/295.txt
답변4
웹에서 스크랩하여 텍스트 파일에 씁니다(폴더의 파일 수에 영향을 받지 않아야 함).
새 파일을 생성하려면 디렉터리 파일을 검색하여 새 디렉터리 항목을 위한 충분한 빈 공간을 찾아야 합니다. 새 디렉토리 항목을 저장할 공간이 충분하지 않으면 디렉토리 파일 끝에 배치됩니다. 디렉터리의 파일 수가 증가하면 디렉터리를 검색하는 데 걸리는 시간도 늘어납니다.
카탈로그 파일이 시스템 캐시에 남아 있는 한 성능에 미치는 영향은 나쁘지 않지만, 데이터가 해제된 경우 디스크에서 카탈로그 파일(일반적으로 조각화됨)을 읽는 데 상당한 시간이 소비될 수 있습니다. SSD는 이를 개선하지만 수백만 개의 파일이 포함된 디렉터리의 경우 여전히 눈에 띄는 성능 영향을 미칠 수 있습니다.
파일 이름 목록에 따라 선택한 파일을 압축합니다.
수백만 개의 파일이 포함된 디렉터리에서는 추가 시간이 필요할 수도 있습니다. 해시된 디렉터리 항목(예: EXT4)이 있는 파일 시스템에서는 이러한 차이가 작습니다.
폴더에 최대 1,000만 개의 파일을 저장하면 위 작업 성능이나 일반적인 시스템 성능에 영향을 미치나요? 파일이 있는 하위 폴더 트리를 만드는 것과 다른가요?
하위 폴더 트리에는 위에서 언급한 성능 단점이 발생하지 않습니다. 또한 기본 파일 시스템이 해시된 파일 이름을 갖지 않도록 변경된 경우에도 트리 접근 방식은 여전히 잘 작동합니다.