2011-09-27 45 views
5

Sử dụng Java Tôi muốn tạo Bản đồ có thể phát triển và phát triển và có khả năng lớn hơn kích thước bộ nhớ có sẵn. Bây giờ rõ ràng bằng cách sử dụng một tiêu chuẩn POJO HashMap chúng tôi sẽ hết bộ nhớ và JVM sẽ sụp đổ. Vì vậy, tôi đã suy nghĩ dọc theo các dòng của một bản đồ rằng nếu nó trở nên nhận thức của bộ nhớ chạy thấp, nó có thể ghi các nội dung hiện tại vào đĩa.Tạo một Bản đồ rất, rất lớn trong Java

Có ai đã triển khai bất kỳ điều gì như thế này hoặc biết về bất kỳ giải pháp hiện có nào không?

Những gì tôi đang cố gắng làm là đọc một tệp ASCII rất lớn (nói 50Gb) một dòng tại một thời điểm. Mỗi dòng chứa một khóa và một giá trị. Các khóa có thể được sao chép trong tệp. Sau đó, tôi sẽ lưu trữ mỗi dòng trong một Bản đồ, đó là Khóa đến một Danh sách các giá trị. Bản đồ này là đối tượng sẽ phát triển và phát triển.

Bất kỳ lời khuyên nào được đánh giá cao.

Phil

Cập nhật:

Cảm ơn tất cả các ý kiến ​​và lời khuyên tất cả mọi người. Với vấn đề mà tôi mô tả, Cơ sở dữ liệu là giải pháp đúng, có thể mở rộng. Tôi nên nói rằng đây là một Bản đồ tạm thời cần được tạo và sử dụng trong một khoảng thời gian ngắn để hỗ trợ việc phân tích cú pháp một tệp. Trong trường hợp này, đề xuất của Michael là "chỉ lưu trữ số dòng thay vì giá trị thực tế" là thích hợp nhất. Đánh dấu (các) câu trả lời của Michael là giải pháp được đề xuất.

+3

sẽ không đơn giản hơn để sử dụng cơ sở dữ liệu trong bộ nhớ như HSQL? – mcfinnigan

+0

Bạn đang ánh xạ loại khóa/giá trị nào? –

+0

Tôi không quan tâm đến phương pháp tiếp cận cơ sở dữ liệu. Nó quá nặng. – Phil

Trả lời

12

Tôi nghĩ bạn đang tìm kiếm cơ sở dữ liệu.

+0

:) Vâng tôi đã xem xét một cơ sở dữ liệu nhưng tôi chỉ muốn một điều rất đơn giản (như một bản đồ) có thể tràn đến đĩa khi cần thiết. Vấn đề là làm thế nào chúng ta có thể biết liệu khóa có tồn tại hay không, vì vậy có thể nó sẽ chỉ tràn phần "giá trị" của Bản đồ – Phil

+0

Giải pháp có thể có: Sử dụng bản đồ, nhưng chỉ lưu trữ số dòng thay vì giá trị thực tế làm giá trị. Bạn có thể sử dụng số dòng để lấy giá trị thực tế từ tệp của bạn. – michael667

+0

Michael - Tôi đã nghĩ về điều này và sử dụng trình đọc RandomAccessFile để đọc. Nỗi đau là BufferedReader không thể cung cấp vị trí đọc hiện tại từ tệp. Mất BufferedReader có nghĩa là mất khả năng readLine và nó cũng sai với phân tích cú pháp CSV của tôi (tôi đã bỏ lỡ câu hỏi này vì nó không thực sự phù hợp). – Phil

2

Âm thanh như bán tệp lớn của bạn vào DB.

Vâng, tôi đã có một tình huống tương tự như thế này. Nhưng, Trong trường hợp của tôi, mọi thứ ở định dạng tệp TXT và toàn bộ tệp có cùng các dòng được định dạng. Vì vậy, những gì tôi đã làm là tôi chỉ tách các tập tin thành nhiều phần (có thể, mà JVM của tôi có thể xử lý kích thước tối đa). Sau đó, tôi gọi từng tệp một, để được xử lý.

Một cách khác, bạn có thể trực tiếp tải dữ liệu của mình vào cơ sở dữ liệu trực tiếp.

0

Nếu bạn chỉ muốn xây dựng bản đồ để xử lý dữ liệu (thay vì truy cập ngẫu nhiên theo yêu cầu), thì MapReduce có thể là thứ bạn muốn, không cần phải làm việc với cơ sở dữ liệu.

