파일 시스템에 백만 개의 이미지 저장


79

엄청난 수의 이미지를 생성하는 프로젝트가 있습니다. 시작시 약 1,000,000 그들은 큰 이미지가 아니므로 시작할 때 하나의 머신에 모두 저장합니다.

이러한 이미지를 효율적으로 저장하는 데 어떻게 권장됩니까? (현재 NTFS 파일 시스템)

이름 지정 체계를 고려하고 있습니다 ... 시작하려면 모든 이미지의 이름이 1부터 증가합니다. 필요한 경우 나중에 정렬하고 다른 폴더에 넣는 데 도움이되기를 바랍니다.

더 나은 명명 체계는 무엇입니까?

a / b / c / 0 ... z / z / z / 999

또는

a / b / c / 000 ... z / z / z / 999

이것에 대한 아이디어가 있습니까?


1
그들은 특정 사용자 또는 일반에 묶여 있습니까? 그들은 어떤 방식으로 그룹화되어 있습니까?

단지 일반. 일부 기술 장비에서 생성 된 많은 이미지. 나는 시간 참조를 생각하기 위해 1에서 증분으로 명명합니다.
s.mihai

그것들은 어떻게 사용 / 접근하게됩니까? 맞춤형 앱 또는 무엇을 통해?
비둘기

16

1
:)) 그렇습니다 ... 1 밀. porn images :))
s.mihai

답변:


73

데이터베이스 대신 일반 파일 시스템을 사용하는 것이 좋습니다. 파일 시스템을 사용하는 것이 데이터베이스보다 쉬우 며, 일반 도구를 사용하여 파일에 액세스 할 수 있으며, 파일 시스템은 이러한 종류의 용도 등을 위해 설계되었습니다. NTFS는 스토리지 시스템으로서 잘 작동합니다.

데이터베이스의 실제 경로를 저장하지 마십시오. 이미지의 시퀀스 번호를 데이터베이스에 저장하는 것이 좋으며 시퀀스 번호에서 경로를 생성 할 수있는 기능이 있습니다. 예 :

 File path = generatePathFromSequenceNumber(sequenceNumber);

디렉토리 구조를 일부 변경해야하는 경우 처리하기가 더 쉽습니다. 이미지를 다른 위치로 이동해야 할 수도 있고 공간이 부족하여 디스크 A와 디스크 B에 이미지를 저장하기 시작할 수도 있습니다. 데이터베이스의 경로를 변경하는 것보다 하나의 기능을 변경하는 것이 더 쉽습니다. .

디렉토리 구조를 생성하기 위해 이러한 종류의 알고리즘을 사용합니다.

  1. 먼저 12 자리 이상의 문자열이 나올 때까지 숫자를 앞에 0으로 채 웁니다. 파일 이름입니다. 접미사를 추가 할 수 있습니다.
    • 12345 -> 000000012345.jpg
  2. 그런 다음 문자열을 2 개 또는 3 개의 문자 블록으로 분할하십시오. 여기서 각 블록은 디렉토리 레벨을 나타냅니다. 고정 된 디렉토리 레벨 수를 가져 오십시오 (예 : 3).
    • 000000012345 -> 000/000/012
  3. 파일을 생성 된 디렉토리에 저장하십시오.
    • 따라서 시퀀스 ID를 가진 파일의 전체 경로와 파일 파일 이름 123000/000/012/00000000012345.jpg
    • 시퀀스 ID를 가진 파일의 12345678901234경우 경로는123/456/789/12345678901234.jpg

디렉토리 구조 및 파일 스토리지에 대해 고려해야 할 사항 :

  • 위의 알고리즘은 모든 리프 디렉토리에 최대 1000 개의 파일이있는 시스템을 제공합니다 (총 파일 수가 10,000 개 미만인 경우)
  • 디렉토리에 포함 할 수있는 파일 및 서브 디렉토리 수에는 제한이있을 수 있습니다. 예를 들어 Linux의 ext3 파일 시스템 은 한 디렉토리 당 31998 개의 서브 디렉토리로 제한됩니다.
  • 디렉토리 당 파일 수가 많은 경우 일반 도구 (WinZip, Windows 탐색기, 명령 줄, bash 쉘 등)가 제대로 작동하지 않을 수 있습니다 (> 1000).
  • 디렉토리 구조 자체는 약간의 디스크 공간을 차지하므로 너무 많은 디렉토리를 원하지 않습니다.
  • 위의 구조를 사용하면 디렉토리 구조를 엉망으로 만드는 경우 파일 이름을보고 이미지 파일의 올바른 경로를 항상 찾을 수 있습니다.
  • 여러 시스템에서 파일에 액세스해야하는 경우 네트워크 파일 시스템을 통해 파일을 공유하십시오.
  • 많은 파일을 삭제하면 위의 디렉토리 구조가 작동하지 않습니다. 디렉토리 구조에 "구멍"을 남깁니다. 그러나 파일을 삭제하지 않기 때문에 괜찮습니다.

