Статьи

Обзор Redisson: клиент Redis Java

Проверьте этот всесторонний обзор Redisson!

Почему Редиссон?

Redis — это хранилище структуры данных с открытым исходным кодом в памяти, которое можно использовать как базу данных ключей NoSQL, а также как кеш и брокер сообщений.

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

Согласно опросу 2019 года, посвященному программированию веб-сайта Stack Overflow, Redis является «самой любимой» технологией баз данных , опережая более устоявшиеся альтернативы, такие как Oracle, MySQL, Microsoft SQL Server и MongoDB.


Вам также может понравиться:
Распределенные коллекции Java в Redis с Redisson

Хотя Redis обладает множеством функций и преимуществ, пользователи должны знать, что Redis не совместим с такими языками программирования, как Java, из коробки. Скорее, пользователи, которые хотят использовать Redis с Java, должны использовать стороннюю клиентскую библиотеку Java для Redis, такую ​​как Redisson.

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

Redisson позволяет разработчикам уделять меньше времени программному аспекту Redis и уделять больше времени таким важным задачам, как моделирование данных и логика приложения.

Основанный на асинхронной управляемой событиями среде клиент-сервер Netty , Redisson совместим с Redis 2.8+ и JDK 1.8+. Redisson поставляется в двух версиях: проект Redisson с открытым исходным кодом и Redisson PRO , который имеет большую скорость и дополнительную функциональность.

В этой статье будет представлен полный обзор всего, что вам нужно знать о работе с Redisson: настройка Redisson, настройка Redis с Redisson, использование объектов Java и коллекций в Redis с Redisson, другие функции Redisson.

Maven Dependency

Большие, сложные Java-проекты часто используют инструменты автоматизации сборки, такие как Apache Maven . Если вы используете Maven для создания своего Java-проекта, включить поддержку Redisson очень просто. Просто включите следующие строки в ваш файл pom.xml :

<dependency>
    <groupId>org.redisson</groupId>
    <artifactId>redisson</artifactId>
    <version>3.11.5</version>
</dependency>

Это обеспечит последнюю версию Redisson для вашего Java-проекта (3.11.5 на момент написания статьи). Чтобы убедиться, что вы используете самую последнюю версию Redisson, проверьте страницу проекта Redisson на GitHub .

Gradle Dependency

Как и Maven, Gradle — это еще один инструмент автоматизации сборки с открытым исходным кодом для проектов Java. Также как и в Maven, поддержка Redisson в Gradle чрезвычайно проста. Добавьте следующую строку в ваш файл build.gradle :

compile 'org.redisson:redisson:3.11.5'

Опять же, вы можете найти последнюю версию Redisson на странице проекта Redisson на GitHub .

Redis Setup

Естественно, первым шагом для использования Redisson с Redis является установка Redis. Инструкции по установке Redis в Linux и Mac OS X можно найти на странице быстрого запуска Redis . Если вы работаете на Windows, вы можете попробовать использовать неофициальный порт Microsoft Redis (хотя, обратите внимание, что этот проект больше не поддерживается).

После того, как вы включили зависимость Redisson через Maven или Gradle и установили Redis, следующим шагом будет подключение Redisson к Redis. Redisson поддерживает подключения к следующим конфигурациям Redis:

  • Один узел
  • Мастер с подчиненными узлами
  • Часовые узлы
  • Кластерные узлы
  • Реплицированные узлы

Следующая строка кода Java подключается к одному экземпляру узла Redis:

RedissonClient client = Redisson.create();

После выполнения этой строки кода клиент работает на порту по умолчанию 6379. Вы можете изменить этот номер порта, а также другие параметры Redisson, передав аргументы Redisson.create()методу. Эта конфигурация может быть написана непосредственно на Java или загружена из внешнего файла.

Настройка Redisson в Java

Ниже приведен пример того, как настроить Redisson напрямую в Java:

Config config = new Config();
config.useSingleServer()
.setAddress("127.0.0.1:6379");
RedissonClient client = Redisson.create(config);

