组件整合之Redisson

Redisson简介

Redisson是一个在Redis的基础上实现的Java驻内存数据网格(In-Memory Data Grid)。它不仅提供了一系列的分布式的Java常用对象,还提供了许多分布式服务。其中包括(BitSet, Set, Multimap, SortedSet, Map, List, Queue, BlockingQueue, Deque, BlockingDeque, Semaphore, Lock, AtomicLong, CountDownLatch, Publish / Subscribe, Bloom filter, Remote service, Spring cache, Executor service, Live Object service, Scheduler service) Redisson提供了使用Redis的最简单和最便捷的方法。Redisson的宗旨是促进使用者对Redis的关注分离(Separation of Concern),从而让使用者能够将精力更集中地放在处理业务逻辑上

快速入门

pom配置

<!--redisson-->
<dependency>
    <groupId>org.redisson</groupId>
    <artifactId>redisson</artifactId>
    <version>3.15.0</version>
</dependency>

Redission配置

程序化配置

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.MapperFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.codec.JsonJacksonCodec;
import org.redisson.config.Config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;

@Configuration
public class RedissonConfig {

    private static final String DEFAULT_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";


    /**
     * 单机模式自动装配
     * @return
     */
    @Bean
    public RedissonClient redissonSingle(){
        Config config = new Config();
        config.useSingleServer()
                .setAddress("redis://localhost:6379")
                .setConnectionMinimumIdleSize(10);
        config.setCodec(new JsonJacksonCodec(objectMapper()));
        RedissonClient redissonClient = Redisson.create(config);
        return redissonClient;
    }

    /**
     * 主从模式
     * @return
     */
    @Bean
    public RedissonClient masterSlave(){
        Config config = new Config();
        config.useMasterSlaveServers()
                //可以用"rediss://"来启用SSL连接
                .setMasterAddress("redis://127.0.0.1:6379")
                .addSlaveAddress("redis://127.0.0.1:6389", "redis://127.0.0.1:6332", "redis://127.0.0.1:6419")
                .addSlaveAddress("redis://127.0.0.1:6399");
        return Redisson.create(config);
    }

    /**
     * 哨兵模式自动装配
     * @return
     */
    @Bean
    public RedissonClient redissonSentinel(){
        Config config = new Config();
        List<String> newNodes = new ArrayList();
        newNodes.add("redis://192.168.1.10:6379");
        newNodes.add("redis://192.168.1.11:16379");
        newNodes.add("redis://192.168.1.12:16379");
        config.useSentinelServers()
                .addSentinelAddress(newNodes.toArray(new String[0]))
                .setMasterName("mymaster")
                .setMasterConnectionPoolSize(250)
                .setMasterConnectionMinimumIdleSize(20)
                .setSlaveConnectionPoolSize(250)
                .setSlaveConnectionMinimumIdleSize(20);
        config.setCodec(new JsonJacksonCodec(objectMapper()));
        return Redisson.create(config);
    }

    /**
     * 集群模式自动装配
     * @return
     */
    @Bean
    public RedissonClient redissionClusterNodes(){
        Config config = new Config();
        List<String> newNodes = new ArrayList();
        newNodes.add("redis://127.0.0.1:6380");
        newNodes.add("redis://127.0.0.1:6381");
        newNodes.add("redis://127.0.0.1:6382");
        config.useClusterServers()
                .addNodeAddress(newNodes.toArray(new String[0]));
        config.setCodec(new JsonJacksonCodec(objectMapper()));
        return Redisson.create(config);
    }

    public ObjectMapper objectMapper() {
        ObjectMapper mapper = new ObjectMapper();
        //大小写不敏感
        mapper.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true);
        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        mapper.setDateFormat(new SimpleDateFormat(DEFAULT_DATE_TIME_FORMAT));
        JavaTimeModule javaTimeModule = new JavaTimeModule();
        javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT)));
        javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT)));
        mapper.registerModule(javaTimeModule);
        return mapper;
    }
}

文件方式配置

 Redisson也可以通过用户提供的JSON或YAML格式的文本文件来配置:

(1)可以通过调用Config.fromJSON方法并指定一个File实例来实现读取JSON格式的配置

Config config = Config.fromJSON(new File("config-file.json"));
RedissonClient redisson = Redisson.create(config);

config-file.json示例:

{
   "clusterServersConfig":{
      "idleConnectionTimeout":10000,
      "pingTimeout":1000,
      "connectTimeout":10000,
      "timeout":3000,
      "retryAttempts":3,
      "retryInterval":1500,
      "reconnectionTimeout":3000,
      "failedAttempts":3,
      "password":null,
      "subscriptionsPerConnection":5,
      "clientName":null,
      "loadBalancer":{
         "class":"org.redisson.connection.balancer.RoundRobinLoadBalancer"
      },
      "slaveSubscriptionConnectionMinimumIdleSize":1,
      "slaveSubscriptionConnectionPoolSize":50,
      "slaveConnectionMinimumIdleSize":32,
      "slaveConnectionPoolSize":64,
      "masterConnectionMinimumIdleSize":32,
      "masterConnectionPoolSize":64,
      "readMode":"SLAVE",
      "nodeAddresses":[
         "redis://127.0.0.1:7004",
         "redis://127.0.0.1:7001",
         "redis://127.0.0.1:7000"
      ],
      "scanInterval":1000
   },
   "threads":0,
   "nettyThreads": 0,
   "codec":{
      "class":"org.redisson.codec.JsonJacksonCodec"
   },
   "transportMode":"NIO"
}