1
매우 흥미로운! 파일 이름을 나누는 중 ... 나는 그것을 생각하지 못했습니다. 나는 이것이 우아한 방법이라고 생각합니다 :-?
s.mihai

37
디렉토리 배포뿐만 아니라 파일 이름으로 해시 (예 : MD5)를 사용하면 작동합니다. 파일의 무결성은 이름 지정 체계 (쉽게 확인)의 부수적 인 이점 일뿐만 아니라 디렉토리 계층 전체에 합리적으로 분배됩니다. "f6a5b1236dbba1647257cc4646308326.jpg"라는 파일이 있으면 "/ f / 6"(또는 필요한 깊이)에 파일을 저장합니다. 2 단계 깊이는 256 개의 디렉토리를 제공하거나 초기 1m 파일에 대해 디렉토리 당 4000 개의 파일을 제공합니다. 또한 재분배를 더 깊은 체계로 자동화하는 것은 매우 쉽습니다.

+1이 답변이 방금 게시 한 답변과 비슷하다는 것을 알았습니다.
3dinfluence 2009

1
파일 시스템을 사용하고 폴더 이름으로 "슬라이스"하기위한 인공 식별자를 만드는 데 동의합니다. 그러나 임의의 식별자 분포를 얻으려고 노력해야합니다. 즉, 시퀀스 번호를 사용하지 마십시오. 그러면 균형 잡힌 폴더 트리가 생길 수 있습니다. 또한 임의 배포를 사용하면 여러 파일 시스템에서 트리를보다 쉽게 ​​분할 할 수 있습니다. 또한 중복 제거 기능이 켜져 있고 각 파일 시스템에 대해 스파 스 볼륨이있는 ZFS 기반 SAN을 사용합니다. iSCSI를 사용하여 SAN에 액세스하여 NTFS를 계속 사용할 수 있습니다.
Michael Dillon

2 단계에서 오른쪽에서 왼쪽으로 이동하면 파일이 고르게 분산됩니다. 또한 파일 수를 무제한으로
늘릴

31

나는 2 센트의 가치를 부정적인 조언에 넣을 것입니다 : 데이터베이스와 함께 가지 마십시오.

나는 수년 동안 이미지 저장 데이터베이스를 사용해 왔습니다. 큰 (1 메가-> 1 기가) 파일, 종종 변경, 여러 버전의 파일, 합리적으로 자주 액세스하는 파일. 큰 파일을 저장하는 중에 발생하는 데이터베이스 문제는 처리하기가 매우 지루하고 쓰기 및 트랜잭션 문제가 까다로워 심각한 열차 사고를 일으킬 수있는 잠금 문제가 발생합니다. dbcc 스크립트를 작성하고 일반 사람보다 백업에서 테이블을 복원하는 데 더 많은 연습 있습니다.

필자가 작업 한 대부분의 최신 시스템은 파일 스토리지를 파일 시스템으로 푸시했으며 색인 작업 외에는 데이터베이스에 의존하지 않았습니다. 파일 시스템은 이러한 종류의 남용을 처리하도록 설계되었으며 확장하기가 훨씬 쉽고 한 항목이 손상되면 전체 파일 시스템을 거의 잃지 않습니다.


예. 참고!
s.mihai

5
SQL 2008의 FILESTREAM 데이터 유형을 살펴 보셨습니까? 데이터베이스와 파일 시스템 스토리지 사이의 교차점입니다.
NotMe

빠르고 빈번한 IO 작업을 수행 할 때 데이터베이스가 아닌 파일 서버를 사용하는 경우 +1

데이터베이스 당 수백 개의 문서 또는 사진을 저장하는 경우 데이터베이스를 스토리지로 사용하는 데 단점이 있습니까?
삐 삐 소리

1
+1 ... 파일 시스템은 어쨌든 일종의 "데이터베이스"(ntfs)이므로 너무 복잡하게 만드는 이유는 무엇입니까?
akira

12

