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

Путеводитель по Редису с Radisson

Краткое и практическое руководство по использованию Radisson для доступа к Redis из приложения Java.

Автор оригинала: baeldung.

1. Обзор

Radisson-это клиент Redis для Java . В этой статье мы рассмотрим некоторые из его функций и продемонстрируем, как он может облегчить создание распределенных бизнес-приложений.

Radisson представляет собой сетку данных в памяти , которая предлагает распределенные объекты Java и службы, поддерживаемые Redis . Его распределенная модель данных в памяти позволяет совместно использовать доменные объекты и службы между приложениями и серверами.

В этой статье мы рассмотрим, как настроить Radisson, поймем, как он работает, и изучим некоторые объекты и услуги Radisson.

2. Зависимости Maven

Давайте начнем с импорта Radisson в наш проект, добавив раздел ниже к вашему pom.xml:


    org.redisson
    redisson
    3.13.1

Последнюю версию этой зависимости можно найти здесь .

3. Конфигурация

Прежде чем мы начнем, мы должны убедиться, что у нас установлена и запущена последняя версия Redis. Если у вас нет Redis и вы используете Linux или Macintosh, вы можете следовать информации здесь , чтобы настроить его. Если вы являетесь пользователем Windows, вы можете настроить Redis, используя этот неофициальный порт .

Нам нужно настроить Radisson для подключения к Redis. Radisson поддерживает подключения к следующим конфигурациям Redis:

  • Один узел
  • Ведущий с подчиненными узлами
  • Сторожевые узлы
  • Кластеризованные узлы
  • Реплицированные узлы

Radisson поддерживает кластер Amazon Web Services (AWS) ElastiCache и кэш Azure Redis для кластеризованных и реплицированных узлов.

Давайте подключимся к экземпляру Redis с одним узлом. Этот экземпляр работает локально на порту по умолчанию 6379:

RedissonClient client = Redisson.create();

Вы можете передать различные конфигурации в метод Radisson объекта create . Это может быть конфигурация для подключения к другому порту или, возможно, для подключения к кластеру Redis. Эта конфигурация может быть в коде Java или загружена из внешнего файла конфигурации .

3.1. Конфигурация Java

Давайте настроим его в коде Java:

Config config = new Config();
config.useSingleServer()
  .setAddress("redis://127.0.0.1:6379");

RedissonClient client = Redisson.create(config);

Мы указываем конфигурации в экземпляре Config object , а затем передаем его методу create . Выше мы указали Radisson, что хотим подключиться к экземпляру Redis с одним узлом. Для этого мы использовали метод Config объекта use Single Server . Это возвращает ссылку на объект Single Server Config .

Объект Single Server Config имеет настройки, которые Radisson использует для подключения к экземпляру Redis с одним узлом. Здесь мы используем его метод setAddress для настройки параметра address . Это устанавливает адрес узла, к которому мы подключаемся. Некоторые другие настройки включают в себя повторные попытки , тайм-аут подключения и Имя клиента . Эти параметры настраиваются с помощью соответствующих методов настройки.

Мы можем настроить Radisson для различных конфигураций Redis аналогичным образом, используя следующие методы объекта Config :

  • useSingleServer – для экземпляра одного узла. Получить настройки одного узла здесь
  • useMasterSlaveServers – для ведущего с подчиненными узлами. Получить настройки ведущего-ведомого узла здесь
  • useSentinelServers – для узлов sentinel. Получить настройки узла sentinel здесь
  • useClusterServers – для кластеризованных узлов. Получить настройки кластеризованного узла здесь
  • useReplicatedServers – для реплицированных узлов. Получить настройки реплицированного узла здесь

3.2. Конфигурация файла

Вы можете загружать конфигурации из внешних файлов JSON или YAML :

Config config = Config.fromJSON(new File("singleNodeConfig.json"));  
RedissonClient client = Redisson.create(config);

Метод Config объекта FromJSON может загружать конфигурации из строки, файла, входного потока или URL-адреса.

Вот пример конфигурации в файле single Node Config.json :

{
    "singleServerConfig": {
        "idleConnectionTimeout": 10000,
        "connectTimeout": 10000,
        "timeout": 3000,
        "retryAttempts": 3,
        "retryInterval": 1500,
        "password": null,
        "subscriptionsPerConnection": 5,
        "clientName": null,
        "address": "redis://127.0.0.1:6379",
        "subscriptionConnectionMinimumIdleSize": 1,
        "subscriptionConnectionPoolSize": 50,
        "connectionMinimumIdleSize": 10,
        "connectionPoolSize": 64,
        "database": 0,
        "dnsMonitoringInterval": 5000
    },
    "threads": 0,
    "nettyThreads": 0,
    "codec": null
}

