2017-11-23 3 views
0

나는 수백만 개의 레코드를 포함 할 수있는 파일 (편의를 위해 csv 파일을 말합니다)이 있습니다. 파일에 여러 개의 중복이있을 수 있습니다. 고유 한 레코드를 찾고 싶지만 특정 열만 기반으로한다고 가정 해 보겠습니다 (기본 열이라고합니다). 파일을 다음과 같이 말합니다 :확장 가능한 솔루션을 사용하여 Java의 매우 큰 파일에서 고유 한 레코드를 찾는 방법은 무엇입니까?

File ScreenShot 이 파일에서 처음 두 레코드는 완전히 동일하지 않습니다. 하지만 column1을 기본 레코드로 간주하면 첫 번째 2 레코드는 나와 중복됩니다 (column1에서 동일한 값을 갖기 때문에). 그리고 최종 결과에서 단 하나만 원합니다.

내 현재 접근 방식에서 키 값이 내 기본 열 데이터이고 해당 매핑 된 값이 전체 레코드 인 Map을 사용하고 있습니다. 이 방법을 통해 모든 레코드를 반복하고 각 레코드에 대해 기본 열 데이터를 키 값으로, 전체 레코드를 각각 매핑 된 값으로 푸시합니다. 이 방법은 중복되는 기본 열이 반복되는 동안 발생할 때마다 동일한 기본 키 데이터가있는 레코드를 바꿉니다 (맵에서 중복을 허용하지 않음).

이 방법은 정상적으로 작동하지만 힙 공간이 부족할 수있는 더 큰 파일로 확장 할 수는 없습니다. 또한 시간 복잡성도 좋지 않습니다. 누구든지 더 나은 방법을 제안 할 수 있습니까?

+1

작업에 적합한 도구 (SQL, Hadoop 등)를 사용하십시오. – ronhash

+0

이러한 데이터는 모든 DB에 저장되지 않으며 원시 파일로만 사용할 수 있으므로 SQL은 옵션이 아닙니다. – DockYard

+0

그래도 SQLite는 파일이지만 쿼리를 실행할 수 있으며 nit는 * any * 설치가 필요합니다 – ronhash

답변

1

필요한 것은 오프 힙 (off-heap) 데이터 구조입니다. Hazelcast 나 Redis를 사용해보십시오. 그렇지 않으면 다른 것을 사용할 수 없으면 고유 한 레코드에 대한 회선 번호 만 저장하고 두 번째로 출력을 작성하면 메모리 요구량을 크게 줄일 수 있습니다. 실제 메모리보다 힙 크기를 늘릴 수도 있지만 스와핑으로 인해 성능이 저하 될 수 있습니다. 그래도 충분하지 않으면 자체 힙 코드를 작성해야합니다. ByteBuffer.allocateDirect()로 메모리를 할당하고 그곳에 데이터를 쓸 수 있으며지도를 사용하여 데이터에 오프셋을 저장할 수 있습니다.

관련 문제