이 문제를 처리해야하는 대부분의 사이트는 파일이 폴더에 고르게 분산되도록하기 위해 일종의 해시를 사용한다고 생각합니다.

따라서 다음과 같은 파일의 해시가 515d7eab9c29349e0cde90381ee8f810
있다고 가정하십시오. 다음 위치에 저장하면 각 폴더의 파일 수를 낮게 유지하는 데 필요한 수준을 얼마나 많이 사용할 수 있습니까?
\51\5d\7e\ab\9c\29\349e0cde90381ee8f810.jpg

이 접근 방식이 여러 번 수행되는 것을 보았습니다. 이러한 파일 해시를 사람이 읽을 수있는 이름과 저장해야 할 다른 메타 데이터에 매핑하려면 여전히 데이터베이스가 필요합니다. 그러나이 접근 방식은 여러 컴퓨터와 스토리지 풀 사이에 해시 주소 공간을 분배 할 수 있기 때문에 꽤 잘 확장됩니다.


2
힘내는 비슷한 접근 방식을 사용합니다 : git-scm.com/book/en/v2/Git-Internals-Git-Objects (이 답변을 뒷받침하기 위해)
aexl

11

이상적으로는 특정 하드 드라이브 설정, 캐싱, 사용 가능한 메모리 등이 이러한 결과를 변경할 수 있으므로 다양한 구조에 대한 임의 액세스 시간에 대해 일부 테스트를 실행해야합니다.

파일 이름을 제어한다고 가정하면 디렉토리 당 1000 레벨로 파일 이름을 분할합니다. 디렉토리 레벨이 많을수록 더 많은 inode를 태우므로 여기에 푸시 풀이 있습니다.

예 :

/ root / [0-99] / [0-99] / 파일 이름

참고 http://technet.microsoft.com/en-us/library/cc781134(WS.10).aspx는 NTFS 설정에 대한 자세한 내용이 있습니다. 특히 "NTFS 폴더 (300,000 이상)에서 많은 수의 파일을 사용하는 경우 짧은 파일 이름 생성을 비활성화하여 성능을 향상 시키십시오. 특히 긴 파일 이름의 처음 6자가 비슷한 경우"

또한 필요하지 않은 파일 시스템 기능 (예 : 마지막 액세스 시간)을 비활성화해야합니다. http://www.pctools.com/guides/registry/detail/50/


3
8.3 파일 이름 생성 및 마지막 액세스 시간을 비활성화하려면 +1; "거대한 수의 [파일]"과 "NTFS"(Windows)를 읽을 때 가장 먼저 떠 올랐던 것이 었습니다.
rob

link down ........................
Pacerier

7

무엇을하든 한 디렉토리에 모두 저장하지 마십시오.

이러한 이미지 이름의 분포에 따라 단일 문자 최상위 폴더가있는 디렉토리 구조를 만들 수 있습니다.이 폴더에는 두 번째 이미지 문자 등의 하위 폴더가 있습니다.

그래서:

폴더 img\a\b\c\d\e\f\g\에는 'abcdefg'로 시작하는 이미지가 포함됩니다.

필요한 적절한 깊이를 소개 할 수 있습니다.

이 솔루션의 가장 큰 장점은 디렉토리 구조가 해시 테이블 / 사전처럼 효과적으로 작동한다는 것입니다. 이미지 파일 이름이 주어지면 디렉토리를 알 수 있고 디렉토리가 주어지면 이미지의 하위 집합을 알 수 있습니다.


\ a \ b \ c \ d \ e \ f \ 지금하고 있습니다. 현명한 방법이 있다고 생각했습니다.
s.mihai

1
물리적으로 저장하는 방법에 대해 일반적으로 인정되는 솔루션입니다. 이미지 URL을 명확하게 생성하는 것은 이미지 파일 이름을 기반으로 동적으로 쉽게 수행 할 수있는 작업입니다. 또한 원하는 경우 이미지 서버에 img-a, img-b 하위 도메인을 도입하여로드 시간을 단축 할 수도 있습니다.

2
"하나의 디렉토리에 모두 저장하지 마십시오"는 +1입니다. 단일 폴더의 서버에 47000 개가 넘는 파일을 넣은 레거시 시스템을 지원하고 있으며 탐색기에서 폴더를 여는 데 약 1 분이 걸립니다.
Mark Ransom

