2011-09-27 12 views
5

Javaを使用して、私は成長し、成長し、潜在的に利用可能なメモリのサイズよりも大きいマップを作成したいと思います。今では明らかに標準のPOJO HashMapを使用してメモリが使い果たされ、JVMがクラッシュします。だから私はマップのラインに沿って、メモリが不足していることを認識すると、現在の内容をディスクに書き込むことができると考えていました。Javaで非常に大規模なマップを作成する

誰もこのようなことを実装していますか、そこにある既存のソリューションを知っていますか?

私がしようとしているのは、一度に1行に非常に大きなASCIIファイル(たとえば50Gb)を読み込むことです。各行にはキーと値が含まれています。キーはファイルに複製できます。次に、各行を値のリストのキーであるマップに保存します。このマップは、成長し成長するオブジェクトです。

アドバイスをいただければ幸いです。

フィル

アップデート:すべてのコメントやアドバイス、みんなのために

感謝。私が記述した問題では、データベースは正しい、スケーラブルなソリューションです。私はこれが一時的なマップであり、ファイルの解析を助けるために短期間に作成して使用する必要があると述べたはずです。この場合、「実際の値の代わりに行番号のみを格納する」というマイケルの提案が最も適切です。マイケルの答えを推奨する解決策としてマークしてください。

+3

そのようなHSQLとして、インメモリデータベースを使用する方が簡単ではないでしょうか? – mcfinnigan

+0

マッピングするキー/値の種類は何ですか? –

+0

私はデータベースアプローチに熱心ではありません。それはあまりにも重すぎます。 – Phil

答えて

12

私はあなたがデータベースを探していると思います。

+0

:)まあ、私は、データベースを検討しなかったのコレクションをサポートしていますが、私はちょうどにオーバーフローする可能性(地図など)は非常に単純なことを望んでいました必要に応じてディスクを挿入します。キーが存在するかどうかを知るにはどうすればいいのでしょうか?マップの "値"部分をオーバーフローさせるだけでよいでしょう。 – Phil

+0

可能な解決策:マップを使用しますが、実際の値の代わりに行番号のみを値として格納します。行番号を使用して、ファイルから実際の値を取得することができます。 – michael667

+0

マイケル - 私はこれを考えて、RandomAccessFileリーダーを使って読みました。 BufferedReaderはファイルから現在の読み取り位置を供給できませんでした。 BufferedReaderを失うことは、readLineの能力を失うことを意味し、私のCSV解析も乱してしまっていました(私はこれが本当の意味合いではなかったので、元の質問からこれを逃しました)。 – Phil

2

巨大なファイルをDBにダンプするのが好きです。

まあ、私はこのような状況がありました。しかし、私の場合はすべてがTXTファイル形式であり、ファイル全体に同じ形式の行があります。だから、私がやったことは、ファイルをいくつかの部分に分割しただけです(おそらく、私のJVMが最大サイズを処理できる可能性があります)。その後、ファイルを1つずつ呼び出して処理されました。

別の方法として、直接データをデータベースに直接ロードすることができます。

0

(リクエストに応じてランダムにアクセスするのではなく)データ処理用のマップを構築したい場合は、MapReduceがデータベースで作業する必要はなく、必要なものになる可能性があります。

編集:多くのMapReduceの導入は多くのノードを実行する能力に重点を置いていますが、メモリ内のすべてのデータを1台のマシンに保持するという必要性を避けることができます。

0

どのくらいのメモリがありますか?メモリ内のデータの大半を非常に遅くするために十分なメモリがない限り、それは失敗する可能性があります。頻繁にページングするプログラムは、1000倍以上遅くなる可能性があります。一部のPCには16〜24 GBがあり、メモリを増やすことを検討するかもしれません。

十分な重複があると仮定すると、ほとんどのデータをメモリに保存できます。 ASCIIデータがあり、これらの "String"型の別のもの(セパレータ付き)として値を格納するため、バイトベースのStringクラスを使用することをお勧めします。メモリ内に作業データセットを保持することができます。

+0

軽量の 'String'ルートに行く場合は、[' MutableString'](http://dsiutils.dsi.unimi.it/docs/it/unimi/dsi/lang/MutableString .html)クラス - これは部分的にこの目的のために設計されています。 –

+0

MutableStringはchar []を使用します。偶数文字列は、新しいJVMのデフォルトであるバイト[] '-XX:+ UseCompressedStrings'を使用して、ASCII文字列を変換することができます。しかし、あなたは自分でできるほど効率的ではありません。 –

2

真剣に言えば、簡単なデータベースを選択してください。オーバーヘッドではありません— JPAなどのネイティブSQLを使用する必要はありません。DerbyやHSQLは、例えば、組み込みモードで実行することができ、ユーザー、アクセス権を定義する必要はなく、サーバーを別々に起動する必要があります。

「オーバーヘッド」は、ハッシュマップソリューションに近づいたときにあなたを刺してしまい、OutOfMemoryExceptionを回避するためのさらに別の最適化が必要であるか、ファイルが50 GBではなく75 ...本当に、そこに行かないでください。

3

AのNoSQLデータベースは、セットアップにおそらく簡単になり、それがマップより似ています。 OracleからBerkeleyDB Java Editionをチェックしてください。 マップのようなインターフェイスがあり、埋め込み可能なので複雑な設定は必要ありません。

+0

メモリデータベースオプションの+1。 – FloppyDisk

0

私はBerkleyDBを使っていますが、これはマップよりも複雑です(マップラッパーはありますが単純なアプリケーション以外のもの)

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

、それはまた、(つまり、あなたがベンダーロックインの一つの他の欠点をされた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> 

可能ですこのツールを使用してください。いくつかの他のデータベースに他のマップラッパー)があるかもしれませんが

だから、あなたのニーズに応じて選択します。

0

ほとんどのキャッシュAPIは、ディスクへのマップとサポートのオーバーフローのように働きます。例えば、Ehcacheはこれをサポートしています。または、this tutorial for guaveに従ってください。

関連する問題