A Guide to Redis with Redisson – 使用Redisson的Redis指南

最后修改: 2017年 3月 14日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

Redisson is a Redis client for Java. In this article, we’ll explore some of its features, and demonstrate how it could facilitate building distributed business applications.

Redisson是一个Java的Redis客户端。在这篇文章中,我们将探讨它的一些功能,并演示它如何促进构建分布式商业应用。

Redisson constitutes an in-memory data grid that offers distributed Java objects and services backed by Redis. Its distributed in-memory data model allows sharing of domain objects and services across applications and servers.

Redisson构成了一个内存数据网格,提供由Redis支持的分布式Java对象和服务。其分布式内存数据模型允许跨应用程序和服务器共享域对象和服务。

In this article we’ll see hot to setup Redisson, understand how it operates, and explore some of Redisson’s objects and services.

在这篇文章中,我们将看到设置Redisson的热度,了解它如何运作,并探索Redisson的一些对象和服务。

2. Maven Dependencies

2.Maven的依赖性

Let’s get started by importing Redisson to our project by adding the section below to our pom.xml:

让我们开始吧,将Redisson导入我们的项目,在pom.xml中加入以下部分:

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

The latest version of this dependency can be found here.

该依赖性的最新版本可以在这里找到。

3. Configuration

3.配置

Before we get started, we must ensure we have the latest version of Redis setup and running. If you don’t have Redis and you use Linux or Macintosh, you can follow the information here to get it setup. If you’re a Windows user, you can setup Redis using this unofficial port.

在我们开始之前,我们必须确保我们有最新版本的Redis的设置和运行。如果您没有 Redis,并且使用 Linux 或 Macintosh,您可以按照这里的信息来设置它。如果您是Windows用户,您可以使用这个非官方的端口设置Redis。

We need to configure Redisson to connect to Redis. Redisson supports connections to the following Redis configurations:

我们需要配置Redisson以连接到Redis。Redisson支持与下列Redis配置的连接。

  • Single node
  • Master with slave nodes
  • Sentinel nodes
  • Clustered nodes
  • Replicated nodes

Redisson supports Amazon Web Services (AWS) ElastiCache Cluster and Azure Redis Cache for Clustered and Replicated Nodes.

Redisson支持亚马逊网络服务(AWS)ElastiCache集群和Azure Redis Cache,用于集群和复制节点。

Let’s connect to a single node instance of Redis. This instance is running locally on the default port, 6379:

让我们连接到Redis的一个单节点实例。这个实例在本地运行,默认端口为6379。

RedissonClient client = Redisson.create();

You can pass different configurations to the Redisson object’s create method. This could be configurations to have it connect to a different port, or maybe, to connect to a Redis cluster. This configuration could be in Java code or loaded from an external configuration file.

你可以向Redisson对象的create方法传递不同的配置。这可以是让它连接到不同的端口的配置,或者是连接到 Redis 集群的配置。这种配置可以在Java代码中,也可以从外部配置文件中加载

3.1. Java Configuration

3.1. Java配置

Let’s configure Redisson in Java code:

让我们在Java代码中配置Redisson。

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

RedissonClient client = Redisson.create(config);

We specify Redisson configurations in an instance of a Config object and then pass it to the create method. Above, we specified to Redisson that we want to connect to a single node instance of Redis. To do this we used the Config object’s useSingleServer method. This returns a reference to a SingleServerConfig object.

我们Config对象的实例中指定Redisson的配置,然后将其传递给create方法。上面,我们向 Redisson 指定我们要连接到 Redis 的单节点实例。为了做到这一点,我们使用了Config对象的useSingleServer方法。这将返回一个指向SingleServerConfig对象的引用。

The SingleServerConfig object has settings that Redisson uses to connect to a single node instance of Redis. Here, we use its setAddress method to configure the address setting. This sets the address of the node we’re connecting to. Some other settings include retryAttempts, connectionTimeout and clientName. These settings are configured using their corresponding setter methods.