5
a \ b \ c \ d \ e \ f \ g를 수행하면 디렉토리 구조가 매우 깊어지고 모든 디렉토리에 파일이 거의 없습니다. 디렉토리 레벨 당 하나 이상의 문자를 사용하는 것이 좋습니다 (예 : ab \ cd \ ef \ 또는 abc \ def \). 디렉토리는 디스크에서 공간을 차지하므로 너무 많이 원하지 않습니다.
Juha Syrjälä 2009

2
한 디렉토리에 4 백만 개 이상의 파일이있는 응용 프로그램을 지원해야했습니다. 놀랍도록 잘 작동했지만 탐색기에서 폴더를 열 수는 없었으며 계속해서 새로운 추가 항목을 정렬했습니다. NTFS가 죽지 않고 처리 할 수있는 경우 +1
SqlACID

5

파일 시스템에 저장하지만 파일 수가 얼마나 빨리 증가하는지에 달려 있습니다. 이 파일들은 웹에서 호스팅됩니까? 이 파일에 몇 명의 사용자가 액세스합니까? 더 나은 추천을하기 전에 답변해야 할 질문들이 있습니다. 또한 Facebook의 Haystack을 살펴볼 것입니다. 이미지를 저장하고 제공하는 데 매우 유용한 솔루션이 있습니다.

또한 파일 시스템을 선택하면 이러한 파일을 디렉토리로 분할해야합니다. 나는이 문제를보고 해결책을 제안했지만 결코 완벽한 해결책은 아닙니다. 해시 테이블 및 사용자별로 분할하여 내 블로그에서 더 많은 내용을 읽을 수 있습니다 .


이미지는 자주 액세스하기위한 것이 아닙니다. 따라서 아무런 문제가 없습니다. 그들의 숫자는 매우 빠르게 성장할 것입니다. 나는 1mil이있을 것이라고 가정합니다. 1 개월 안에 표시합니다.
s.mihai

나는 이것을 너무 많이 생각하지 않도록 프로그래머 관점에 관심이있다
s.mihai

따라서 빠른 액세스가 필요하지 않은 경우 Haystack이 적합하지 않을 수 있습니다. 파티션에 디렉토리를 사용하는 것이 제 생각에 가장 간단한 해결책입니다.
Lukasz

5

4 백만 개의 이미지가있는 사진 저장 시스템이 있습니다. 우리는 메타 데이터에 대해서만 데이터베이스를 사용하고 모든 이미지는 파일 이름의 마지막 숫자, 마지막 1 등에서 폴더 이름이 생성되는 역 명명 시스템을 사용하여 파일 시스템에 저장됩니다. 예 : 000001234.jpg는 4 \ 3 \ 2 \ 1 \ 000001234.jpg와 같은 디렉토리 구조에 저장됩니다.

이 체계는 전체 디렉토리 구조를 균등하게 채우므로 데이터베이스의 ID 색인과 매우 잘 작동합니다.


4

요점은 DB에 파일 경로를 저장할 필요가 없다는 것입니다. 설명 된 방식으로 파일 이름이 지정된 경우 숫자 값만 저장할 수 있습니다. 그런 다음 이미 논의 된 잘 정의 된 스토리지 체계 중 하나를 사용하여 색인을 숫자로 가져와 디렉토리 구조를 순회하여 파일을 매우 빠르게 찾을 수 있습니다.


:-? 좋은 빠른 포인트. 이제는 경로를 생성하는 알고리즘이 없습니다.
s.mihai


4

이미지 이름을 고유하게 지정해야합니까? 이러한 이미지를 생성하는 프로세스가 동일한 파일 이름을 두 번 이상 생성 할 수 있습니까? 어떤 장치가 파일 이름을 만들고 있는지 알지 못하지만 장치가 '재설정'되었다고 말하면 다시 시작하면 마지막으로 '재설정'했던 것처럼 이미지의 이름이 지정되기 시작합니다.

또한 한 달에 100 만 장의 이미지를 기록 할 것이라고 말합니다. 그 후는 어떻습니까? 이 이미지가 파일 시스템을 얼마나 빨리 채우는가? 어느 시점에서 최고 1 백만 장의 TOTAL 이미지로 레벨을 올리 거나 매월 계속 성장하고 성장할 것인가?

월별로, 이미지별로 파일 시스템 설계를 시작할 수 있기 때문에 묻습니다. 그러한 디렉토리 구조에 이미지를 저장하는 것이 좋습니다.

imgs\yyyy\mm\filename.ext

where: yyyy = 4 digit year
         mm = 2 digit month