(2)通过调用config.fromYAML方法并指定一个File实例来实现读取YAML格式的配置

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

config-file.yaml示例:

singleServerConfig:
  #连接空闲超时,单位:毫秒
  idleConnectionTimeout: 10000
  pingTimeout: 1000
  #连接超时,单位:毫秒
  connectTimeout: 10000
  #命令等待超时,单位:毫秒
  timeout: 3000
  #命令失败重试次数
  retryAttempts: 3
  #命令重试发送时间间隔,单位:毫秒
  retryInterval: 1500
  #重新连接时间间隔,单位:毫秒
  reconnectionTimeout: 3000
  #执行失败最大次数
  failedAttempts: 3
  #单个连接最大订阅数量
  subscriptionsPerConnection: 5
  #客户端名称
  clientName: null
  #地址
  address: "redis://192.168.1.16:6379"
  #数据库编号
  database: 0
  #密码
  password: xiaokong
  #发布和订阅连接的最小空闲连接数
  subscriptionConnectionMinimumIdleSize: 1 
  #发布和订阅连接池大小
  subscriptionConnectionPoolSize: 50
  #最小空闲连接数
  connectionMinimumIdleSize: 32
  #连接池大小
  connectionPoolSize: 64
  #是否启用DNS监测
  dnsMonitoring: false
  #DNS监测时间间隔,单位:毫秒
  dnsMonitoringInterval: 5000
threads: 0
nettyThreads: 0
codec: !<org.redisson.codec.JsonJacksonCodec> {}
transportMode : "NIO"

Config类

Redisson程序化的配置方法是通过构建Config对象实例来实现的。

以下是org.redisson.Config类的配置参数,它适用于所有Redis组态模式(单机,集群和哨兵)。

codec(编码)

默认值是:org.redisson.codec.JsonJacksonCodec

Redisson的对象编码类是用于将对象进行序列化和反序列化,以实现对该对象在Redis里的读取和存储。Redisson提供了以下几种的对象编码应用,以供大家选择:

编码类名称 说明
org.redisson.codec.JsonJacksonCodec Jackson JSON 编码 默认编码
org.redisson.codec.KryoCodec Kryo 二进制对象序列化编码
org.redisson.codec.SerializationCodec JDK序列化编码
org.redisson.codec.FstCodec FST 10倍于JDK序列化性能而且100%兼容的编码
org.redisson.client.codec.JsonJacksonMapCodec 基于Jackson的映射类使用的编码。可用于避免序列化类的信息,以及用于解决使用byte[]遇到的问题。
org.redisson.client.codec.ByteArrayCodec 字节数组编码
org.redisson.codec.CompositeCodec 用来组合多种不同编码在一起

属性配置

属性名 属性简介 默认值 详细说明
threads  线程池数量 当前处理核数量 * 2  这个线程池数量被所有RTopic对象监听器,RRemoteService调用者和RExecutorService任务共同共享。 
nettyThreads  Netty线程池数量  当前处理核数量 * 2  

这个线程池数量是在一个Redisson实例内,被其创建的所有分布式数据类型和服务,以及底层客户端所一同共享的线程池里保存的线程数量。 

executor  线程池    单独提供一个用来执行所有RTopic对象监听器,RRemoteService调用者和RExecutorService任务的线程池(ExecutorService)实例。 
eventLoopGroup     

用于特别指定一个EventLoopGroup. EventLoopGroup是用来处理所有通过Netty与Redis服务之间的连接发送和接受的消息。

每一个Redisson都会在默认情况下自己创建管理一个EventLoopGroup实例。

因此,如果在同一个JVM里面可能存在多个Redisson实例的情况下,采取这个配置实现多个Redisson实例共享一个EventLoopGroup的目的。

只有io.netty.channel.epoll.EpollEventLoopGroup或io.netty.channel.nio.NioEventLoopGroup才是允许的类型。

 
transportMode  传输模式  TransportMode.NIO 

可选参数:
TransportMode.NIO
TransportMode.EPOLL - 需要依赖里有netty-transport-native-epoll包(Linux)
TransportMode.KQUEUE - 需要依赖里有 netty-transport-native-kqueue包(macOS)

 
lockWatchdogTimeout 

监控锁的看门狗超时。单位:毫秒

 
30000 

监控锁的看门狗超时时间单位为毫秒。该参数只适用于分布式锁的加锁请求中未明确使用leaseTimeout参数的情况。

如果该看门口未使用lockWatchdogTimeout去重新调整一个分布式锁的lockWatchdogTimeout超时,那么这个锁将变为失效状态。

这个参数可以用来避免由Redisson客户端节点宕机或其他原因造成死锁的情况。 