В этом коде мы сначала создаем экземпляр Configобъекта, а затем настраиваем его для использования IP-адреса 127.0.0.1 с номером порта 6379.

useSingleServer()Метод указывает Redis , что мы хотим подключить к одному экземпляру узла Redis. Другие варианты подключения к различным конфигурациям Redis:

Настройка Redisson из внешнего файла

Кроме того, мы можем настроить Redisson, загрузив настройки из внешнего файла JSON или YAML. Ниже приведен пример загрузки настроек Redisson из внешнего файла YAML:

Config config = Config.fromYAML(new File("redisson.yaml"));  
RedissonClient client = Redisson.create(config);

Настройки Redisson по умолчанию в соответствующем файле YAML:

singleServerConfig:
    idleConnectionTimeout: 10000
    pingTimeout: 1000
    connectTimeout: 10000
    timeout: 3000
    retryAttempts: 3
    retryInterval: 1500
    reconnectionTimeout: 3000
    failedAttempts: 3
    password: null
    subscriptionsPerConnection: 5
    clientName: null
    address: "redis://127.0.0.1:6379"
    subscriptionConnectionMinimumIdleSize: 1
    subscriptionConnectionPoolSize: 50
    connectionMinimumIdleSize: 10
    connectionPoolSize: 64
    database: 0
    dnsMonitoring: false
    dnsMonitoringInterval: 5000
threads: 0
nettyThreads: 0
codec: !<org.redisson.codec.FstCodec> {}
useLinuxNativeEpoll: false

Подробную информацию о настройке Redisson смотрите на странице конфигурации в вики Redisson .

Java-объекты на основе Redis

Redisson включает в себя поддержку широкого спектра объектов Java. Отдельные экземпляры объекта Redisson сериализуются и сохраняются в доступном узле Redis или распределяются в кластере по нескольким узлам.

Распределенные объекты Java в Redisson соответствуют спецификациям пакета java.util.concurrent.atomic . Таким образом, вы можете выполнять без блокировки, поточно-ориентированные и атомарные операции над объектами, хранящимися в Redis. Данные остаются согласованными между различными приложениями и серверами.

В этом разделе мы обсудим различные распределенные объекты Java в Redisson. Для получения более подробной информации обратитесь к странице « Распределенные объекты» в вики Redisson .

ObjectHolder

Класс RBucket в Redisson переопределяет  ObjectHolder класс в Java. RBucket Объект способен удерживать любой тип объекта. Он также имеет интерфейсы Reactive и RxJava2. Пример кода:

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

BinaryStreamHolder

Интерфейс RBinaryStream в Redisson содержит двоичный поток. Вы можете легко читать и писать в поток , используя  InputStream и  OutputStream объекты:

RBinaryStream stream = redisson.getBinaryStream("anyStream");
byte[] content = ...
stream.set(content);

InputStream is = stream.getInputStream();
byte[] readBuffer = new byte[512];
is.read(readBuffer);

OutputStream os = stream.getOuputStream();
byte[] contentToWrite = ...
os.write(contentToWrite);

GeospatialHolder

Интерфейс RGeo в Redisson содержит геопространственные элементы. Он также имеет интерфейсы Reactive и RxJava2. Пример кода:

RGeo<String> geo = redisson.getGeo("test");
geo.add(new GeoEntry(13.361389, 38.115556, "Palermo"), 
new GeoEntry(15.087269, 37.502669, "Catania"));
geo.addAsync(37.618423, 55.751244, "Moscow");

BitSet

Интерфейс RBitSet в Redisson представляет битовый вектор, который может расширяться по мере необходимости, с максимальным размером 4 294 967 295 бит. Он также имеет интерфейсы Reactive и RxJava2. Пример кода:

RBitSet set = redisson.getBitSet("simpleBitset");
set.set(0, true);
set.set(1812, false);
set.clear(0);

AtomicLong

Интерфейс RAtomicLong в Redisson переопределяет  AtomicLong класс в Java, представляя длинное целое значение, которое может быть обновлено атомарно. Он также имеет интерфейсы Reactive и RxJava2. Пример кода:

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