example:  D:\imgs\2009\12\aaa0001.jpg
          D:\imgs\2009\12\aaa0002.jpg
          D:\imgs\2009\12\aaa0003.jpg
          D:\imgs\2009\12\aaa0004.jpg
                   |
          D:\imgs\2009\12\zzz9982.jpg
          D:\imgs\2010\01\aaa0001.jpg (this is why I ask about uniqueness)
          D:\imgs\2010\01\aab0001.jpg

월, 년, 심지어는 낮에도 보안 유형 이미지에 적합합니다. 이것이 당신이하는 일인지 확실하지 않지만 10 초마다 사진을 찍는 가정 보안 카메라로 그렇게했습니다 ...이 방법으로 응용 프로그램은 특정 시간이나 이미지가 생성되었다고 생각할 수있는 범위까지 드릴 다운 할 수 있습니다 . 또는 연도 대신 월-이미지 파일 자체에서 파생 될 수있는 다른 "의미"가 있습니까? 내가 준 날짜 예제 이외의 다른 설명자?

이진 데이터를 DB에 저장하지 않습니다. 그런 종류의 물건으로 좋은 성능 / 행운을 얻지 못했습니다. 캔 트는 백만 개의 이미지로 잘 작동한다고 상상해보십시오. 파일 이름을 저장하면 바로 그 것입니다. 그들이 모두 JPG가 될 경우 확장을 저장하지 마십시오. 파일의 서버, 드라이브, 경로 등에 대한 포인터를 저장 한 제어 테이블을 작성합니다.이 방법으로 해당 이미지를 다른 상자로 이동하고 여전히 찾을 수 있습니다. 이미지에 키워드 태그를 추가해야합니까? 그렇다면 그런 종류의 태깅을 허용하는 적절한 테이블을 작성하려고합니다.

내가 답장을하는 동안 귀하 / 다른 사람들이 이러한 아이디어를 해결했을 수도 있습니다. 도움이 되길 바랍니다 ..


1. 모든 파일의 이름이 고유하게 지정됩니다. 2. 시스템이 처음에는 커지고 커질 것입니다. 3. 향후 어느 시점에서 파일에 일종의 태그가있을 것이므로 DB에 일종의 식별 데이터를 저장하고 싶습니다.
s.mihai

3

다양한 장치의 상태를 문서화하기 위해 일년 동안 810 만 개의 이미지를 저장하는 프로젝트에 참여하고 있습니다. 더 최근의 이미지는 더 자주 액세스되며, 누군가가 아카이브를 파고 드는 조건이 발견되지 않는 한 오래된 이미지는 거의 찾지 않습니다.

이 사용법을 기반으로 내 솔루션은 이미지를 압축 파일로 점진적으로 압축하는 것이 었습니다. 이미지는 각각 약 20kB이고 압축되지 않은 JPG이므로 ZIP 압축 방식은 없습니다. 이는 드라이브에서 드라이브로 이동하거나 파일 목록을 살펴볼 때 속도 측면에서 NTFS를 크게 도와주는 하나의 파일 시스템 항목으로 연결하기 위해 수행됩니다.

하루보다 오래된 이미지는 "일일"zip으로 결합됩니다. 한 달보다 오래된 지퍼는 각각의 "월간"지퍼로 결합됩니다. 마지막으로 1 년이 넘는 기간은 더 이상 필요하지 않으며 결과적으로 삭제됩니다.

이 시스템은 사용자가 운영 체제 또는 여러 클라이언트 응용 프로그램을 통해 파일을 찾아 볼 수 있고 모든 장치 이름과 타임 스탬프를 기반으로 이름이 지정되므로 제대로 작동합니다. 일반적으로 사용자는이 두 가지 정보를 알고 있으며 수백만 개의 이미지 중 하나를 빠르게 찾을 수 있습니다.

나는 이것이 귀하의 특정 세부 사항과 관련이 없다는 것을 이해하지만 공유 할 것이라고 생각했습니다.


2

파일 이름에 모든 정보를 포함 시키거나 (나중에 찾아보기에 더 나은) 디렉토리에서 분할하는 작성 날짜 기반 이름 지정 체계 일 수 있습니다. 이미지 생성 빈도에 따라 다음을 생각할 수 있습니다.

  • 매일 여러 이미지가 생성됩니다. Year/Month/Day/Hour_Minute_Second.png
  • 한 달에 몇 Year/Month/Day_Hour_Minute_Second.png

등 당신은 내 요점을 얻는다 ... =)


