データをディスクに永続化し、ランダムに更新し、効率的に RAM にストリーミングするにはどうすればよいですか?
-
16-09-2019 - |
質問
最大で数千万、場合によっては数億のデータをディスク上に保存する必要があります。各データには次のような情報が含まれています。
id=23425
browser=firefox
ip-address=10.1.1.1
outcome=1.0
新しいデータは、1 ミリ秒あたり最大 1 個の割合で追加される可能性があります。
したがって、これは比較的単純なキーと値のペアのセットであり、値は文字列、整数、または浮動小数点のいずれかになります。場合によっては、フラグ フィールドを 0 から 1 に変更して、特定の ID でデータを更新する必要がある場合があります。言い換えれば、ID によるランダムなキー検索を実行し、データを変更できる必要があります (実際には浮動小数点の「結果」フィールドのみ - したがって、値のサイズを変更する必要はありません)。
もう 1 つの要件は、このデータをディスクから効率的にストリーミングできる必要があることです (順序は特に重要ではありません)。これは、ハードディスク ヘッドがデータを読み取るためにディスク上を飛び回る必要はなく、連続したディスク ブロックで読み取る必要があることを意味します。
これをJavaで書いています。
組み込みデータベースの使用を考えましたが、DB4O は GPL であり、コードの残りの部分は GPL ではないため、選択肢にはなりません。また、SQL クエリとの間の変換のオーバーヘッドを考慮すると、組み込み SQL データベースの使用効率も心配です。
何かアイデアがある人はいますか?これに対するカスタム ソリューションを構築する必要があるでしょうか (ByteBuffers を直接処理し、ID ルックアップを処理しています)。
解決 7
最後に、私は、それが入ってくると、ディスクにデータを記録し、また、私はそれを更新することができ、メモリにそれを維持することを決めました。一定期間の後、私は、ディスクへのデータの書き込みやログを削除します。
他のヒント
どうでしょうか H2?の ライセンス あなたのために働くはずです。
- H2は無料でご利用いただけます。(商用アプリケーションを含む)アプリケーションに統合でき、配布できます。
- コードのみを含むファイルは、このライセンスでカバーされていません(「商業的に優しい」です)。
- H2ソースコードの変更を公開する必要があります。
- 何も変更しなかった場合、H2のソースコードを提供する必要はありません。
分かりました
22492 ミリ秒で 1000000 件の挿入 (44460.252534234394 行/秒)
9565 ミリ秒で 100000 件の更新 (10454.783063251438 行/秒)
から
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Random;
/**
* @author clint
*
*/
public class H2Test {
static int testrounds = 1000000;
public static void main(String[] args) {
try {
Class.forName("org.h2.Driver");
Connection conn = DriverManager.
getConnection("jdbc:h2:/tmp/test.h2", "sa", "");
// add application code here
conn.createStatement().execute("DROP TABLE IF EXISTS TEST");
conn.createStatement().execute("CREATE TABLE IF NOT EXISTS TEST(id INT PRIMARY KEY, browser VARCHAR(64),ip varchar(16), outcome real)");
//conn.createStatement().execute("CREATE INDEX IDXall ON TEST(id,browser,ip,outcome");
PreparedStatement ps = conn.prepareStatement("insert into TEST (id, browser, ip, outcome) values (?,?,?,?)");
long time = System.currentTimeMillis();
for ( int i = 0; i < testrounds; i++ ) {
ps.setInt(1,i);
ps.setString(2,"firefox");
ps.setString(3,"000.000.000.000");
ps.setFloat(4,0);
ps.execute();
}
long last = System.currentTimeMillis() ;
System.out.println( testrounds + " insert in " + (last - time) + "ms (" + ((testrounds)/((last - time)/1000d)) + " row/sec)" );
ps.close();
ps = conn.prepareStatement("update TEST set outcome = 1 where id=?");
Random random = new Random();
time = System.currentTimeMillis();
/// randomly updadte 10% of the entries
for ( int i = 0; i < testrounds/10; i++ ) {
ps.setInt(1,random.nextInt(testrounds));
ps.execute();
}
last = System.currentTimeMillis();
System.out.println( (testrounds/10) + " updates in " + (last - time) + "ms (" + ((testrounds/10)/((last - time)/1000d)) + " row/sec)" );
conn.close();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
JDBM のJava用の大きな埋め込みデータベースである(とのJavaバージョンとしてライセンスと邪魔しないようにバークレー)。それは試みる価値があるだろう。あなたは(すなわち、あなたがクラッシュ時に壊れるデータベースとOKです)ACID保証を必要としない場合は、(大幅に速度を上げる)トランザクションマネージャをオフにします。
私はあなたがメモリ内で最もアクティブなレコードをキャッシュし、DBに挿入する低優先度などのデータ変更をキューに何かを書いて、より多くの成功を持っていると思う。
私は、このメソッドを使用してIOのわずかな増加があります理解していますが、レコードの数百万人の話をしている場合、私はあなたが作成した検索アルゴリズムを大幅にAA本格的なデータベースエンジンで上回っしようとしているので、それはまだ速くなると思います。
これで、オラクルが所有しているバークレーDB を試みることができます。彼らは、オープンソースと商用ライセンスを持っています。これは、(クエリの他の形態が必要な場合は、インデックスを作成するためのオプション付き)キー/バリューモデルを使用しています。純粋なJavaバージョンとJavaバインディングを持つネイティブバージョンがあります。
http://www.zentus.com/sqlitejdbc/する
SQLiteデータベース(パブリックドメイン)、BSDライセンスでJDBCコネクタ、プラットフォーム(OSX、Linuxでは、Windowsの場合)、残りのエミュレーション。の全体の束のためのネイティブ
あなたはJDKにバンドルされているApache Derbyの(またはJavaDB)を使用することができます。ただし、DBMSを使用すると、特定のファイル構造を自分で実装することが必要な速度を提供していません。ただ、正確なキーのルックアップが必要な場合は、あなたはそれを実装するためにハッシュ・ファイルを使用することができます。ハッシュファイル(DBSで使用されるようなBツリーやグリッドなどの汎用ファイル構造よりもはるかに速い)このような要求のための最速のファイル構造です。また、許容可能なストリーミング効率を提供しています。
は、Oracleの「TimesTenの」データベースを見て撮影したことがありますか?非常に高性能であると考えられる。そのAN、インメモリDB。など、コスト/ライセンスについて知っているが、オラクルのサイトを見て、それを検索しないでください。評価ダウンロードが利用可能であるべきである。
私も役立つかもしれないEHCacheなどまたはJCSのいずれかに基づいて、既存のものがありますかどうかを確認するために見てみたい。