keepPubSubOrder  保持订阅发布顺序  true  通过该参数来修改是否按订阅发布消息的接收顺序出来消息,如果选否将对消息实行并行处理,该参数只适用于订阅发布消息的情况。 
performanceMode  高性能模式 

HIGHER_THROUGHPUT

 

用来指定高性能引擎的行为。由于该变量值的选用与使用场景息息相关(NORMAL除外)我们建议对每个参数值都进行尝试。

该参数仅限于Redisson PRO版本。

可选模式:

HIGHER_THROUGHPUT - 将高性能引擎切换到 高通量 模式。

LOWER_LATENCY_AUTO - 将高性能引擎切换到 低延时 模式并自动探测最佳设定。

LOWER_LATENCY_MODE_1 - 将高性能引擎切换到 低延时 模式并调整到预设模式1。 LOWER_LATENCY_MODE_2 - 将高性能引擎切换到 低延时 模式并调整到预设模式2。

NORMAL - 将高性能引擎切换到 普通 模式

ClusterServersConfig类

ClusterServersConfig clusterConfig = config.useClusterServers();

nodeAddresses(添加节点地址)
可以通过host:port的格式来添加Redis集群节点的地址。多个节点可以一次性批量添加。

scanInterval(集群扫描间隔时间)
默认值: 1000,对Redis集群节点状态扫描的时间间隔。单位是毫秒。

slots(分片数量)
默认值: 231用于指定数据分片过程中的分片数量。支持数据分片/框架结构有:集(Set)、映射(Map)、BitSet、Bloom filter, Spring Cache和Hibernate Cache等.

readMode(读取操作的负载均衡模式)
默认值: SLAVE(只在从服务节点里读取)注:在从服务节点里读取的数据说明已经至少有两个节点保存了该数据,确保了数据的高可用性。设置读取操作选择节点的模式。可用值为:SLAVE - 只在从服务节点里读取。MASTER - 只在主服务节点里读取。MASTER_SLAVE - 在主从服务节点里都可以读取。

subscriptionMode(订阅操作的负载均衡模式)
默认值:SLAVE(只在从服务节点里订阅),设置订阅操作选择节点的模式。可用值为:SLAVE - 只在从服务节点里订阅。MASTER - 只在主服务节点里订阅。

loadBalancer(负载均衡算法类的选择)
默认值: org.redisson.connection.balancer.RoundRobinLoadBalancer

在多Redis服务节点的环境里,可以选用以下几种负载均衡方式选择一个节点:org.redisson.connection.balancer.WeightedRoundRobinBalancer - 权重轮询调度算法org.redisson.connection.balancer.RoundRobinLoadBalancer - 轮询调度算法org.redisson.connection.balancer.RandomLoadBalancer - 随机调度算法

subscriptionConnectionMinimumIdleSize(从节点发布和订阅连接的最小空闲连接数)
默认值:1。多从节点的环境里,每个 从服务节点里用于发布和订阅连接的最小保持连接数(长连接)。Redisson内部经常通过发布和订阅来实现许多功能。长期保持一定数量的发布订阅连接是必须的。

subscriptionConnectionPoolSize(从节点发布和订阅连接池大小)
默认值:50。多从节点的环境里,每个 从服务节点里用于发布和订阅连接的连接池最大容量。连接池的连接数量自动弹性伸缩。

slaveConnectionMinimumIdleSize(从节点最小空闲连接数)
默认值:32。多从节点的环境里,每个 从服务节点里用于普通操作(非 发布和订阅)的最小保持连接数(长连接)。长期保持一定数量的连接有利于提高瞬时读取反映速度。

slaveConnectionPoolSize(从节点连接池大小)
默认值:64。多从节点的环境里,每个 从服务节点里用于普通操作(非 发布和订阅)连接的连接池最大容量。连接池的连接数量自动弹性伸缩。

masterConnectionMinimumIdleSize(主节点最小空闲连接数)
默认值:32。多节点的环境里,每个 主节点的最小保持连接数(长连接)。长期保持一定数量的连接有利于提高瞬时写入反应速度。

masterConnectionPoolSize(主节点连接池大小)
默认值:64。多主节点的环境里,每个 主节点的连接池最大容量。连接池的连接数量自动弹性伸缩。

idleConnectionTimeout(连接空闲超时,单位:毫秒)
默认值:10000。如果当前连接池里的连接数量超过了最小空闲连接数,而同时有连接空闲时间超过了该数值,那么这些连接将会自动被关闭,并从连接池里去掉。时间单位是毫秒。

connectTimeout(连接超时,单位:毫秒)
默认值:10000。同任何节点建立连接时的等待超时。时间单位是毫秒。

timeout(命令等待超时,单位:毫秒)
默认值:3000。等待节点回复命令的时间。该时间从命令发送成功时开始计时。

retryAttempts(命令失败重试次数)
默认值:3。如果尝试达到 retryAttempts(命令失败重试次数) 仍然不能将命令发送至某个指定的节点时,将抛出错误。如果尝试在此限制之内发送成功,则开始启用 timeout(命令等待超时) 计时。

retryInterval(命令重试发送时间间隔,单位:毫秒)
默认值:1500。在一条命令发送失败以后,等待重试发送的时间间隔。时间单位是毫秒。