그들은 지속적으로 시간이 지남에 생성되지 않으므로 일부 폴더는 지방이 될 것입니다 및 기타) :) ... 슬림 유지
s.mihai

글쎄, 당신은 분명히이 구성표를 따르기 때문에 폴더 를 만들 필요는 없습니다 . 당신은 할 수 Year/Month/Day/Hour/Minute- 당신은 얼마나 자주 이미지가 생성됩니다에 따라 필요가 얼마나 많은 수준 폴더의 결정 비율이 가장 높은 때 단지 비어 될 폴더를 생성하지 않는 다음 -.
Tomas Aschan

2

날짜 기반 폴더 구조 (예 : \ year \ month \ day)를 만들고 파일 이름에 타임 스탬프를 사용하는 경향이 있습니다. 필요한 경우 이미지가 너무 빨리 생성되어 밀리 초 내에 둘 이상이있을 경우 타임 스탬프에 추가 카운터 구성 요소가있을 수 있습니다. 명명 정렬에 가장 중요하거나 가장 중요하지 않은 순서를 사용하면 찾기 및 유지 관리가 쉬워집니다. 예 : hhmmssmm [seq] .jpg


2

재해 복구를 고려하고 있습니까?

여기에 제안 된 솔루션 중 일부는 파일 이름을 관리하지 못하게합니다 (실제 파일을 이동하면 실제로 어떤 파일인지 추적하지 못하게됩니다). 파일 위치의 마스터 목록이 손상된 경우 작은 셸, er, powershell, 스크립트를 사용하여 파일을 다시 생성 할 수 있도록 고유 한 실제 파일 이름을 유지하는 것이 좋습니다.)

여기서 읽은 내용 에서이 모든 파일이 하나의 파일 시스템에 저장되는 것처럼 들립니다. 여러 시스템의 여러 파일 시스템에이를 저장하십시오. 리소스가있는 경우 전원 공급 장치가 손실되고 교체가 2 일이 지난 경우에 대비하여 각 파일을 두 개의 다른 시스템에 저장하는 시스템을 결정하십시오.

머신 또는 파일 시스템간에 파일을 마이그레이션하기 위해 어떤 종류의 절차를 작성해야하는지 고려하십시오. 시스템에서이 작업을 수행 할 수있는 기능은 온라인 상태이며 온라인 상태에서 상당한 두통을 덜 수 있습니다.

증분 번호 카운터 (데이터베이스 ID 열?)가 엉망이되는 경우 GUID를 증분 번호 대신 실제 파일 이름으로 사용하는 것을 고려할 수 있습니다.

적절한 경우 Amazon S3와 같은 CDN 사용을 고려하십시오.


2

