2014-10-09 4 views
0

Google은 수천 개의 매우 작은 CSV 파일을 저장해야하는 애플리케이션을 보유하고 있습니다. 100,000 이상이며 매년 같은 금액으로 증가합니다. 각 파일에는 약 20-80KB의 차량 추적 데이터가 들어 있습니다. 각 데이터 세트 (또는 파일)는 단일 차량 여행을 나타냅니다.서버에 100,000 개 이상의 CSV 텍스트 파일을 저장하는 가장 좋은 방법은 무엇입니까?

현재이 정보는 SQL Server에 저장되어 있지만 데이터베이스의 크기가 약간 커지고 시간이 지나면 한 파일 만 액세스 할 필요가 있습니다 (대량 쿼리 또는 다른 방식으로 쿼리해야 함). 관계형 데이터베이스에 저장하는 것은 필요하지 않습니다.) 데이터를 삽입하거나 삭제할 때 인덱스를 다시 작성하거나 업데이트하는 데 소요되는 시간 때문에 더 많은 트랙을 추가 할 때 데이터베이스 성능이 저하됩니다.

우리가 고려하고있는 3 개 가지 옵션이 있습니다 :

  1. 우리는 파일에 데이터를 외부화하는 SQL의 FILESTREAM 기능을 사용할 수 있지만 내가 전에이 기능을 사용하지했습니다. Filestream은 여전히 ​​데이터베이스 객체 (BLOB) 당 하나의 실제 파일을 생성합니까?

  2. 또는 파일을 개별적으로 디스크에 저장할 수 있습니다. 거기에서 는 3 년 이상 지나면 50 만명을 끝낼 수 있습니다. NTFS 파일 시스템이이 양을 정상적으로 처리합니까?

  3. 많은 파일이 문제가되는 경우 데이터 세트/파일을 작은 데이터베이스 (한 명의 사용자)로 그룹화하여 각 사용자를 고려해야합니까? 파일을 저장할 수있는 SQLite와 같은 매우 가벼운 데이터베이스가 있습니까?

또 하나 요점 : 데이터는 고도로 압축 가능합니다. 파일을 압축하면 원본 크기의 10 %로 줄어 듭니다. 가능한 경우 압축을 사용하여 사용 된 디스크 공간과 백업 크기를 최소화하고 싶습니다.

+0

'더 많은 트랙을 추가 할 때 데이터베이스의 성능이 저하됩니다 .' csv 파일로 전환하는 대신 데이터베이스에 적절한 색인을 추가하는 것을 고려 했습니까? 주된 관심사가 디스크 공간 (희귀 한 imho) 인 경우 속도가 주요 문제 인 경우 db에서 전환하면 도움이 될 수 있습니다 (영향은 미미할 것입니다) – DrCopyPaste

+0

저는 SQL 전문가는 아니지만 수백만 행 (각각 10,000 행 CSV 파일의 한 행을 나타냄)이있는 테이블에서 적절한 삽입 성능을 얻는 것이 어렵다고 생각하십시오. 우리는 그것을 considereed했지만, 우리는 왜 이러한 특정 데이터 항목이 데이터베이스에 있어야하는지에 대해 정말로 확신하지 못합니다. – NickG

+0

또한 데이터 양이 불필요하게 백업 크기를 부풀게하고 결코 바뀌지 않는 데이터 톤과 같은 다른 문제가 있습니다. – NickG

답변

2

나는 약간의 생각이 있습니다. 이것은 매우 주관적이기 때문에, 다른 독자의 마일리지는 다를 수 있지만, 다른 사람들이 다른 견해를 나타 내기를 원한다고해도, 여전히 공을 굴릴 것입니다. ..