AtomicDouble

Интерфейс RAtomicDouble в Redisson переопределяет  AtomicDouble класс в Java, представляя двойное значение, которое может быть обновлено атомарно. Он также имеет интерфейсы Reactive и RxJava2. Пример кода:

RAtomicDouble atomicDouble = redisson.getAtomicDouble("myAtomicDouble");
atomicDouble.set(2.81);
atomicDouble.addAndGet(4.11);

Тема

Интерфейс RTopic в Redisson используется для реализации системы обмена сообщениями публикации / подписки. Подписчики могут прослушивать сообщения по определенной теме. Он также имеет интерфейсы Reactive и RxJava2. Пример кода:

RTopic topic = redisson.getTopic("anyTopic");
topic.addListener(SomeObject.class, new MessageListener<SomeObject>() {
    @Override
    public void onMessage(String channel, SomeObject message) {
        //...
    }
});

Фильтр Блума

Интерфейс RBloomFilter в Redisson используется для реализации структуры данных фильтра Блума:

RBloomFilter<SomeObject> bloomFilter = redisson.getBloomFilter("sample");
// initialize bloom filter with 
// expectedInsertions = 55000000
// falseProbability = 0.03
bloomFilter.tryInit(55000000L, 0.03);
bloomFilter.add(new SomeObject("field1Value", "field2Value"));
bloomFilter.add(new SomeObject("field5Value", "field8Value"));
bloomFilter.contains(new SomeObject("field1Value", "field8Value"));

HyperLogLog

Интерфейс RHyperLogLog в Redisson обеспечивает доступ к  HyperLogLog алгоритму и структуре данных, реализованным в Redis. HyperLogLog используется для оценки количества уникальных элементов в мультимножестве. Он также имеет интерфейсы Reactive и RxJava2. Пример кода:

RHyperLogLog<Integer> log = redisson.getHyperLogLog("log");
log.add(1);
log.add(2);
log.add(3);
log.count();

Коллекции Java на основе Redis

Коллекции Java в Redisson обрабатываются так же, как объекты. Это позволяет вам выполнять без блокировки, поточно-ориентированные и атомарные операции над коллекциями Java в Redisson.

Коллекции Java, поддерживаемые Redisson:

  • карта
  • Multimap
  • Поставил
  • SortedSet
  • ScoredSortedSet
  • LexSortedSet
  • Список
  • Очередь
  • Deque
  • BlockingQueue
  • BoundedBlockingQueue
  • BlockingDeque
  • BlockingFairQueue
  • DelayedQueue
  • PriorityQueue
  • PriorityDeque

Подробные сведения об использовании этих коллекций в Redisson см. На странице « Распределенные коллекции» в вики Redisson .

Основанные на Redis блокировки и синхронизаторы

В Redisson распределены блокировки и синхронизаторы, что позволяет синхронизировать потоки между несколькими приложениями и серверами. Блокировки и синхронизаторы Java, поддерживаемые Redisson:

  • Замок
  • FairLock
  • MULTILOCK
  • ReadWriteLock
  • семафор
  • PermitExpirableSemaphore
  • CountDownLatch

Подробные сведения об использовании этих коллекций в Redisson см. На странице « Распределенные блокировки и синхронизаторы» в вики Redisson .

Замок

Интерфейс RLock в Redisson является распределенной реализацией интерфейса Lock в Java. Он также имеет интерфейсы Reactive и RxJava2. Пример кода:

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

MULTILOCK

RedissonMultiLock Класс Redisson позволяет пользователям управлять несколькими замками , как единое целое:

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();

семафор

Интерфейс RSemaphore в Redisson используется для управления доступом к общему ресурсу с помощью счетчика. Он также имеет интерфейсы Reactive и RxJava2. Пример кода:

RSemaphore semaphore = redisson.getSemaphore("semaphore");
semaphore.acquire();
// or
semaphore.acquireAsync();
semaphore.acquire(23);
semaphore.tryAcquire();

semaphore.releaseAsync();

Сервисы на базе Redis