SingleServerConfig对象拥有 Redisson 用来连接到 Redis 单个节点实例的设置。在这里,我们使用其 setAddress 方法来配置 address 设置。这设置了我们要连接的节点的地址。其他一些设置包括retryAttemptsconnectionTimeoutclientName。这些设置是用它们相应的setter方法配置的。

We can configure Redisson for different Redis configurations in a similar way using the Config object’s following methods:

我们可以使用Config对象的以下方法,以类似方式为不同的Redis配置配置Redisson。

  • useSingleServer – for single node instance. Get single node settings here
  • useMasterSlaveServers – for master with slave nodes. Get master-slave node settings here
  • useSentinelServers – for sentinel nodes. Get sentinel node settings here
  • useClusterServers – for clustered nodes. Get clustered node settings here
  • useReplicatedServers – for replicated nodes. Get replicated node settings here

3.2. File Configuration

3.2.文件配置

Redisson can load configurations from external JSON or YAML files:

Redisson可以从外部JSON或YAML文件加载配置。

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

The Config object’s fromJSON method can load configurations from a string, file, input stream or URL.

Config对象的fromJSON方法可以从字符串、文件、输入流或URL加载配置。

Here is the sample configuration in the singleNodeConfig.json file:

这里是singleNodeConfig.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
}

Here is a corresponding YAML configuration file:

下面是一个相应的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: !<org.redisson.codec.JsonJacksonCodec> {}

We can configure other Redis configurations from a file in a similar manner using settings peculiar to that configuration. For your reference, here are their JSON and YAML file formats:

我们可以用类似的方式从文件中配置其他Redis配置,使用该配置特有的设置。供你参考,这里是它们的JSON和YAML文件格式。

To save a Java configuration to JSON or YAML format, we can use the toJSON or toYAML methods of the Config object:

要将Java配置保存为JSON或YAML格式,我们可以使用toJSONtoYAML对象的Config方法。

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

Now that we know how to configure Redisson, let’s look at how Redisson executes operations.

现在我们知道如何配置Redisson,让我们看看Redisson如何执行操作。

4. Operation

4.操作

Redisson supports synchronous, asynchronous and reactive interfaces. Operations over these interfaces are thread-safe.

Redisson支持同步、异步和反应式接口。对这些接口的操作是线程安全的

All entities (objects, collections, locks and services) generated by a RedissonClient have synchronous and asynchronous methods. Synchronous methods bear asynchronous variants. These methods normally bear the same method name of their synchronous variants appended with “Async”. Let’s look at a synchronous method of the RAtomicLong object:

RedissonClient生成的所有实体(对象、集合、锁和服务)都有同步和异步方法。同步方法带有异步变体。这些方法的名称通常与同步变体的方法名称相同,并附加 “Async”。让我们看看RAtomicLong对象的一个同步方法。

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

The asynchronous variant of the synchronous compareAndSet method would be:

同步compareAndSet方法的异步变量将是。

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

The asynchronous variant of the method returns an RFuture object. We can set listeners on this object to get back the result when it becomes available:

该方法的异步变量返回一个RFuture对象。我们可以在这个对象上设置监听器,以便在结果可用时取回它。

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

To generate reactive objects, we would need to use the RedissonReactiveClient:

为了生成反应式对象,我们将需要使用RedissonReactiveClient

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

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

This method returns reactive objects based on the Reactive Streams Standard for Java 9.

该方法基于反应式流标准为Java 9返回反应式对象。

Let’s explore some of the distributed objects provided by Redisson.

让我们来探索Redisson提供的一些分布式对象。

5. Objects

5.对象

An individual instance of a Redisson object is serialized and stored in any of the available Redis nodes backing Redisson. These objects could be distributed in a cluster across multiple nodes and can be accessed by a single application or multiple applications/servers.

Redisson对象的单个实例被序列化并存储在支持Redisson的任何可用Redis节点中。这些对象可以分布在多个节点的集群中,可以由一个应用程序或多个应用程序/服务器访问。

These distributed objects follow specifications from the java.util.concurrent.atomic package. They support lock-free, thread-safe and atomic operations on objects stored in Redis. Data consistency between applications/servers is ensured as values are not updated while another application is reading the object.