첫째, 너무 많은 파일이 포함 된 폴더에서 성능 문제가 발생했습니다. 하나의 프로젝트는 00, 01, 02 ... fd, fe, ff라고 불리는 256 개의 디렉토리를 생성하고 동일한 이름 지정 규칙을 사용하여 256 개의 디렉토리를 추가함으로써이 문제를 해결했습니다. 500,000 개의 파일을 65,536 개의 디렉토리로 나눌 수 있습니다. 좋은 해쉬/랜덤 생성기를 사용하면 각 디렉토리에 몇 개만 있습니다. 또한 파일 이름은 데이터베이스에 저장하기에 꽤 짧습니다 (예 : 32/af/file-xyz.csv. 의심 할 여지없이 누군가가 내 머리를 물어 뜯지 만 한 디렉토리에 10,000 개의 파일이 많다고 느낍니다.

두 번째로 80kB의 10 만 개의 파일은 요즘 실제로별로 크지 않은 8GB의 데이터입니다. 사실 작은 USB 플래시 드라이브입니다. 압축에 대한 모든 논쟁은 유효하지 않습니다. 스토리지는 저렴합니다. 그래도 중요한 것은 백업입니다. 50 만 개의 파일을 가지고 있으면 많은 inodes가 트래버스 될 것이고 많은 백업 제품이 초당 50-100 개의 inode만을 트래버스 할 수 있다고 생각합니다. 따라서 매우 오랜 시간 기다리게 될 것입니다. 허용 할 수있는 중단 시간에 따라 시스템을 오프라인으로 설정하고 원시 장치 인 블록 장치에서 백업하는 것이 좋습니다. 예를 들어 100MB/s에서 80 초 동안 8GB를 백업 할 수 있으며 기존 파일을 상상할 수 없습니다 기반 백업은 그와 가깝게 될 수 있습니다. 대안은 스냅 샷을 허용하는 파일 관리자 일 수 있으며 스냅 샷에서 백업 할 수 있습니다. 또는 미러를 분할하고 한 복사본에서 백업 한 다음 미러에 다시 결합 할 수있게 해주는 미러 된 파일 시스템입니다.

내가 말했듯이, 꽤 주관적이고 나는 다른 사람들이 다른 아이디어를 가질 것이라고 확신한다.

+0

감사합니다. 문제를 피하기 위해 회사 ID와 사용자 ID를 기반으로 폴더를 만들 수 있습니다 (단 한 명의 사용자도 많은 파일을 보유 할 수 없음). 따라서 우리는 co9665 \ user21043 \ track1.zip으로 끝날 것입니다. 이는 사용자 또는 회사의 모든 데이터를 신속하게 삭제할 수 있음을 의미합니다. – NickG

+0

나는 백업에 대해서 생각조차하지 않았기 때문에 좋은 지적이다. 이상적으로는 너무 많은 작업이나 오버 헤드를 만들지 않고 파일을 더 큰 파일로 쉽게 결합 할 수있는 방법이 있는지 알고 싶습니다. 예를 들어 한 달에 하나의 파일이나 다른 파일이있을 수 있습니다. – NickG

1

저는 하이브리드 접근 방식을 사용하는 응용 프로그램에서 작업합니다. 주로 응용 프로그램을 작은 설치 환경에서 SQL Server의 공짜로 제공되는 버전에서 작동시킬 수 있기를 원했기 때문에 ... 파일로드로 인해 최고 빨리. 대규모 설치시 수천만 개의 파일이 있습니다.

우리는 열거 한 것과 같은 시나리오를 고려했습니다. 그러나 우리가 결국하기로 결정한 것은 예정 파일을 불투명 한 모양으로 포함하는 일련의 중간 크기 (2GB) 메모리 매핑 파일을 만드는 것입니다. 그런 다음 blob은 blob-id (압축되지 않은 blob의 sha1 해시)에 의해 키가 지정되고 container-file-id, offset, length 및 uncompressed-length에 대한 필드가 있습니다. BLOB 참조 테이블에는 "published"플래그가 있습니다. 해시는 내용을 충실하게 표현하기 때문에 얼룩은 한 번만 기록됩니다. 수정 된 파일은 새로운 해시를 생성하며 블롭 저장소의 새 위치에 기록됩니다.

이 경우 BLOB는 일관되게 텍스트 파일이 아니 었습니다. 실제로 모든 유형의 파일입니다. 대용량 파일은 롤링 해시 함수로 약 64k 청크로 분할됩니다. 우리는 lz4 압축을 사용하여 각 블롭을 압축하려고 시도합니다 (이는 빠른 압축이며 효율적으로 압축 할 수없는 데이터를 빠르게 중단합니다).

이 접근법은 실제로 잘 작동하지만 가볍게 권장하지는 않습니다. 그것은 복잡해질 수 있습니다. 예를 들어 삭제 된 콘텐츠가있는 컨테이너 파일 정리 이를 위해 스파 스 파일을 사용하고 삭제 된 BLOB의 범위를 NTFS에 알려줍니다. 거래 요구는 더욱 복잡합니다.

db-to-blob-store에 대한 모든 goop은 메모리 매핑 파일에 대해 약간의 interop를 사용하는 C#입니다. 시나리오는 비슷하지만 다소 까다 롭습니다. 메모리 맵핑 된 I/O 문제가 없으면 빠져 나올 수 있다고 생각합니다.