Вот соответствующий файл конфигурации YAML:

singleServerConfig:
    idleConnectionTimeout: 10000
    connectTimeout: 10000
    timeout: 3000
    retryAttempts: 3
    retryInterval: 1500
    password: null
    subscriptionsPerConnection: 5
    clientName: null
    address: "redis://127.0.0.1:6379"
    subscriptionConnectionMinimumIdleSize: 1
    subscriptionConnectionPoolSize: 50
    connectionMinimumIdleSize: 10
    connectionPoolSize: 64
    database: 0
    dnsMonitoringInterval: 5000
threads: 0
nettyThreads: 0
codec: ! {}

Мы можем настроить другие конфигурации Redis из файла аналогичным образом, используя параметры, характерные для этой конфигурации. Для справки, вот их форматы файлов JSON и YAML:

Чтобы сохранить конфигурацию Java в формате JSON или YAML, мы можем использовать методы toJSON или toYAML объекта Config :

Config config = new Config();
// ... we configure multiple settings here in Java
String jsonFormat = config.toJSON();
String yamlFormat = config.toYAML();

Теперь, когда мы знаем, как настроить Radisson, давайте посмотрим, как Radisson выполняет операции.

4. Эксплуатация

Radisson поддерживает синхронные, асинхронные и реактивные интерфейсы . Операции над этими интерфейсами являются потокобезопасными .

Все сущности (объекты, коллекции, блокировки и службы), созданные клиентом Radisson , имеют синхронные и асинхронные методы. Синхронные методы имеют асинхронные варианты . Эти методы обычно имеют одно и то же имя метода их синхронных вариантов, добавленное с “асинхронным”. Давайте рассмотрим синхронный метод объекта Atomiclong :

RedissonClient client = Redisson.create();
RAtomicLong myLong = client.getAtomicLong('myLong');

Асинхронным вариантом метода synchronous compareAndSet будет:

RFuture isSet = myLong.compareAndSetAsync(6, 27);

Асинхронный вариант метода возвращает объект Future . Мы можем установить прослушиватели на этот объект, чтобы получить результат, когда он станет доступным:

isSet.handle((result, exception) -> {
    // handle the result or exception here.
});

Чтобы генерировать реактивные объекты, нам нужно будет использовать клиент Radisson Reactive :

RedissonReactiveClient client = Redisson.createReactive();
RAtomicLongReactive myLong = client.getAtomicLong("myLong");

Publisher isSetPublisher = myLong.compareAndSet(5, 28);

Этот метод возвращает реактивные объекты на основе стандарта Reactive Streams для Java 9.

Давайте рассмотрим некоторые из распределенных объектов, предоставляемых Radisson.

5. Объекты

Отдельный экземпляр объекта Radisson сериализуется и хранится в любом из доступных узлов Redis, поддерживающих Redisson . Эти объекты могут быть распределены в кластере по нескольким узлам и доступны одному приложению или нескольким приложениям/серверам.

Эти распределенные объекты следуют спецификациям из пакета java.util.concurrent.atomic. Они поддерживают операции без блокировки, потокобезопасные и атомарные операции с объектами, хранящимися в Redis . Согласованность данных между приложениями/серверами обеспечивается, поскольку значения не обновляются, пока другое приложение считывает объект.

Объекты Radisson привязаны к ключам Redis. Мы можем управлять этими ключами через интерфейс Keys . А затем мы получаем доступ к нашим объектам Radisson с помощью этих ключей.

Есть несколько вариантов, которые мы можем использовать для получения ключей Redis.

Мы можем просто получить все ключи:

RKeys keys = client.getKeys();

В качестве альтернативы мы можем извлечь только имена:

Iterable allKeys = keys.getKeys();

И, наконец, мы можем получить ключи, соответствующие шаблону:

Iterable keysByPattern = keys.getKeysByPattern('key*')

Интерфейс ключей также позволяет удалять ключи, удалять ключи по шаблону и другие полезные операции на основе ключей, которые мы могли бы использовать для управления нашими ключами и объектами.

Распределенные объекты, предоставляемые Radisson, включают в себя:

  • Держатель объекта
  • Держатель BinaryStream
  • Геопространственный держатель
  • Набор битов
  • АтомикЛонг
  • Атомный Двойник
  • Тема
  • Фильтр Блума
  • HyperLogLog

Давайте рассмотрим три из этих объектов: Держатель объекта, AtomicLong, и Тема.

5.1. Держатель объекта

Представленный классом Bucket , этот объект может содержать объекты любого типа. Этот объект имеет максимальный размер 512 МБ:

RBucket bucket = client.getBucket("ledger");
bucket.set(new Ledger());
Ledger ledger = bucket.get();