这些分布式对象遵循java.util.concurrent.atomic 包的规范。它们支持对存储在 Redis 中的对象进行无锁、线程安全和原子操作。应用程序/服务器之间的数据一致性得到了保证,因为当另一个应用程序正在读取该对象时,值不会被更新。

Redisson objects are bound to Redis keys. We can manage these keys through the RKeys interface. And then, we access our Redisson objects using these keys.

Redisson对象被绑定到Redis键。我们可以通过RKeys接口管理这些键。然后,我们使用这些键访问我们的Redisson对象。

There are several options we may use to get the Redis keys.

我们有几个选项可以用来获取Redis的密钥。

We can simple get all the keys:

我们可以简单地拿到所有的钥匙。

RKeys keys = client.getKeys();

Alternatively, we can extract only the names:

另外,我们可以只提取名字。

Iterable<String> allKeys = keys.getKeys();

And finally, we’re able to get the keys conforming to a pattern:

最后,我们能够得到符合模式的钥匙。

Iterable<String> keysByPattern = keys.getKeysByPattern('key*')

The RKeys interface also allows deleting keys, deleting keys by pattern and other useful key-based operations that we could use to manage our keys and objects.

RKeys接口还允许删除键,按模式删除键以及其他有用的基于键的操作,我们可以用它来管理我们的键和对象。

Distributed objects provided by Redisson include:

由Redisson提供的分布式对象包括。

  • ObjectHolder
  • BinaryStreamHolder
  • GeospatialHolder
  • BitSet
  • AtomicLong
  • AtomicDouble
  • Topic
  • BloomFilter
  • HyperLogLog

Let’s take a look at three of these objects: ObjectHolder, AtomicLong, and Topic.

让我们看一下其中的三个对象。ObjectHolder, AtomicLong,Topic.

5.1. Object Holder

5.1.物体支架

Represented by the RBucket class, this object can hold any type of object. This object has a maximum size of 512MB:

RBucket类代表,这个对象可以容纳任何类型的对象。这个对象的最大尺寸为512MB。

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

The RBucket object can perform atomic operations such as compareAndSet and getAndSet on objects it holds.

RBucket对象可以对其持有的对象执行原子操作,如compareAndSet和getAndSet

5.2. AtomicLong

5.2.AtomicLong

Represented by the RAtomicLong class, this object closely resembles the java.util.concurrent.atomic.AtomicLong class and represents a long value that can be updated atomically:

这个对象由RAtomicLong类表示,它与java.util.concurrent.atomic.AtomicLong类非常相似,表示一个可以被原子更新的long值。

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

5.3. Topic

5.3.题目

The Topic object supports the Redis’ “publish and subscribe” mechanism. To listen for published messages:

Topic对象支持Redis的 “发布和订阅 “机制。要监听发布的消息。

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

Above, the Topic is registered to listen to messages from the “baeldung” channel. We then add a listener to the topic to handle incoming messages from that channel. We can add multiple listeners to a channel.

上面,Topic被注册为监听来自 “baeldung “频道的消息。然后我们给主题添加一个监听器,以处理来自该通道的传入消息。我们可以为一个频道添加多个监听器。

Let’s publish messages to the “baeldung” channel:

让我们把信息发布到 “baeldung “频道。

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

This could be published from another application or server. The CustomMessage object will be received by the listener and processed as defined in the onMessage method.

这可以从另一个应用程序或服务器发布。CustomMessage对象将被监听器接收并按照onMessage方法中的定义进行处理。

We can learn more about other Redisson objects here.

我们可以了解更多关于其他Redisson对象的信息这里

6. Collections

6.收藏

We handle Redisson collections in the same fashion we handle objects.

我们以处理对象的方式处理Redisson集合。

Distributed collections provided by Redisson include:

由Redisson提供的分布式集合包括。

  • Map
  • Multimap
  • Set
  • SortedSet
  • ScoredSortedSet
  • LexSortedSet
  • List
  • Queue
  • Deque
  • BlockingQueue
  • BoundedBlockingQueue
  • BlockingDeque
  • BlockingFairQueue
  • DelayedQueue
  • PriorityQueue
  • PriorityDeque

Let’s take a look at three of these collections: Map, Set, and List.

