RockDBとは
Key-Valueのデータ形式(バイト配列)を保持するデータベース。
C++で作られており、JavaからもJNIで使用できる。
ただし、JavaのAPIはC++のAPIに追いついていないとのこと。
Wiki
https://ja.wikipedia.org/wiki/RocksDB
使い方
以下に簡単な使用方法を記載します。
詳細は公式のドキュメントを参照してください。
Maven
以下のライブラリを使用します。
RocksDbのみを使用する場合、rocksdbjniのみでOK。
シリアライズ、デシリアライズのためにkryoを追加しています。
<dependency>
<groupId>org.rocksdb</groupId>
<artifactId>rocksdbjni</artifactId>
<version>6.0.1</version>
</dependency>
<dependency>
<groupId>com.esotericsoftware</groupId>
<artifactId>kryo</artifactId>
<version>3.0.1</version>
</dependency>
オープン・クローズ
クローズ用のメソッドもあるが、try-with-resourcesの使用を推奨しているので、従いましょう。
openにはDB保存先のパスを指定する必要があります。以下のように指定するとプロジェクト直下にDB用のフォルダが作成されます。
try (RocksDB rocksDb = RocksDB.open("sample")) {
// ここに処理を書く
}
読み込み、書き込み、削除
基本的なAPIの使用例です。
読み込みはget、書き込みはput、削除はdeleteです。
その他、全件取得(newIterator)、範囲削除(deleteRange)、複数取得(multiGetAsList)の使用例を記載しています。
public void execute() {
// RocksDBをOpenする。openにはDB保存先を指定する(下記の指定を行うとプロジェクト直下に作成される)
try (RocksDB rocksDb = RocksDB.open("sample")) {
// Kryoを使用してシリアライズ
byte[] binaryKey = serialize("key");
byte[] binaryValue = serialize("Value");
// Key、Valueを指定してRocksDBにput(API#put)
// 重複したKeyを登録してもエラーとならず、上書きするだけ
rocksDb.put(binaryKey, binaryValue);
rocksDb.put(binaryKey, binaryValue);
// シリアライズしたKeyを使用して、RocksDBから取得(API#get)
try (Input input = new Input(rocksDb.get(binaryKey))) {
System.out.println(kryo.readObject(input, String.class));
}
// Keyを指定してRockDBから削除(API#delete)
rocksDb.delete(binaryKey);
if (null == rocksDb.get(binaryKey)) {
System.out.println("取得できません");
}
for (int i = 0; i < 10; i++) {
// Kryoを使用してシリアライズ
byte[] tempBinaryKey = serialize("key" + String.valueOf(i));
byte[] tempBinaryValue = serialize("Value"+ String.valueOf(i));
// Key、Valueを指定してRocksDBにput
rocksDb.put(tempBinaryKey, tempBinaryValue);
}
// RocksDB内のすべてのデータ取得(API#newIterator)
System.out.println("全Entry取得");
RocksIterator iterator = rocksDb.newIterator();
iterator.seekToFirst();
while (iterator.isValid()) {
try (Input input = new Input(iterator.key())) {
System.out.println(kryo.readObject(input, String.class));
}
iterator.next();
}
// RocksDB内をキーの範囲を指定して削除(API#deleteRange)
// beginKeyに指定〜EndKeyの直前までが削除される
rocksDb.deleteRange(serialize("key0"), serialize("key8"));
System.out.println("範囲削除key0-key7");
RocksIterator iterator2 = rocksDb.newIterator();
iterator2.seekToFirst();
while (iterator2.isValid()) {
try (Input input = new Input(iterator2.value())) {
System.out.println(kryo.readObject(input, String.class));
}
iterator2.next();
}
// RocksDB内複数取得(#multiGetAsList)
System.out.println("複数取得");
List<byte[]> binaryKeyList = new ArrayList<>();
binaryKeyList.add(serialize("key8"));
binaryKeyList.add(serialize("key9"));
List<byte[]> binaryValueList = rocksDb.multiGetAsList(binaryKeyList);
for (byte[] binary:binaryValueList) {
try (Input input = new Input(binary)) {
System.out.println(kryo.readObject(input, String.class));
}
}
} catch (RocksDBException e) {
throw new RuntimeException(e);
}
}
private byte[] serialize(String str) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try (Output output = new Output(baos)) {
kryo.writeObject(output, str);
}
return baos.toByteArray();
}
どんなときに使う?
ライブラリを導入するだけで使用できるため、RDBを使用するまでも行かないけど、
データの永続化が必要な場面で活躍すると思います。
参考
https://github.com/EsotericSoftware/kryo
https://github.com/facebook/rocksdb/wiki/RocksJava-Basics