Redisson включает поддержку пяти типов распределенных сервисов: Удаленный сервис, Сервис Live Object, Сервис Executor, Сервис Scheduled Executor и Сервис MapReduce. Полное руководство по распределенным службам в Redisson см. На странице « Распределенные службы» в вики Redisson .

Дистанционное обслуживание

Этот сервис позволяет пользователям Redisson выполнять удаленные вызовы процедур в Java с помощью API-интерфейсов Async, Reactive и RxJava2. Он включает в себя два аспекта: реализацию на стороне сервера и реализацию на стороне клиента.

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

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

remoteService.register(LedgerServiceInterface.class, ledgerServiceImpl);

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

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

List<String> entries = ledgerService.getEntries(10);

Сервис живых объектов

«Живые объекты» в Redisson — это расширенная версия стандартных объектов Java, которые могут совместно использоваться различными машинами и различными JVM. Поля живого объекта отображаются в хэше Redis и могут быть доступны атомарно, благодаря однопоточности Redis.

Код ниже демонстрирует создание живого объекта в Redis. @RId Аннотацию обозначает уникальное или идентифицирующее поле:

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

    // getters and setters...
}

После создания живой объект можно использовать в приложении и сохранить в Redis с помощью   persist() метода:

RLiveObjectService service = client.getLiveObjectService();

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

ledger = service.persist(ledger);

операции

Транзакции в Redis являются атомарными: либо все команды в транзакции обрабатываются, либо ни одна из них не выполняется. MULTIEXECDISCARD, И  WATCH являются четыре команды , которые являются основой Redis сделок. Команда  MULTI допускает несколько команд в транзакции, в то время как  EXEC команда выполняет все команды в транзакции.

Redisson поддерживает выполнение транзакций с уровнем изоляции,  READ_COMMITTED используя блокировки во время операций записи. Объекты , которые имеют право на сделки в Redisson включают  RMapRMapCacheRLocalCachedMapRSetRSetCache, и  RBucket.

The following code demonstrates the execution of a transaction in Redisson:

RTransaction transaction = redisson.createTransaction(TransactionOptions.defaults());

RMap<String, String> map = transaction.getMap("myMap");
map.put("1", "2");
String value = map.get("3");
RSet<String> set = transaction.getSet("mySet")
set.add(value);

try {
   transaction.commit();
} catch(TransactionException e) {
   transaction.rollback();
}

For more information, read the Transactions section on the Redisson wiki.

Pipelining

In Redis, pipelining is a feature that allows you to send multiple commands to the server in a batch as a single atomic operation, helping to reduce execution times. Pipelining is supported in Redisson with the RBatch class:

RBatch batch = client.createBatch();
batch.getMap("ledgerMap").fastPutAsync("1", "2");
batch.getMap("ledgerMap").putAsync("2", "5");
List<?> result = batch.execute();

Publish/subscribe

As discussed above, Redisson can be used to implement the publish/subscribe pattern (“pub/sub”) using the RTopic interface.

Below is an example of how to listen for published messages in Redisson:

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

subscribeTopic is an RTopic instance that listens for messages from the “redisson” channel. The  addListener() method specifies how to handle incoming messages from that channel.

The following code demonstrates how to publish messages to a channel (possibly from another application or server):

RTopic publishTopic = client.getTopic("redisson");
long clientsReceivedMessage = publishTopic.publish(new CustomMessage("Hello world"));

Integration With Frameworks

Redisson is fully compatible with popular Java frameworks including:

  • Spring Cache
  • Hibernate Cache
  • JCache
  • Tomcat Session Manager
  • Spring Session
  • Spring PlatformTransactionManager
  • Spring Boot starters
  • More than 20 statistics monitoring solutions (JMX, NewRelic, etc.)

For more information about using Java frameworks with Redisson, consult the Integration with Frameworks page on the Redisson wiki.

Redis Cluster support

Redis Cluster enables Redis users to automatically shard data across multiple Redis nodes, improving the database’s scalability and availability. Thanks to the distributed nature of Redisson’s Java constructs, Redis Cluster is easily compatible with Redisson.