让我们来看看这些集合中的三个。Map, Set,List.

6.1. Map

6.1.地图

Redisson based maps implement the java.util.concurrent.ConcurrentMap and java.util.Map interfaces. Redisson has four map implementations. These are RMap, RMapCache, RLocalCachedMap and RClusteredMap.

基于Redisson的地图实现了java.util.concurrent.ConcurrentMapjava.util.Map接口。Redisson 有四个地图实现。它们是RMapRMapCacheRLocalCachedMapRClusteredMap

Let’s create a map with Redisson:

让我们用Redisson创建一个地图。

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

RMapCache supports map entry eviction. RLocalCachedMap allows local caching of map entries. RClusteredMap allows data from a single map to be split across Redis cluster master nodes.

RMapCache支持地图条目驱逐。RLocalCachedMap允许对地图条目进行本地缓存。RClusteredMap允许单个地图的数据在Redis集群主节点之间分割。

We can learn more about Redisson maps here.

我们可以了解更多关于Redisson地图的信息这里

6.2. Set

6.2.设置

Redisson based Set implements the java.util.Set interface.

基于Redisson的Set实现了java.util.Set接口。

Redisson has three Set implementations, RSet, RSetCache, and RClusteredSet with similar functionality as their map counterparts.

Redisson有三个Set实现,RSetRSetCacheRClusteredSet,其功能与它们的对应地图类似。

Let’s create a Set with Redisson:

让我们用Redisson创建一个Set

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

We can learn more about Redisson sets here.

我们可以在这里了解更多关于Redisson套装的信息

6.3. List

6.3.清单

Redisson-based Lists implement the java.util.List interface.

基于Redisson的Lists实现java.util.List接口。

Let’s create a List with Redisson:

让我们用Redisson创建一个List

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

We can learn more about other Redisson collections here.

我们可以了解更多关于其他Redisson的收藏这里

7. Locks and Synchronizers

7.锁和同步器

Redisson’s distributed locks allow for thread synchronization across applications/servers. Redisson’s list of locks and synchronizers include:

Redisson的分布式锁允许跨应用程序/服务器进行线程同步。Redisson的锁和同步器列表包括。

  • Lock
  • FairLock
  • MultiLock
  • ReadWriteLock
  • Semaphore
  • PermitExpirableSemaphore
  • CountDownLatch

Let’s take a look at Lock and MultiLock.

我们来看看LockMultiLock.

7.1. Lock

7.1.锁定

Redisson’s Lock implements java.util.concurrent.locks.Lock interface.

Redisson的Lock实现了java.util.concurrent.locks.Lockinterface。

Let’s implement a lock, represented by the RLock class:

让我们来实现一个锁,由RLock类代表。

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

7.2. MultiLock

7.2.多重锁定

Redisson’s RedissonMultiLock groups multiple RLock objects and treats them as a single lock:

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

We can learn more about other locks here.

我们可以在这里了解更多关于其他锁具的信息

8. Services

8.服务

Redisson exposes 4 types of distributed services. These are: Remote Service, Live Object Service, Executor Service and Scheduled Executor Service. Let’s look at the Remote Service and Live Object Service.

Redisson暴露了4种类型的分布式服务。这些服务是。远程服务实时对象服务执行器服务预定执行器服务。让我们看一下远程服务和实时对象服务。

8.1. Remote Service

8.1.远程服务

This service provides Java remote method invocation facilitated by Redis. A Redisson remote service consists of a server-side (worker instance) and client-side implementation. The server-side implementation executes a remote method invoked by the client. Calls from a remote service can be synchronous or asynchronous.

该服务提供由Redis促进的Java远程方法调用。Redisson远程服务由服务器端(工作者实例)和客户端的实现组成。服务器端的实现执行由客户端调用的远程方法。远程服务的调用可以是同步或异步的。

The server-side registers an interface for remote invocation:

服务器端注册了一个用于远程调用的接口。

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

remoteService.register(LedgerServiceInterface.class, ledgerServiceImpl);

The client-side calls a method of the registered remote interface:

客户端调用注册的远程接口的一个方法。

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

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