reconnectionTimeout(重新连接时间间隔,单位:毫秒)
默认值:3000。当与某个节点的连接断开时,等待与其重新建立连接的时间间隔。时间单位是毫秒。

failedAttempts(执行失败最大次数)
默认值:3。在某个节点执行相同或不同命令时,连续 失败 failedAttempts(执行失败最大次数) 时,该节点将被从可用节点列表里清除,直到 reconnectionTimeout(重新连接时间间隔) 超时以后再次尝试。

password(密码)
默认值:null。用于节点身份验证的密码。

subscriptionsPerConnection(单个连接最大订阅数量)
默认值:5。每个连接的最大订阅数量。

clientName(客户端名称)
默认值:null。在Redis节点里显示的客户端名称。

sslEnableEndpointIdentification(启用SSL终端识别)
默认值:true。开启SSL终端识别能力。

sslProvider(SSL实现方式)
默认值:JDK。确定采用哪种方式(JDK或OPENSSL)来实现SSL连接。

sslTruststore(SSL信任证书库路径)
默认值:null。指定SSL信任证书库的路径。

sslTruststorePassword(SSL信任证书库密码)
默认值:null。指定SSL信任证书库的密码。

sslKeystore(SSL钥匙库路径)
默认值:null。指定SSL钥匙库的路径。

sslKeystorePassword(SSL钥匙库密码)
默认值:null。指定SSL钥匙库的密码。

SingleServerConfig类

SingleServerConfig singleConfig = config.useSingleServer();

address(节点地址)
可以通过host:port的格式来指定节点地址。

subscriptionConnectionMinimumIdleSize(发布和订阅连接的最小空闲连接数)
默认值:1。用于发布和订阅连接的最小保持连接数(长连接)。Redisson内部经常通过发布和订阅来实现许多功能。长期保持一定数量的发布订阅连接是必须的。

subscriptionConnectionPoolSize(发布和订阅连接池大小)
默认值:50。用于发布和订阅连接的连接池最大容量。连接池的连接数量自动弹性伸缩。

connectionMinimumIdleSize(最小空闲连接数)
默认值:32。最小保持连接数(长连接)。长期保持一定数量的连接有利于提高瞬时写入反应速度。

connectionPoolSize(连接池大小)
默认值:64。连接池最大容量。连接池的连接数量自动弹性伸缩。

dnsMonitoring(是否启用DNS监测)
默认值:false。在启用该功能以后,Redisson将会监测DNS的变化情况。

dnsMonitoringInterval(DNS监测时间间隔,单位:毫秒)
默认值:5000。监测DNS的变化情况的时间间隔。

idleConnectionTimeout(连接空闲超时,单位:毫秒)
默认值:10000。如果当前连接池里的连接数量超过了最小空闲连接数,而同时有连接空闲时间超过了该数值,那么这些连接将会自动被关闭,并从连接池里去掉。时间单位是毫秒。

connectTimeout(连接超时,单位:毫秒)
默认值:10000。同节点建立连接时的等待超时。时间单位是毫秒。

timeout(命令等待超时,单位:毫秒)
默认值:3000。等待节点回复命令的时间。该时间从命令发送成功时开始计时。

retryAttempts(命令失败重试次数)
默认值:3。如果尝试达到 retryAttempts(命令失败重试次数) 仍然不能将命令发送至某个指定的节点时,将抛出错误。如果尝试在此限制之内发送成功,则开始启用 timeout(命令等待超时) 计时。

retryInterval(命令重试发送时间间隔,单位:毫秒)
默认值:1500。在一条命令发送失败以后,等待重试发送的时间间隔。时间单位是毫秒。

reconnectionTimeout(重新连接时间间隔,单位:毫秒)
默认值:3000。当与某个节点的连接断开时,等待与其重新建立连接的时间间隔。时间单位是毫秒。

failedAttempts(执行失败最大次数)
默认值:3。在某个节点执行相同或不同命令时,连续 失败 failedAttempts(执行失败最大次数) 时,该节点将被从可用节点列表里清除,直到 reconnectionTimeout(重新连接时间间隔) 超时以后再次尝试。

database(数据库编号)
默认值:0。尝试连接的数据库编号。

password(密码)
默认值:null。用于节点身份验证的密码。

subscriptionsPerConnection(单个连接最大订阅数量)
默认值:5。每个连接的最大订阅数量。

clientName(客户端名称)
默认值:null。在Redis节点里显示的客户端名称。

sslEnableEndpointIdentification(启用SSL终端识别)
默认值:true。开启SSL终端识别能力。

sslProvider(SSL实现方式)
默认值:JDK。确定采用哪种方式(JDK或OPENSSL)来实现SSL连接。

sslTruststore(SSL信任证书库路径)
默认值:null。指定SSL信任证书库的路径。

sslTruststorePassword(SSL信任证书库密码)
默认值:null。指定SSL信任证书库的密码。

sslKeystore(SSL钥匙库路径)
默认值:null。指定SSL钥匙库的路径。

sslKeystorePassword(SSL钥匙库密码)
默认值:null。指定SSL钥匙库的密码。