Объект Bucket может выполнять атомарные операции, такие как compareAndSet и get и Set на объектах, которые он содержит.

5.2. Атомная длина

Представленный классом Atomiclong , этот объект очень похож на java.util.concurrent.atomic.Класс AtomicLong и представляет значение long , которое может быть обновлено атомарно:

RAtomicLong atomicLong = client.getAtomicLong("myAtomicLong");
atomicLong.set(5);
atomicLong.incrementAndGet();

5.3. Тема

Объект Topic поддерживает механизм “публикации и подписки” Redis. Прослушивание опубликованных сообщений:

RTopic subscribeTopic = client.getTopic("baeldung");
subscribeTopic.addListener(CustomMessage.class,
  (channel, customMessage) -> future.complete(customMessage.getMessage()));

Выше Тема зарегистрирована для прослушивания сообщений с канала “baeldung”. Затем мы добавляем прослушиватель в тему для обработки входящих сообщений с этого канала. Мы можем добавить несколько слушателей на канал.

Давайте опубликуем сообщения на канале “baeldung”:

RTopic publishTopic = client.getTopic("baeldung");
long clientsReceivedMessage
  = publishTopic.publish(new CustomMessage("This is a message"));

Это может быть опубликовано из другого приложения или сервера. Объект Custom Message будет получен слушателем и обработан, как определено в методе onMessage .

Мы можем узнать больше о других объектах Radisson здесь .

6. Коллекции

Мы обрабатываем коллекции Radisson таким же образом, как и объекты.

Распределенные коллекции, предоставляемые Radisson, включают в себя:

  • Карта
  • Multimap
  • Набор
  • Сортированный набор
  • Забил сортированный набор
  • Лекс Сортированный набор
  • Список
  • Очередь
  • Деке
  • BlockingQueue
  • BoundedBlockingQueue
  • BlockingDeque
  • Блокировка Справедливой Очереди
  • Отложенная очередь
  • Приоритетная очередь
  • Приоритетный Дек

Давайте рассмотрим три из этих коллекций: Map, Set, и List.

6.1. Карта

Карты на основе Radisson реализуют java.util.concurrent.ConcurrentMap и java.util.Карта Интерфейсы. Radisson имеет четыре реализации карт. Это RMap , RMapCache , RLocalCachedMap и R Кластерная карта .

Давайте создадим карту с Radisson:

RMap map = client.getMap("ledger");
Ledger newLedger = map.put("123", new Ledger());map

Кэш карт поддерживает выселение записей на карте. RLocalCachedMap позволяет локальное кэширование записей карты . Кластерная карта позволяет распределять данные с одной карты по основным узлам кластера Redis.

Мы можем узнать больше о картах Radisson здесь .

6.2. Набор

/| Set реализует java.util.Установить интерфейс.

Radisson имеет три реализации Set , Reset , Reset Cache и R Clustered Set с аналогичной функциональностью , как и их аналоги на карте.

Давайте создадим Набор с помощью Radisson:

RSet ledgerSet = client.getSet("ledgerSet");
ledgerSet.add(new Ledger());

Мы можем узнать больше о наборах Radisson здесь .

6.3. Список

На основе/| Списков реализуйте java.util.Список интерфейс.

Давайте создадим Список с помощью Radisson:

RList ledgerList = client.getList("ledgerList");
ledgerList.add(new Ledger());

Мы можем узнать больше о других коллекциях Radisson здесь .

7. Замки и синхронизаторы

Распределенные блокировки Radisson позволяют синхронизировать потоки между приложениями/серверами. Список блокировок и синхронизаторов Radisson включает в себя:

  • Замок
  • Шлюз
  • Мультиблок
  • ReadWriteLock
  • Семафор
  • PermitExpirableSemaphore
  • Обратный отсчет

Давайте взглянем на Lock и Multi Lock.

7.1. Блокировка

/| Lock реализует java.util.concurrent.замки.Блокировка интерфейс.

Давайте реализуем блокировку, представленную классом RLock :

RLock lock = client.getLock("lock");
lock.lock();
// perform some long operations...
lock.unlock();

7.2. Мультиблокировка

Radisson RedissonMultiLock группирует несколько RLock объектов и обрабатывает их как одну блокировку:

RLock lock1 = clientInstance1.getLock("lock1");
RLock lock2 = clientInstance2.getLock("lock2");
RLock lock3 = clientInstance3.getLock("lock3");

RedissonMultiLock lock = new RedissonMultiLock(lock1, lock2, lock3);
lock.lock();
// perform long running operation...
lock.unlock();

Мы можем узнать больше о других замках здесь .

8. Услуги

Radisson предоставляет 4 типа распределенных услуг. Это: Удаленная служба , Служба живых объектов , ExecutorService и ScheduledExecutorService . Давайте рассмотрим Удаленную службу и Службу живых объектов.