We can learn more about remote services here.

我们可以了解更多关于远程服务的信息这里

8.2. Live Object Service

8.2.实时对象服务

Redisson Live Objects extend the concept of standard Java objects that could only be accessed from a single JVM to enhanced Java objects that could be shared between different JVMs in different machines. This is accomplished by mapping an object’s fields to a Redis hash. This mapping is made through a runtime-constructed proxy class. Field getters and setters are mapped to Redis hget/hset commands.

Redisson Live Objects将只能从单个JVM访问的标准Java对象的概念扩展为可在不同机器的不同JVM之间共享的增强型Java对象。这是通过将一个对象的字段映射到Redis哈希上实现的。这种映射是通过运行时构建的代理类进行的。字段的获取器和设置器被映射到Redis的hget/hset命令。

Redisson Live Objects support atomic field access as a result of Redis’ single-threaded nature.

由于Redis的单线程特性,Redisson Live Objects支持原子字段访问。

Creating a Live Object is simple:

创建一个真实对象很简单。

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

    // getters and setters...
}

We annotate our class with @REntity and a unique or identifying field with @RId. Once we have done this, we can use our Live Object in our application:

我们用@REntity注解我们的类,用@RId注解一个独特的或可识别的字段。一旦我们完成了这些,我们就可以在我们的应用程序中使用我们的Live对象。

RLiveObjectService service = client.getLiveObjectService();

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

ledger = service.persist(ledger);

We create our Live Object like standard Java objects using the new keyword. We then use an instance of RLiveObjectService to save the object to Redis using its persist method.

我们使用new关键字像标准Java对象一样创建我们的Live对象。然后我们使用RLiveObjectService的一个实例,使用其persist方法将该对象保存到Redis。

If the object has previously been persisted to Redis, we can retrieve the object:

如果该对象之前已经被持久化到Redis,我们可以检索该对象。

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

We use the RLiveObjectService to get our Live Object using the field annotated with @RId.

我们使用RLiveObjectService来获取我们的实时对象,使用@RId注释的字段。

Here we can find more about Redisson Live Objects, and other Redisson services are described here.

在这里我们可以找到更多关于Redisson Live Objects的信息,而其他Redisson服务的描述在这里。

9. Pipelining

9.流水线

Redisson supports pipelining. Multiple operations can be batched as a single atomic operation. This is facilitated by the RBatch class. Multiple commands are aggregated against an RBatch object instance before they are executed:

Redisson支持流水作业。多个操作可以作为一个单一的原子操作进行批处理。这是由RBatch类促成的。在执行之前,多个命令被聚集到一个RBatch对象实例上。

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

BatchResult<?> batchResult = batch.execute();

10. Scripting

10.脚本

Redisson supports LUA scripting. We can execute LUA scripts against Redis:

Redisson支持LUA脚本。我们可以针对Redis执行LUA脚本

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

11. Low-Level Client

11.低级别的客户

It’s possible that we might want to perform Redis operations not yet supported by Redisson. Redisson provides a low-level client that allows execution of native Redis commands:

我们有可能想要执行Redisson尚不支持的Redis操作。Redisson 提供了一个低级别的客户端,允许执行本地 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();

The low-level client also supports asynchronous operations.

低级别的客户端也支持异步操作。

12. Conclusion

12 结论

This article showcased Redisson and some of the features that make it ideal for developing distributed applications. We explored its distributed objects, collections, locks and services. We also explored some of its other features such as pipelining, scripting and its low-level client.

这篇文章展示了Redisson和一些使其成为开发分布式应用理想的功能。我们探讨了它的分布式对象、集合、锁和服务。我们还探讨了它的一些其他特性,如流水线、脚本和它的低级客户端。

Redisson also provides integration with other frameworks such as the JCache API, Spring Cache, Hibernate Cache and Spring Sessions. We can learn more about its integration with other frameworks here.

Redisson还提供与其他框架的集成,如JCache API、Spring Cache、Hibernate Cache和Spring Sessions。我们可以了解其与其他框架集成的更多信息这里

You can find code samples in the GitHub project.

你可以在GitHub项目中找到代码样本。