1
0

More than 3 years have passed since last update.

JavaでRocksDBを使用してみる

Posted at

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

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0