그 규모의 사진을 제공하지는 않았지만 이전에는 400MHz 컴퓨터에서 ~ 25k 사진을 제공하는 작은 갤러리 앱을 작성했습니다. 512MB의 RAM 정도 일부 경험;

  • 모든 비용으로 관계형 데이터베이스를 피하십시오. 데이터베이스는 의심 할 여지없이 데이터를 처리하는 데는 능숙하지만 그러한 용도로 설계되지는 않았습니다 ( 파일 시스템 이라고하는 특수한 계층 키-값 데이터베이스가 있습니다 ). 나는 단순한 직감이 없지만 DB 캐시가 실제로 큰 덩어리를 던지면 DB 캐시가 창 밖으로 나가는 것에 베팅했습니다. 사용 가능한 하드웨어가 작은 반면 이미지 검색에서 DB를 전혀 만지지 않으면 속도가 훨씬 빨라졌습니다.

  • 파일 시스템의 동작을 연구하십시오. ext3에서 (또는 당시 ext2 였는지 기억할 수 없음), 하위 디렉토리와 파일을 효율적으로 검색 할 수있는 한계는 256 마크였습니다. 특정 폴더에 많은 파일과 폴더 만 있습니다. 다시 눈에 띄는 속도 향상. NTFS에 대해서는 알지 못하지만 XFS (B-tree를 사용하는 한)는 매우 빨리 조회 할 수 있기 때문에 매우 빠릅니다.

  • 데이터를 균등하게 분배하십시오. 위의 내용을 실험 할 때 모든 디렉토리에 데이터를 고르게 분배하려고했습니다 (URL의 MD5를 수행하고 디렉토리에 사용했습니다 /1a/2b/1a2b...f.jpg). 이렇게하면 성능 제한에 관계없이 시간이 더 오래 걸립니다 (그리고 파일 시스템 캐시는 어쨌든 그러한 큰 데이터 세트에서는 무효입니다). (반대로, 당신은 한계가 초기에 어디인지 알고 싶을 것입니다. 그러면 사용 가능한 첫 번째 디렉토리에 모든 것을 던지려고합니다.


2

이 게임에 늦을 수도 있습니다. 그러나 하나의 솔루션 (사용 사례에 맞는 경우)은 파일 이름 해싱 일 수 있습니다. 파일 이름을 사용하여 쉽게 재현 가능한 파일 경로를 작성하는 동시에 분산 된 디렉토리 구조를 작성하는 방법입니다. 예를 들어, 파일 이름의 해시 코드 바이트를 경로로 사용할 수 있습니다.

String fileName = "cat.gif";
int hash = fileName.hashCode();
int mask = 255;
int firstDir = hash & mask;
int secondDir = (hash >> 8) & mask;

경로는 다음과 같습니다.

/172/029/cat.gif

그런 다음 cat.gif알고리즘을 재생하여 디렉토리 구조에서 찾을 수 있습니다 .

디렉토리 이름으로 HEX를 사용하면 int값 을 변환하는 것만 큼 쉽습니다 .

String path = new StringBuilder(File.separator)
        .append(String.format("%02x", firstDir))
        .append(File.separator)
        .append(String.format("%02x", secondDir)
        .toString();

를 야기하는:

/AC/1D/cat.gif

나는 몇 년 전에 이것에 관한 기사를 썼고 최근에 보통으로 옮겼습니다. : 그것은 몇 자세한 내용과 몇 가지 예제 코드가 파일 이름 해싱 : 해시 된 디렉토리 구조를 만들기 . 도움이 되었기를 바랍니다!


비슷한 것을 사용하여 18 억 개의 항목을 저장합니다. 잘 작동한다. 빠르고 충돌 율이 낮고 설정되어있는 해시를 사용하십시오.
CVVS


1

모두 필요하지 않고 즉시 생성 할 수 있고 작은 이미지 인 경우 이미지 생성기 위에 LRU 메모리 또는 디스크 캐시를 구현하지 않겠습니까?

저장 공간을 절약하고 핫 이미지를 mem에서 제공 할 수 있습니까?


1

zfs를 좋아하기 때문에 zfs에서 테스트를 실행했으며 압축 된 500gig 파티션이있었습니다. 50-100k 파일을 생성하고 1/2/3/4/5/6/7/8 (5-8 레벨 깊이)의 중첩 된 디렉토리에 배치하고 1 주일 동안 실행되도록하는 스크립트를 작성했습니다. (대단한 스크립트는 아니 었습니다.) 디스크를 채우고 약 2,500 만 개의 파일을 갖게되었습니다. 알려진 경로를 가진 파일 하나에 즉시 액세스 할 수있었습니다. 알려진 경로가있는 디렉토리를 즉시 나열했습니다.

그러나 (파일을 통해) 파일 목록을 계산하는 데 68 시간이 걸렸습니다.

또한 하나의 디렉토리에 많은 파일을 넣는 테스트를 실행했습니다. 중지하기 전에 한 디렉토리에 약 370 만 개의 파일이 있습니다. 카운트를 얻기 위해 디렉토리를 나열하는 데 약 5 분이 걸렸습니다. 해당 디렉토리의 모든 파일을 삭제하는 데 20 시간이 걸렸습니다. 그러나 모든 파일을 조회하고 액세스 할 수있었습니다.


1

다른 데이터베이스에 대해서는 언급했지만 귀하의 게시물에는 언급되지 않았습니다. 어쨌든,이 특정 요점에 대한 나의 의견은 데이터베이스 또는 파일 시스템에 충실한다는 것입니다. 두 가지를 혼합해야하는 경우주의하십시오. 상황이 더 복잡해집니다. 그러나 당신은해야 할 수도 있습니다. 데이터베이스에 백만 장의 사진을 저장하는 것이 가장 좋은 생각은 아닙니다.

다음 사양에 관심이있을 수 있습니다. 대부분의 디지털 카메라는 파일 저장을 관리하기 위해 그것을 따릅니다. https://en.wikipedia.org/wiki/Camera_Image_File_Format

기본적으로 같은 폴더가 만들어 000OLYMPUS지고 사진이 해당 폴더에 추가됩니다 (예 DSC0000.RAW:). 파일 이름 카운터에 도달 DSC9999.RAW하면 새 폴더가 생성되고 ( 001OLYMPUS) 이미지가 다시 추가되어 다른 접두사 (예 :)로 카운터를 재설정합니다 P_0000.RAW.

또는 파일 이름의 일부 (이미 여러 번 언급)를 기반으로 폴더를 만들 수도 있습니다. 예를 들어 사진 이름이 인 IMG_A83743.JPG경우에 저장하십시오 IMG_\A8\3\IMG_A83743.JPG. 구현하기가 더 복잡하지만 파일을 쉽게 찾을 수 있습니다.

파일 시스템에 따라 (연구가 필요합니다) 모든 이미지를 단일 폴더에 덤프 할 수는 있지만 경험상 일반적으로 성능 문제가 발생할 수 있습니다.


0

ZFS (Sun의 파일 시스템, 볼륨 관리자)를보고 싶을 수도 있습니다.


0

많은 수의 경로를 생성하는 깨끗한 방법은 쉽게 16 진수로 변환 한 다음 분할하는 것입니다!

1099496034834> 0xFFFF1212>FF/FF/12/12

public string GeneratePath(long val)
{  
    string hex = val.ToString("X");
    hex=hex.PadLeft(10, '0');
    string path="";
    for(int i=0; i<hex.Length; i+=2 )
    {
        path += hex.Substring(i,2);
        if(i+2<hex.Length)
            path+="/";
    }
    return path;
}

보관 및 적재 :

public long Store(Stream doc)
{
   var newId = getNewId();
   var fullpath = GeneratePath(newId)
   // store into fullpath 
   return newId;
}

public Stream Load(long id)
{
   var fullpath = GeneratePath(newId)
   var stream = ... 
   return stream;
}

전체 소스 코드 : https://github.com/acrobit/AcroFS


-1

불행히도 파일 시스템은 작은 파일을 많이 관리 할 때 (디렉토리 또는 딥 디렉토리 트리 당 많은 파일의 성능, 재시작 시간 확인, 안정성) 매우 나쁘므로 ZIP 파일과 관련된 위의 솔루션은 파일 시스템을 사용하려는 경우 가장 좋습니다.

데이터베이스 관리 프로그램을 사용하는 것이 가장 좋습니다. 예를 들어 BDB 또는 GDBM과 같은 간단한 것; MySQL과 같은 관련 DBMS조차 더 좋습니다. 파일 시스템과 데이터베이스를 이해하지 못하는 게으른 사람들 (예 : 트랜잭션을 해제하는 사람들)만이 파일 시스템을 데이터베이스로 사용하는 경향이 있습니다 (또는 그 반대).


-2

이미지를 저장할 ID와 BLOB가 포함 된 테이블이있는 데이터베이스는 어떻습니까? 그런 다음 더 많은 데이터 요소를 사진과 연관 시키려고 할 때마다 새 테이블을 추가 할 수 있습니다.

확장을 기대한다면 지금 확장하지 않겠습니까? 이제 IMO와 나중에 IMO 시간을 절약 할 수 있습니다. 데이터베이스 계층을 한 번 구현하면 시작하기가 매우 쉽습니다. 또는 폴더와 파일 이름 및 blah blah blah로 무언가를 구현 한 다음 MAX_PATH를 시작하면 나중에 다른 것으로 전환하십시오.


5
거기에 있었으므로 그것을 증명할 흉터가 있습니다. 많은 수의 이미지를 저장하는 데이터베이스는 거의 믿을 수 없을 정도로 까다 롭고 많은 양의 유지 관리가 필요합니다. 데이터베이스에서만 응답 할 수있는 특정 요구 사항이없는 한 파일 시스템에 파일을 저장하는 것이 훨씬 좋습니다 (버전 추적이었습니다)
Satanicpuppy

1
또한 파일 및 파일 시스템을 처리하는 유틸리티는 많지만 데이터베이스 내의 파일을 처리하는 유틸리티는 거의 없습니다.
Mark Ransom

2
오 맙소사. 데이터베이스를 큰 BLOB 스토리지로 사용하지 마십시오.
Neil N

Eek. 데이터베이스 (여전히?)에 BLOB에 많은 문제가 있다는 것을 몰랐습니다.

그렇게 많은 의견을 가진 나쁜 해결책은 어떻게 여전히 +1을 가질 수 있습니까? OP에 대한 공격은 없습니다 (SO에서 온 것으로 보았습니다).하지만 downvote 버튼은 이유가 있습니다!
Mark Henderson
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.