SentinelServersConfig类

SentinelServersConfig sentinelConfig = config.useSentinelServers();

dnsMonitoringInterval(DNS监控间隔,单位:毫秒)
默认值:5000。用来指定检查节点DNS变化的时间间隔。使用的时候应该确保JVM里的DNS数据的缓存时间保持在足够低的范围才有意义。用-1来禁用该功能。

masterName(主服务器的名称)
主服务器的名称是哨兵进程中用来监测主从服务切换情况的。

addSentinelAddress(添加哨兵节点地址)
可以通过host:port的格式来指定哨兵节点的地址。多个节点可以一次性批量添加。

readMode(读取操作的负载均衡模式)
默认值: SLAVE(只在从服务节点里读取)注:在从服务节点里读取的数据说明已经至少有两个节点保存了该数据,确保了数据的高可用性。

设置读取操作选择节点的模式。可用值为:SLAVE - 只在从服务节点里读取。MASTER - 只在主服务节点里读取。MASTER_SLAVE - 在主从服务节点里都可以读取。

subscriptionMode(订阅操作的负载均衡模式)
默认值:SLAVE(只在从服务节点里订阅)。设置订阅操作选择节点的模式。可用值为:SLAVE - 只在从服务节点里订阅。MASTER - 只在主服务节点里订阅。

loadBalancer(负载均衡算法类的选择)
默认值: org.redisson.connection.balancer.RoundRobinLoadBalancer

在使用多个Redis服务节点的环境里,可以选用以下几种负载均衡方式选择一个节点:org.redisson.connection.balancer.WeightedRoundRobinBalancer - 权重轮询调度算法org.redisson.connection.balancer.RoundRobinLoadBalancer - 轮询调度算法org.redisson.connection.balancer.RandomLoadBalancer - 随机调度算法

subscriptionConnectionMinimumIdleSize(从节点发布和订阅连接的最小空闲连接数)
默认值:1。多从节点的环境里,每个 从服务节点里用于发布和订阅连接的最小保持连接数(长连接)。Redisson内部经常通过发布和订阅来实现许多功能。长期保持一定数量的发布订阅连接是必须的。

subscriptionConnectionPoolSize(从节点发布和订阅连接池大小)
默认值:50。多从节点的环境里,每个 从服务节点里用于发布和订阅连接的连接池最大容量。连接池的连接数量自动弹性伸缩。

slaveConnectionMinimumIdleSize(从节点最小空闲连接数)
默认值:32。多从节点的环境里,每个 从服务节点里用于普通操作(非 发布和订阅)的最小保持连接数(长连接)。长期保持一定数量的连接有利于提高瞬时读取反映速度。

slaveConnectionPoolSize(从节点连接池大小)
默认值:64。多从节点的环境里,每个 从服务节点里用于普通操作(非 发布和订阅)连接的连接池最大容量。连接池的连接数量自动弹性伸缩。

masterConnectionMinimumIdleSize(主节点最小空闲连接数)
默认值:32。多从节点的环境里,每个 主节点的最小保持连接数(长连接)。长期保持一定数量的连接有利于提高瞬时写入反应速度。

masterConnectionPoolSize(主节点连接池大小)
默认值:64。主节点的连接池最大容量。连接池的连接数量自动弹性伸缩。

idleConnectionTimeout(连接空闲超时,单位:毫秒)
默认值:10000。如果当前连接池里的连接数量超过了最小空闲连接数,而同时有连接空闲时间超过了该数值,那么这些连接将会自动被关闭,并从连接池里去掉。时间单位是毫秒。

connectTimeout(连接超时,单位:毫秒)
默认值:10000。同任何节点建立连接时的等待超时。时间单位是毫秒。

timeout(命令等待超时,单位:毫秒)
默认值:3000。等待节点回复命令的时间。该时间从命令发送成功时开始计时。

retryAttempts(命令失败重试次数)
默认值:3。如果尝试达到 retryAttempts(命令失败重试次数) 仍然不能将命令发送至某个指定的节点时,将抛出错误。如果尝试在此限制之内发送成功,则开始启用 timeout(命令等待超时) 计时。

retryInterval(命令重试发送时间间隔,单位:毫秒)
默认值:1500。在一条命令发送失败以后,等待重试发送的时间间隔。时间单位是毫秒。

reconnectionTimeout(重新连接时间间隔,单位:毫秒)
默认值:3000。当与某个节点的连接断开时,等待与其重新建立连接的时间间隔。时间单位是毫秒。

failedAttempts(执行失败最大次数)
默认值:3。在某个节点执行相同或不同命令时,连续 失败 failedAttempts(执行失败最大次数) 时,该节点将被从可用节点列表里清除,直到 reconnectionTimeout(重新连接时间间隔) 超时以后再次尝试。

database(数据库编号)
默认值:0。尝试连接的数据库编号。

password(密码)
默认值:null。用于节点身份验证的密码。

subscriptionsPerConnection(单个连接最大订阅数量)
默认值:5。每个连接的最大订阅数量。

clientName(客户端名称)
默认值:null。在Redis节点里显示的客户端名称。

sslEnableEndpointIdentification(启用SSL终端识别)
默认值:true。开启SSL终端识别能力。