8.1. Удаленное обслуживание

Эта служба обеспечивает Удаленный вызов метода Java, облегченный Redis . Удаленная служба Radisson состоит из серверной (рабочий экземпляр) и клиентской реализации. Реализация на стороне сервера выполняет удаленный метод, вызываемый клиентом. Вызовы из удаленной службы могут быть синхронными или асинхронными.

Серверная сторона регистрирует интерфейс для удаленного вызова:

RRemoteService remoteService = client.getRemoteService();
LedgerServiceImpl ledgerServiceImpl = new LedgerServiceImpl();

remoteService.register(LedgerServiceInterface.class, ledgerServiceImpl);

Клиентская сторона вызывает метод зарегистрированного удаленного интерфейса:

RRemoteService remoteService = client.getRemoteService();
LedgerServiceInterface ledgerService
  = remoteService.get(LedgerServiceInterface.class);

List entries = ledgerService.getEntries(10);

Мы можем узнать больше об удаленных сервисах здесь .

8.2. Обслуживание живых объектов

Живые объекты Redisson расширяют концепцию стандартных объектов Java, доступ к которым возможен только из одной JVM, до расширенных объектов Java, которые могут совместно использоваться различными JVM на разных машинах . Это достигается путем сопоставления полей объекта с хэшем Redis. Это сопоставление выполняется через прокси-класс, созданный во время выполнения. Геттеры и сеттеры полей сопоставляются командам Redis hget/h set.

Живые объекты Radisson поддерживают доступ к атомарным полям в результате однопоточной природы Redis.

Создание живого объекта очень просто:

@REntity
public class LedgerLiveObject {
    @RId
    private String name;

    // getters and setters...
}

Мы аннотируем наш класс с помощью @Entity и уникального или идентифицирующего поля с помощью @RId . Как только мы это сделаем, мы сможем использовать наш живой объект в нашем приложении:

RLiveObjectService service = client.getLiveObjectService();

LedgerLiveObject ledger = new LedgerLiveObject();
ledger.setName("ledger1");

ledger = service.persist(ledger);

Мы создаем наш живой объект, как стандартные объекты Java, используя ключевое слово new . Затем мы используем экземпляр R Live Object Service , чтобы сохранить объект в Redis, используя его метод persist .

Если объект ранее сохранялся в Redis, мы можем получить его:

LedgerLiveObject returnLedger
  = service.get(LedgerLiveObject.class, "ledger1");

Мы используем сервис R Live Object , чтобы получить наш живой объект, используя поле с аннотацией @RId .

Здесь мы можем узнать больше об объектах Radisson Live, а другие услуги Radisson описаны здесь.

9. Конвейеризация

Radisson поддерживает конвейерную обработку. Несколько операций могут быть объединены в одну атомарную операцию . Этому способствует класс Batch . Несколько команд объединяются с экземпляром объекта R Batch перед их выполнением:

RBatch batch = client.createBatch();
batch.getMap("ledgerMap").fastPutAsync("1", "2");
batch.getMap("ledgerMap").putAsync("2", "5");

BatchResult batchResult = batch.execute();

10. Сценарии

Radisson поддерживает сценарии LUA. Мы можем выполнять LUA-скрипты против Redis :

client.getBucket("foo").set("bar");
String result = client.getScript().eval(Mode.READ_ONLY,
  "return redis.call('get', 'foo')", RScript.ReturnType.VALUE);

11. Клиент низкого Уровня

Возможно, мы захотим выполнить операции Redis, которые еще не поддерживаются Radisson. Radisson предоставляет низкоуровневый клиент, который позволяет выполнять собственные команды Redis :

RedisClientConfig redisClientConfig = new RedisClientConfig();
redisClientConfig.setAddress("localhost", 6379);

RedisClient client = RedisClient.create(redisClientConfig);

RedisConnection conn = client.connect();
conn.sync(StringCodec.INSTANCE, RedisCommands.SET, "test", 0);

conn.closeAsync();
client.shutdown();

Клиент низкого уровня также поддерживает асинхронные операции.

12. Заключение

В этой статье мы продемонстрировали Radisson и некоторые функции, которые делают его идеальным для разработки распределенных приложений. Мы исследовали его распределенные объекты, коллекции, замки и сервисы. Мы также изучили некоторые другие его функции, такие как конвейеризация, сценарии и низкоуровневый клиент.

Radisson также обеспечивает интеграцию с другими фреймворками , такими как API JCache, Spring Cache, Hibernate Cache и Spring Sessions. Мы можем узнать больше о его интеграции с другими фреймворками здесь .

Примеры кода можно найти в проекте GitHub .