The example below illustrates the usage of Redisson with Redis Cluster:

package redis.demo;
import org.redisson.Redisson;
import org.redisson.api.RBucket;
import org.redisson.api.RedissonClient;

public class Application 
{
    public static void main( String[] args )
    {
        Config config = new Config();
        config.useClusterServers()
              .addNodeAddress("redis://127.0.0.1:6379", "redis://127.0.0.1:6380");
        RedissonClient redisson = Redisson.create(config);
        // operations with Redis based Lock
        // implements java.util.concurrent.locks.Lock
        RLock lock = redisson.getLock("simpleLock");
        lock.lock();
        try {
           // do some actions
        } finally {
           lock.unlock();
        }
        // operations with Redis based Map
        // implements java.util.concurrent.ConcurrentMap
        RMap<String, String> map = redisson.getMap("simpleMap");
        map.put("mapKey", "This is a map value");
        String mapValue = map.get("mapKey");
        System.out.println("stored map value: " + mapValue);
        redisson.shutdown();
    }
}

Redis Sentinel support

Redis Sentinel is a high-availability solution for Redis that manages and monitors your Redis deployment. As with Redis Cluster, Redisson includes support for Redis Sentinel. You must specify at least one Redis Sentinel server and a master name when using Redisson with Redis Sentinel.

The example below illustrates the usage of Redisson with Redis Sentinel:

package redis.demo;
import org.redisson.Redisson;
import org.redisson.api.RBucket;
import org.redisson.api.RedissonClient;
/**
 * Redis Sentinel Java example
 *
 */
public class Application 
{
    public static void main( String[] args )
    {
        Config config = new Config();
        config.useSentinelServers()
              .addSentinelAddress("redis://127.0.0.1:6379")
              .setMasterName("myMaster");
        RedissonClient redisson = Redisson.create(config);
        // perform operations
        // implements java.util.concurrent.ConcurrentMap
        RMap<String, String> map = redisson.getMap("simpleMap");
        map.put("mapKey", "This is a map value");
        String mapValue = map.get("mapKey");
        System.out.println("stored map value: " + mapValue);
        // implements java.util.concurrent.locks.Lock
        RLock lock = redisson.getLock("simpleLock");
        lock.lock();
        try {
           // do some actions
        } finally {
           lock.unlock();
        }
        redisson.shutdown();
    }
}

Azure Cache, Amazon ElastiCache, and Google Cloud Memorystore Support

Redisson supports three of the most popular options for fully managed Redis services in the cloud:

  • Azure Cache
  • Amazon ElastiCache
  • Google Cloud Memorystore

To learn more about using Redisson with these Redis cloud services, consult our pages on Azure Cache and AWS ElastiCache.

Redisson Vs. Jedis

Redisson isn’t the only Java client library for Redis. So how does Redisson compare with other Redis Java clients like Jedis?

For one, Redisson offers a much richer set of distributed collections than Jedis. The list of distributed collections in Redisson consists of:

  • Map
  • Multimap
  • Set
  • List
  • Queue
  • Deque
  • SortedSet
  • ScoredSortedSet
  • PriorityQueue
  • PriorityDeque
  • DelayedQueue
  • Stream
  • RingBuffer

Jedis, on the other hand, only supports the following distributed collections with plain commands:

  • Map
  • Multimap
  • Set
  • List
  • Queue
  • Deque
  • Stream
  • ScoredSortedSet

Distributed collections such as PriorityQueuesPriorityDequesDelayedQueuesStreams, and RingBuffers are not available in Jedis at all. In addition, Jedis does not support distributed locks and synchronizers such as LocksSemaphores, and CountDownLatches, or distributed services such as RemoteService and LiveObjectService.

Redisson also outperforms Jedis when it comes to features like advanced cache support, transactions, API architectures, and custom data serialization. To read a full comparison between Redisson and Jedis, check out our page Feature Comparison: Redisson vs. Jedis.

Further Reading

Distributed Java Collections in Redis With Redisson

Redis for Java Developers: Tutorials and Code Examples