sslProvider(SSL实现方式)
默认值:JDK。确定采用哪种方式(JDK或OPENSSL)来实现SSL连接。

sslTruststore(SSL信任证书库路径)
默认值:null。指定SSL信任证书库的路径。

sslTruststorePassword(SSL信任证书库密码)
默认值:null。指定SSL信任证书库的密码。

sslKeystore(SSL钥匙库路径)
默认值:null。指定SSL钥匙库的路径。

sslKeystorePassword(SSL钥匙库密码)
默认值:null。指定SSL钥匙库的密码。

MasterSlaveServersConfig类

MasterSlaveServersConfig masterSlaveConfig = config.useMasterSlaveServers();

dnsMonitoringInterval(DNS监控间隔,单位:毫秒)
默认值:5000。用来指定检查节点DNS变化的时间间隔。使用的时候应该确保JVM里的DNS数据的缓存时间保持在足够低的范围才有意义。用-1来禁用该功能。

masterAddress(主节点地址)
可以通过host:port的格式来指定主节点地址。

addSlaveAddress(添加从主节点地址)
可以通过host:port的格式来指定从节点的地址。多个节点可以一次性批量添加。

readMode(读取操作的负载均衡模式)
默认值: SLAVE(只在从服务节点里读取)。注:在从服务节点里读取的数据说明已经至少有两个节点保存了该数据,确保了数据的高可用性。

设置读取操作选择节点的模式。可用值为:SLAVE - 只在从服务节点里读取。MASTER - 只在主服务节点里读取。MASTER_SLAVE - 在主从服务节点里都可以读取。

subscriptionMode(订阅操作的负载均衡模式)
默认值:SLAVE(只在从服务节点里订阅)。设置订阅操作选择节点的模式。可用值为:SLAVE - 只在从服务节点里订阅。MASTER - 只在主服务节点里订阅。

loadBalancer(负载均衡算法类的选择)
默认值: org.redisson.connection.balancer.RoundRobinLoadBalancer

在使用多个Redis服务节点的环境里,可以选用以下几种负载均衡方式选择一个节点:org.redisson.connection.balancer.WeightedRoundRobinBalancer - 权重轮询调度算法org.redisson.connection.balancer.RoundRobinLoadBalancer - 轮询调度算法org.redisson.connection.balancer.RandomLoadBalancer - 随机调度算法

subscriptionConnectionMinimumIdleSize(从节点发布和订阅连接的最小空闲连接数)
默认值:1。多从节点的环境里,每个 从服务节点里用于发布和订阅连接的最小保持连接数(长连接)。Redisson内部经常通过发布和订阅来实现许多功能。长期保持一定数量的发布订阅连接是必须的。

subscriptionConnectionPoolSize(从节点发布和订阅连接池大小)
默认值:50。多从节点的环境里,每个 从服务节点里用于发布和订阅连接的连接池最大容量。连接池的连接数量自动弹性伸缩。

slaveConnectionMinimumIdleSize(从节点最小空闲连接数)
默认值:32。多从节点的环境里,每个 从服务节点里用于普通操作(非 发布和订阅)的最小保持连接数(长连接)。长期保持一定数量的连接有利于提高瞬时读取反映速度。

slaveConnectionPoolSize(从节点连接池大小)
默认值:64。多从节点的环境里,每个 从服务节点里用于普通操作(非 发布和订阅)连接的连接池最大容量。连接池的连接数量自动弹性伸缩。

masterConnectionMinimumIdleSize(主节点最小空闲连接数)
默认值:32。多从节点的环境里,每个 主节点的最小保持连接数(长连接)。长期保持一定数量的连接有利于提高瞬时写入反应速度。

masterConnectionPoolSize(主节点连接池大小)
默认值:64。主节点的连接池最大容量。连接池的连接数量自动弹性伸缩。

idleConnectionTimeout(连接空闲超时,单位:毫秒)
默认值:10000。如果当前连接池里的连接数量超过了最小空闲连接数,而同时有连接空闲时间超过了该数值,那么这些连接将会自动被关闭,并从连接池里去掉。时间单位是毫秒。

connectTimeout(连接超时,单位:毫秒)
默认值:10000。同任何节点建立连接时的等待超时。时间单位是毫秒。

timeout(命令等待超时,单位:毫秒)
默认值:3000。等待节点回复命令的时间。该时间从命令发送成功时开始计时。

retryAttempts(命令失败重试次数)
默认值:3。如果尝试达到 retryAttempts(命令失败重试次数) 仍然不能将命令发送至某个指定的节点时,将抛出错误。如果尝试在此限制之内发送成功,则开始启用 timeout(命令等待超时) 计时。

retryInterval(命令重试发送时间间隔,单位:毫秒)
默认值:1500。在一条命令发送失败以后,等待重试发送的时间间隔。时间单位是毫秒。

reconnectionTimeout(重新连接时间间隔,单位:毫秒)
默认值:3000。当与某个节点的连接断开时,等待与其重新建立连接的时间间隔。时间单位是毫秒。