Chỉnh sửa: Lưu ý rằng mặc dù nhiều giới thiệu MapReduce tập trung vào khả năng chạy nhiều nút, bạn vẫn sẽ nhận được lợi ích từ việc tiếp cận yêu cầu giữ tất cả dữ liệu trong bộ nhớ trên một máy.

0

Bạn có bao nhiêu bộ nhớ? Trừ khi bạn có đủ bộ nhớ để giữ cho hầu hết các dữ liệu trong bộ nhớ của nó sẽ rất chậm, nó có thể cũng đã thất bại. Một chương trình phân trang nặng có thể chậm hơn hoặc bằng 1000 lần. Một số máy tính có 16-24 GB và bạn có thể xem xét nhận được nhiều bộ nhớ hơn.

Giả sử có đủ bản sao, bạn có thể giữ hầu hết dữ liệu trong bộ nhớ. Tôi đề nghị bạn sử dụng một lớp String dựa trên việc tạo của riêng bạn, vì bạn có dữ liệu ASCII và lưu trữ các giá trị của bạn như một kiểu khác trong chuỗi "String" (với dấu tách) Bạn có thể thấy rằng bạn có thể giữ bộ dữ liệu làm việc trong bộ nhớ.

+0

Nếu bạn định đi đến tuyến đường 'String' nhẹ hơn, tôi khuyên bạn nên sử dụng [' MutableString'] (http://dsiutils.dsi.unimi.it/docs/it/unimi/dsi/lang/MutableString .html) - một phần được thiết kế cho mục đích này. –

+0

MutableString sử dụng một char [], Even String có thể chuyển đổi chuỗi ascii thành sử dụng một byte [] '-XX: + UseCompressedStrings' là mặc định trên các JVM mới hơn. Tuy nhiên nó không khá hiệu quả như bạn có thể làm cho mình. –

2

Nghiêm túc, hãy chọn một cơ sở dữ liệu đơn giản như được khuyên. Nó không phải là trên không — bạn không cần phải sử dụng JPA hoặc whatnot, chỉ cần đồng bằng JDBC với SQL bản địa.Ví dụ: Derby hoặc HSQL có thể chạy ở chế độ được nhúng, không cần xác định người dùng, quyền truy cập, khởi động máy chủ riêng.

"Chi phí" sẽ đâm bạn ở phía sau khi bạn đã chuyển sang giải pháp bản đồ băm và hóa ra bạn cần tối ưu hóa khác để tránh OutOfMemoryException hoặc tệp không phải là 50 GB, nhưng 75 ... Thực sự, đừng đi đến đó.

3

Cơ sở dữ liệu NoSQL có thể dễ cài đặt và nó giống như một bản đồ. Kiểm tra phiên bản Java BerkeleyDB, hiện tại từ Oracle. Nó có bản đồ giống như giao diện, có thể nhúng được nên không cần thiết lập phức tạp

+0

+1 cho tùy chọn cơ sở dữ liệu bộ nhớ. – FloppyDisk

0

Tôi sử dụng BerkleyDB cho điều này, mặc dù nó phức tạp hơn Bản đồ (mặc dù chúng có bất cứ điều gì nhưng các ứng dụng đơn giản)

http://www.oracle.com/technetwork/database/berkeleydb/overview/index.html

Nó cũng có sẵn trong Maven http://www.oracle.com/technetwork/database/berkeleydb/downloads/maven-087630.html

<dependencies> 
    <dependency> 
     <groupId>com.sleepycat</groupId> 
     <artifactId>je</artifactId> 
     <version>3.3.75</version> 
    </dependency> 
    </dependencies> 

    <repositories> 
    <repository> 
     <id>oracleReleases</id> 
     <name>Oracle Released Java Packages</name> 
     <url>http://download.oracle.com/maven</url> 
     <layout>default</layout> 
    </repository> 
    </repositories> 

Nó cũng có một nhược điểm khác của nhà cung cấp lock-in (tức là bạn đang cho ced để sử dụng công cụ này. mặc dù có thể có các trình bao bọc Bản đồ khác cho một số cơ sở dữ liệu khác)

Vì vậy, chỉ cần chọn theo nhu cầu của bạn.

0

Hầu hết các API bộ nhớ cache hoạt động giống như bản đồ và hỗ trợ tràn vào đĩa. Ví dụ: Ehcache hỗ trợ điều đó. Hoặc theo dõi this tutorial for guave.

Các vấn đề liên quan