В этом посте мы собираемся реализовать очень простое хранилище ключей сохраняемости клиента с RocksDB. Идея состоит в том, чтобы иметь максимально простую реализацию в качестве начального ориентира.
Вы можете найти ссылку с полным исходным кодом для этого поста в разделе “Ссылки” в конце этого поста.
Из документации RocksDB : RocksDB - это постоянное и встраиваемое хранилище ключей и значений для быстрых сред хранения
. Его открытый исходный код и был создан и до сих пор поддерживается Facebook, и он оптимизирован для быстрого хранения с низкой задержкой, такого как флэш-накопители и высокоскоростные диски.
Давайте создадим наш пример, первым шагом будет создание начального приложения SpringBoot с базовыми конечными точками REST, перейдите к start.spring.io и создайте приложение, выберите Java 11, добавив привод и веб в качестве зависимостей для начала, если вы никогда этого не делали, ознакомьтесь с этим сообщением где вы узнаете, как это сделать в очень простых шагах. Давайте назовем это приложение rocksdbBootApp
.
Как только приложение будет создано, следующим шагом будет добавление Rocksjava в качестве зависимости, здесь вы видите фрагмент того, как это сделать с помощью maven.
11 5.5.1 org.rocksdb rocksdbjni ${rocksdb.version}
Давайте теперь создадим интерфейс с подписью основных операций, которые мы хотим, Хранилище значений ключа
.
package io.stockgeeks.repository; public interface KeyValueRepository{ void save(K key, V value); V find(K key); void delete(K key); }
Хорошо, у нас есть базовые начальные операции для сохранения, поиска и удаления записей, давайте реализуем эти базовые операции, самое важное, что следует заметить в следующих фрагментах кода, – это то, что RocksDB работает с байтами таким образом, все это преобразуется в массив байтов и обратно при взаимодействии с его API, потому что мы используем строки здесь, в этом простом примере, мы можем просто использовать getBytes
для преобразования строки в массив байтов и построить его обратно, используя Строку(байт [] байт)
конструктор. Если вам нужно сериализовать объекты, вы можете использовать spring Утилиты сериализации
или, если вы не используете Spring, также есть SerializationUtils
класс в API apache-commons, который можно использовать.
Сначала мы реализуем интерфейс и объявляем константу 1 с именем локального хранилища, которое будет отражено в каталоге в файловой системе, где RocksDB будет хранить структуры данных, мы также определяем ссылку java Файл
, которая указывает на конечную структуру папок и ссылку RocksDB
, которую мы собираемся использовать, мы помечаем класс как @Репозиторий
с аннотацией Spring и добавляем ведение журнала с использованием ломбок @Slf4j
аннотация:
@Slf4j @Repository public class RocksDBRepositoryImpl implements KeyValueRepository{ private final static String NAME = "first-db"; File dbDir; RocksDB db;
Давайте теперь создадим метод инициализации, который инициализирует структуру файловой системы RocksDB и ее конфигурации и подготовит ее к взаимодействию.
Мы используем @PostConstruct
аннотация, поэтому этот фрагмент будет выполнен после запуска приложения. Затем мы убеждаемся, что нужная нам структура каталогов файловой системы создана, и открываем RocksDB
после инициализации, если вы будете следовать приведенному здесь коду, поскольку структура файловой системы, в которой он будет сохраняться, находится в разделе: /tmp/rocks-db/first-db
, вам, вероятно, потребуется немного изменить пути кода, если вы используете среду Windows.
Примечание: Java имеет универсальный путь
@PostConstruct void initialize() { RocksDB.loadLibrary(); final Options options = new Options(); options.setCreateIfMissing(true); dbDir = new File("/tmp/rocks-db", NAME); try { Files.createDirectories(dbDir.getParentFile().toPath()); Files.createDirectories(dbDir.getAbsoluteFile().toPath()); db = RocksDB.open(options, dbDir.getAbsolutePath()); } catch(IOException | RocksDBException ex) { log.error("Error initializng RocksDB, check configurations and permissions, exception: {}, message: {}, stackTrace: {}", ex.getCause(), ex.getMessage(), ex.getStackTrace()); } log.info("RocksDB initialized and ready to use"); }
Теперь, когда приложение готово к работе, мы можем реализовать основные методы операций, начиная с операции сохранения, в этом нет ничего особенного, просто простая простая реализация, мы регистрируем вызов метода и используем метод RocksDB.save
, преобразующий строки, переданные как указано выше, в случае каких-либо исключений мы просто регистрируем ошибку в этом случае:
@Override public synchronized void save(String key, String value) { log.info("save"); try { db.put(key.getBytes(), value.getBytes()); } catch (RocksDBException e) { log.error("Error saving entry in RocksDB, cause: {}, message: {}", e.getCause(), e.getMessage()); } }
Операция поиска также проста, единственное, что важно отметить, это то, что мы проверяем результат на отсутствие нуля. исключение NullPointerException
во время выполнения в случае, если переданный ключ не существует, и вышеупомянутое преобразование из массива байтов в Строку
с использованием конструктора String
.
@Override public String find(String key) { log.info("find"); String result = null; try { byte[] bytes = db.get(key.getBytes()); if(bytes == null) return null; result = new String(bytes); } catch (RocksDBException e) { log.error("Error retrieving the entry in RocksDB from key: {}, cause: {}, message: {}", key, e.getCause(), e.getMessage()); } return result; }
Удаление выполняется по той же схеме, и его реализация проста.
@Override public void delete(String key) { log.info("delete"); try { db.delete(key.getBytes()); } catch (RocksDBException e) { log.error("Error deleting entry in RocksDB, cause: {}, message: {}", e.getCause(), e.getMessage()); } } }
Теперь, когда у нас есть базовая реализация, мы готовы создать API, чтобы завершить пример более интерактивным способом, поэтому давайте создадим простой API с использованием Spring REST, API просто передаст полученные значения в реализацию RocksDB, предоставив ее с помощью базовых вызовов методов HTTP и обработав результаты, возвращающие 200 или 204, когда это применимо, пожалуйста, проверьте Ускоренный курс Spring Boot для получения более подробной информации, объяснений и ссылок о создании базового API с помощью SpringBoot, если вы чувствуете, что вам нужны дополнительные ссылки:
public class RocksApi { private final KeyValueRepositoryrocksDB; public RocksApi(KeyValueRepository rocksDB) { this.rocksDB = rocksDB; } @PostMapping("/{key}") public ResponseEntity save(@PathVariable("key") String key, @RequestBody String value) { log.info("RocksApi.save"); rocksDB.save(key, value); return ResponseEntity.ok(value); } @GetMapping("/{key}") public ResponseEntity find(@PathVariable("key") String key) { log.info("RocksApi.find"); String result = rocksDB.find(key); if(result == null) return ResponseEntity.noContent().build(); return ResponseEntity.ok(result); } @DeleteMapping("/{key}") public ResponseEntity delete(@PathVariable("key") String key) { log.info("RocksApi.delete"); rocksDB.delete(key); return ResponseEntity.ok(key); }
Теперь, когда приложение готово, вы можете создать проект с помощью maven чистый пакет mvn
а затем запустите его mvn spring-boot: запустите
, как только приложение запустится, вы сможете протестировать основные операции с помощью API, который мы только что создали, используя curl , параметры, используемые в приведенной ниже команде curl, предназначены для печати заголовков и полезной нагрузки из запросов, чтобы вы могли немного лучше видеть, что происходит:
Добавить записи: curl -v -H "Тип содержимого: текст/обычный" -X СООБЩЕНИЕ http://localhost:8080/api/rocks/1 -d мое постоянное значение
, если вы добавите новую запись с тем же ключом (1 в пути), она автоматически переопределит предыдущую, обратите внимание, что ключом может быть любая строка в этой простой реализации, здесь мы просто используем 1 в качестве ключа для примера, который анализируется как строка.
Getentries: curl-iv-X GET-H "Тип содержимого: текст/обычный" http://localhost:8080/api/rocks/1
Удалить записи: curl -X УДАЛИТЬ http://localhost:8080/api/rocks/1
Сделано! Это была очень простая начальная ссылка, предназначенная для того, чтобы вы начали, если вам когда-нибудь понадобится использовать постоянный кэш на стороне клиента и вы решите, что RocksDB – хороший вариант, это, безусловно, только верхушка, RocksDB предоставляет вам множество других возможных вариантов, когда вам нужно настроить свой кэш, вы можете установить фильтры (например, BloomFilter), вы можете настроить кэш LRU, и доступны многие другие опции, ознакомьтесь с их полной документацией и ссылками в справочном разделе ниже для получения дополнительной информации.
Примечание: Кафка использует RocksDB по умолчанию при создании потоков и использовании таблиц или глобальных таблиц K.
Клонировать исходный код с github rocksdbBootApp : Клонировать git git@github.com:stockgeeks/rocksdbBootApp.git
Создает документацию и проект Java
Фотография в заголовке Кристофер Гауэр на Unsplash
Оригинал: “https://dev.to/thegroo/simple-rocksdb-with-java-crash-course-20o7”