failedAttempts(执行失败最大次数)
默认值:3。在某个节点执行相同或不同命令时,连续 失败 failedAttempts(执行失败最大次数) 时,该节点将被从可用节点列表里清除,直到 reconnectionTimeout(重新连接时间间隔) 超时以后再次尝试。

database(数据库编号)
默认值:0。尝试连接的数据库编号。

password(密码)
默认值:null。用于节点身份验证的密码。

subscriptionsPerConnection(单个连接最大订阅数量)
默认值:5。每个连接的最大订阅数量。

clientName(客户端名称)
默认值:null。在Redis节点里显示的客户端名称。

sslEnableEndpointIdentification(启用SSL终端识别)
默认值:true。开启SSL终端识别能力。

sslProvider(SSL实现方式)
默认值:JDK。确定采用哪种方式(JDK或OPENSSL)来实现SSL连接。

sslTruststore(SSL信任证书库路径)
默认值:null。指定SSL信任证书库的路径。

sslTruststorePassword(SSL信任证书库密码)
默认值:null

指定SSL信任证书库的密码。

sslKeystore(SSL钥匙库路径)
默认值:null。指定SSL钥匙库的路径。

sslKeystorePassword(SSL钥匙库密码)
默认值:null。指定SSL钥匙库的密码。

测试类

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes={RootConfig.class, WebConfig.class}) //如果是Java Config配置的,指定相关的配置类
@WebAppConfiguration
public class RedissionTest {

    @Autowired
    private RedissonClient redissionClusterNodes;

    @Test
    public void testConnect(){
        RBucket<String> stringRBucket = redissionClusterNodes.getBucket("test");
        //设值
        stringRBucket.set("1");
        System.out.println(stringRBucket.get());
    }
}

Redisson 操作API

分布式对象

分布式Object

通过泛型指定对象类型

RBucket<Integer> bucket = redissionClusterNodes.getBucket("test");
bucket.set(1);
Integer obj = bucket.get();
bucket.trySet(3);
bucket.compareAndSet(4, 5);
bucket.getAndSet(6);

分布式BitSet

BitSet是一个bit数据集,类似bit数组,和Set接口没啥关系。对于存储一些需要按位操作的数据是很理想的数据结构。对应于Java中 Java.util.BitSet。

RBucket<Integer> bucket = redissionClusterNodes.getBucket("test");
bucket.set(1);
Integer obj = bucket.get();
bucket.trySet(3);
bucket.compareAndSet(4, 5);
bucket.getAndSet(6);

分布式Lock

RLock lock = redissionClusterNodes.getLock("anyLock");
// Most familiar locking method
lock.lock();
// Lock time-to-live support
// releases lock automatically after 10 seconds
// if unlock method not invoked
lock.lock(10, TimeUnit.SECONDS);
// Wait for 100 seconds and automatically unlock it after 10 seconds
boolean res = lock.tryLock(100, 10, TimeUnit.SECONDS);
//...
lock.unlock();

一般我们在程序中的使用方式都是:

RLock lock = redissionClusterNodes.getLock("anyLock");
lock.lock();
try {
    ...
} finally {
    lock.unlock();
}

有时 redission分布式锁释放异常问题

分布式ReadWriteLock

RLock lock1 = redissionClusterNodes.getLock("lock1");
RLock lock2 = redissionClusterNodes.getLock("lock2");
RLock lock3 = redissionClusterNodes.getLock("lock3");
RedissonMultiLock lock = new RedissonMultiLock(lock1, lock2, lock3);
lock.lock();

分布式ReadWriteLock

RReadWriteLock rwlock = redissionClusterNodes.getReadWriteLock("anyRWLock");
// Most familiar locking method
rwlock.readLock().lock();
// or
rwlock.writeLock().lock();
// Lock time-to-live support
// releases lock automatically after 10 seconds
// if unlock method not invoked
rwlock.readLock().lock(10, TimeUnit.SECONDS);
// or
rwlock.writeLock().lock(10, TimeUnit.SECONDS);
// Wait for 100 seconds and automatically unlock it after 10 seconds
boolean res = rwlock.readLock().tryLock(100, 10, TimeUnit.SECONDS);
// or
boolean res = rwlock.writeLock().tryLock(100, 10, TimeUnit.SECONDS);

分布式Semaphore

RSemaphore semaphore = redissionClusterNodes.getSemaphore("semaphore");
semaphore.acquire();
semaphore.acquire(23);
semaphore.tryAcquire();
semaphore.tryAcquire(23, TimeUnit.SECONDS);
semaphore.release(10);
semaphore.release();

分布式AtomicLong

RAtomicLong atomicLong = redissionClusterNodes.getAtomicLong("myAtomicLong");
atomicLong.set(3);
atomicLong.incrementAndGet();
atomicLong.get();

分布式AtomicDouble

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

分布式CountDownLatch

RCountDownLatch latch = redissionClusterNodes.getCountDownLatch("anyCountDownLatch");
latch.trySetCount(1);
latch.await();
// in other thread or other JVM
RCountDownLatch latch2 = redissionClusterNodes.getCountDownLatch("anyCountDownLatch");
latch2.countDown();

Topic

