Почему Редиссон?
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:
useMasterSlaveServers()
: Мастер с подчиненными узламиuseSentinelServers()
: Часовые узлыuseClusterServers()
: Кластерные узлы, включая поддержку AWS ElastiCache Cluster и Azure Redis Cache .- useReplicatedServers (): реплицированные узлы, включая поддержку AWS ElastiCache и Azure Redis Cache .
Настройка 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 являются атомарными: либо все команды в транзакции обрабатываются, либо ни одна из них не выполняется. MULTI
, EXEC
, DISCARD
, И WATCH
являются четыре команды , которые являются основой Redis сделок. Команда MULTI
допускает несколько команд в транзакции, в то время как EXEC
команда выполняет все команды в транзакции.
Redisson поддерживает выполнение транзакций с уровнем изоляции, READ_COMMITTED
используя блокировки во время операций записи. Объекты , которые имеют право на сделки в Redisson включают RMap
, RMapCache
, RLocalCachedMap
, RSet
, RSetCache
, и 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 PriorityQueues
, PriorityDeques
, DelayedQueues
, Streams
, and RingBuffers
are not available in Jedis at all. In addition, Jedis does not support distributed locks and synchronizers such as Locks
, Semaphores
, 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.