4

大丈夫。そのため、さまざまな長さの一連のファイル (たとえば 5000) に分散された非常に大量のバイナリ データ (たとえば 10GB) があります。

このデータを処理する Java アプリケーションを作成しており、データ アクセスの優れた設計を導入したいと考えています。通常、次のようなことが起こります。

  • いずれにせよ、処理中にすべてのデータが読み取られます。
  • 各ファイルは (通常) 順次読み取られ、一度に数キロバイトしか必要としません。ただし、たとえば、各ファイルの最初の数キロバイトを同時に、または各ファイルの中間の数キロバイトを同時に持つ必要があることがよくあります。
  • アプリケーションがあちこちで 1 ~ 2 バイトへのランダム アクセスを必要とする場合があります。

現在、RandomAccessFile クラスを使用して、バイト バッファー (および ByteBuffers) に読み込みます。私の最終的な目標は、データ アクセスを何らかのクラスにカプセル化して高速化し、二度と心配する必要がないようにすることです。基本的な機能は、指定されたファイルからデータのフレームを読み取るように要求することです。上記の考慮事項を考慮して、I/O 操作を最小限に抑えたいと考えています。

一般的なアクセスの例:

  • すべてのファイルの最初の 10 キロバイトをください!
  • ファイル F のバイト 0 から 999 まで、次にバイト 1 から 1000 まで、次に 2 から 1001 まで、などなど...
  • ファイル F の何メガバイトから何メガバイトのデータをください!

良いデザインの提案はありますか?

4

9 に答える 9

9

Java NIO と MappedByteBuffers を使用し、ファイルをバイト配列のリストとして扱います。次に、キャッシュ、読み取り、フラッシュなどの詳細を OS に任せます。

于 2008-09-26T15:10:43.113 に答える
2

@意思

かなり良い結果。大きなバイナリ ファイルの読み取りのクイック比較:

  • テスト 1 - RandomAccessFile を使用した基本的な順次読み取り。 2656ミリ秒

  • テスト 2 - バッファリングを使用した基本的な順次読み取り。 47ミリ秒

  • テスト 3 - MappedByteBuffers を使用した基本的なシーケンシャル読み取りと、フレーム バッファリングの最適化。 16ミリ秒

于 2008-09-26T18:39:17.857 に答える
1

Eric のデータベースのアイデアをフォローアップして、データベースがバッファーを管理する方法、つまり独自の仮想メモリ管理を効果的に実装する方法を学ぶことをお勧めします。

しかし、よく考えてみると、ほとんどのオペレーティング システムは、Java で低レベルのアクセスなしで実行できるよりも、ファイル システム キャッシュを実装する方が優れているという結論に達しました。

ただし、データベース バッファー管理から、考慮すべき教訓が 1 つあります。データベースは、クエリ プランの理解を使用して、管理戦略を最適化します。

リレーショナル データベースでは、最近使用されたブロックをキャッシュから削除することが最善の方法であることがよくあります。たとえば、結合で子レコードを保持する「若い」ブロックは再び参照されませんが、その親レコードを含むブロックは「古い」にもかかわらずまだ使用されています。

一方、オペレーティング システムのファイル キャッシュは、最近使用したデータを再利用するように最適化されています (そして、最近使用したデータよりも先に読み取ります)。アプリケーションがそのパターンに適合しない場合は、自分でキャッシュを管理する価値があるかもしれません。

于 2008-09-26T18:23:21.047 に答える
1

jdbmと呼ばれるオープン ソースの単純なオブジェクト データベースを調べてみるとよいでしょう。このデータベースには、ACID 機能を含め、この種のものが多数開発されています。

私はこのプロジェクトに多くの貢献をしてきました。あなたが取り組んでいる問題の多くをどのように解決したかを確認するために、ソース コードを確認する価値はあります。

ここで、データ ファイルが自分の管理下にない場合 (つまり、他の誰かが生成したテキスト ファイルを解析している場合など)、jdbm が使用するページ構造のストレージ タイプは適切ではない可能性があります。これらのファイルは、あなたが作成して作業しているファイルです。一見の価値があるかもしれません。

于 2008-09-27T03:43:17.237 に答える
1

わお。基本的に、データベースをゼロから実装しています。データを実際の RDBMS にインポートし、SQL だけを使用する可能性はありますか?

自分で行う場合は、最終的に何らかのキャッシュメカニズムを実装する必要があるため、必要なデータが RAM にある場合はそこから取得し、下位レイヤーでファイルを読み書きします。

もちろん、これには、データの一貫性を保つために、多くの複雑なトランザクション ロジックも必要です。

于 2008-09-26T15:08:04.773 に答える
0

一歩下がって、なぜファイルを記録システムとして使用しているのか、データベースを使用することでどのようなメリットがあるのか​​を自問してみてください。データベースは確かにデータを構造化する機能を提供します。SQL 標準を考えると、長期的にはより保守しやすいかもしれません。

一方、ファイル データは、データベースの制約内ではそれほど簡単に構造化されない場合があります。世界最大の検索会社 :) ビジネス処理にデータベースを使用していません。ここここを参照してください。

于 2008-09-28T03:06:04.633 に答える
0

@エリック

しかし、私のクエリは、SQL で実行できるものよりもはるかに単純になります。また、データベースへのアクセスは、バイナリ データの読み取りよりもはるかにコストがかかるのではないでしょうか?

于 2008-09-26T15:11:12.847 に答える
0

これは、I/O トラフィックの最小化に関する部分に答えるものです。Java 側で実際にできることは、リーダーを BufferedReaders でラップすることだけです。それとは別に、オペレーティング システムは、最近読み取ったデータをページ キャッシュに保持したり、ファイルを先読みして順次読み取りを高速化するなど、他の最適化を処理します。Java で追加のバッファリングを行っても意味がありません (ただし、データをクライアントに返すにはバイト バッファが必要です)。

于 2008-09-26T15:11:46.637 に答える
0

先日、誰かに Hadoop ( http://hadoop.apache.org ) を勧めてもらいました。それはかなりいいように見え、市場での牽引力があるかもしれません.

于 2008-09-27T03:51:12.677 に答える