RTopic topic = redissionClusterNodes.getTopic("mytopic");
topic.addListener(String.class, new MessageListener<String>() {
    @Override
    public void onMessage(CharSequence channel, String s) {
        System.out.println("channel=" + channel); //mytopic
        System.out.println("接收到的消息:" + s);
    }
});
// in other thread or JVM
RTopic topic2 = redissionClusterNodes.getTopic("mytopic");
long clientsReceivedMessage = topic.publish("1234567");
System.out.println(clientsReceivedMessage);

Topic patttern

// subscribe to all topics by `topic1.*` pattern
RPatternTopic topic1 = redissionClusterNodes.getPatternTopic("topic1.*");
topic1.addListener(String.class, new PatternMessageListener<String>() {
    @Override
    public void onMessage(CharSequence pattern, CharSequence channel, String msg) {
        System.out.println("pattern=" + pattern); //topic1.*
        System.out.println("channel=" + channel); //topic1.a
        System.out.println("msg=" + msg); //1234567
    }
});
RTopic topic2 = redissionClusterNodes.getTopic("topic1.a");
long clientsReceivedMessage = topic2.publish("1234567");
System.out.println(clientsReceivedMessage);

分布式集合

分布式Map

除此之外,还支持Multimap。

RMap<String, String> map = redissionClusterNodes.getMap("anyMap");
map.put("name", "hello");
//如果不存在,那么会向map中添加该键值对,并返回null。
//如果已经存在,那么不会覆盖已有的值,直接返回已经存在的值。
String currentValue = map.putIfAbsent("name", "harvey");
System.out.println("currentValue=" + currentValue);

//删除键的值,返回相应的值
String obj = map.remove("name");
System.out.println("obj=" + obj);

map.fastPut("name", "test");
map.fastRemove("name");

//异步设值,马上取无法取到设置的值
Future<String> putAsyncFuture = map.putAsync("alia", "cool");
System.out.println("asyncFuture value = " + putAsyncFuture.get());
//快速异步设值,只返回true或false,如果已存在返回的是false
RFuture<Boolean> rFuture = map.fastPutAsync("alia4", "mixue");
System.out.println("asyncFuture value boolean = " + rFuture.get());

map.fastPutAsync("321", "6666666");
map.fastRemoveAsync("321");

Map eviction

现在Redis没有过期清空Map中的某个entry的功能,只能是清空Map所有的entry。Redission提供了这种功能。

RMapCache<Object, Object> mapCache = redissionClusterNodes.getMapCache("anyMap");
// ttl = 10 minutes,
mapCache.put("key1", "hello", 10, TimeUnit.MINUTES);
// ttl = 10 minutes, maxIdleTime = 10 seconds
mapCache.put("key1", "hello", 10, TimeUnit.MINUTES, 10, TimeUnit.SECONDS);
// ttl = 3 seconds
mapCache.putIfAbsent("key2", "hello", 3, TimeUnit.SECONDS);
// ttl = 40 seconds, maxIdleTime = 10 seconds
mapCache.putIfAbsent("key2", "hello", 40, TimeUnit.SECONDS, 10, TimeUnit.SECONDS);

分布式Set

RSet<String> set = redissionClusterNodes.getSet("anySet");
set.add("11");
Set<String> stringSetting = set.readAll();
stringSetting.forEach(s->{
    System.out.println(s);
});
set.remove("11");

除此之外还有,还支持Set eviction, SortedSet, ScoredSortedSet, LexSortedSet。

分布式List

RList<String> list = redissionClusterNodes.getList("anyList");
list.add("11");
List<String> stringList = list.readAll();
System.out.println(stringList);
list.get(0);
list.remove("11");

分布式Blocking Queue

RBlockingQueue<String> queue = redissionClusterNodes.getBlockingQueue("anyQueue");
queue.offer("111");
//查看首个元素,不会移除首个元素,如果队列是空的就返回null
String obj = queue.peek();
//查看首个元素,不会移除首个元素,如果队列是空的就抛出异常NoSuchElementException
String obj2 = queue.element();
//将首个元素从队列中弹出,如果队列是空的,就返回null
String someObj = queue.poll();
String ob = queue.poll(10, TimeUnit.MINUTES);

除此之外,还支持Queue, Deque, Blocking Deque。

其他功能

执行批量命令

//future列表
LinkedList<RFuture<Object>> futures = new LinkedList<>();
//结果集
LinkedList<Object> result = new LinkedList<>();
RBatch batch = redissionClusterNodes.createBatch();
for (int i = 0; i < 100; i++) {
    RBucketAsync<Object> bucket = batch.getBucket("key" + i);
    RFuture<Object> async = bucket.getAsync();
    futures.add(async);
}
//批量执行
batch.execute();
while (futures.size() > 0) {
    RFuture<Object> first = futures.removeFirst();
    //获取当前值,未完成时值为null,使用isDone方法区分value不存在还是任务未完成
    Object o = first.getNow();
    if (o != null) {
        result.add(o);
    } else {
        if (!first.isDone()) {
            futures.addLast(first);
        }
    }
}

 

posted @ 2022-01-03 07:41  残城碎梦  阅读(1168)  评论(0编辑  收藏  举报