Рубрики
Без рубрики

Простая база данных RocksDB с Java – Ускоренный курс

В этом посте мы собираемся реализовать очень простое хранилище ключей сохраняемости клиента с RocksDB… С тегами java, spring boot, микросервисы, rocksdb.

В этом посте мы собираемся реализовать очень простое хранилище ключей сохраняемости клиента с 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 KeyValueRepository rocksDB;

  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”