Compute
Elastic Cloud Server
Huawei Cloud Flexus
Bare Metal Server
Auto Scaling
Image Management Service
Dedicated Host
FunctionGraph
Cloud Phone Host
Huawei Cloud EulerOS
Networking
Virtual Private Cloud
Elastic IP
Elastic Load Balance
NAT Gateway
Direct Connect
Virtual Private Network
VPC Endpoint
Cloud Connect
Enterprise Router
Enterprise Switch
Global Accelerator
Management & Governance
Cloud Eye
Identity and Access Management
Cloud Trace Service
Resource Formation Service
Tag Management Service
Log Tank Service
Config
OneAccess
Resource Access Manager
Simple Message Notification
Application Performance Management
Application Operations Management
Organizations
Optimization Advisor
IAM Identity Center
Cloud Operations Center
Resource Governance Center
Migration
Server Migration Service
Object Storage Migration Service
Cloud Data Migration
Migration Center
Cloud Ecosystem
KooGallery
Partner Center
User Support
My Account
Billing Center
Cost Center
Resource Center
Enterprise Management
Service Tickets
HUAWEI CLOUD (International) FAQs
ICP Filing
Support Plans
My Credentials
Customer Operation Capabilities
Partner Support Plans
Professional Services
Analytics
MapReduce Service
Data Lake Insight
CloudTable Service
Cloud Search Service
Data Lake Visualization
Data Ingestion Service
GaussDB(DWS)
DataArts Studio
Data Lake Factory
DataArts Lake Formation
IoT
IoT Device Access
Others
Product Pricing Details
System Permissions
Console Quick Start
Common FAQs
Instructions for Associating with a HUAWEI CLOUD Partner
Message Center
Security & Compliance
Security Technologies and Applications
Web Application Firewall
Host Security Service
Cloud Firewall
SecMaster
Anti-DDoS Service
Data Encryption Workshop
Database Security Service
Cloud Bastion Host
Data Security Center
Cloud Certificate Manager
Edge Security
Situation Awareness
Managed Threat Detection
Blockchain
Blockchain Service
Web3 Node Engine Service
Media Services
Media Processing Center
Video On Demand
Live
SparkRTC
MetaStudio
Storage
Object Storage Service
Elastic Volume Service
Cloud Backup and Recovery
Storage Disaster Recovery Service
Scalable File Service Turbo
Scalable File Service
Volume Backup Service
Cloud Server Backup Service
Data Express Service
Dedicated Distributed Storage Service
Containers
Cloud Container Engine
SoftWare Repository for Container
Application Service Mesh
Ubiquitous Cloud Native Service
Cloud Container Instance
Databases
Relational Database Service
Document Database Service
Data Admin Service
Data Replication Service
GeminiDB
GaussDB
Distributed Database Middleware
Database and Application Migration UGO
TaurusDB
Middleware
Distributed Cache Service
API Gateway
Distributed Message Service for Kafka
Distributed Message Service for RabbitMQ
Distributed Message Service for RocketMQ
Cloud Service Engine
Multi-Site High Availability Service
EventGrid
Dedicated Cloud
Dedicated Computing Cluster
Business Applications
Workspace
ROMA Connect
Message & SMS
Domain Name Service
Edge Data Center Management
Meeting
AI
Face Recognition Service
Graph Engine Service
Content Moderation
Image Recognition
Optical Character Recognition
ModelArts
ImageSearch
Conversational Bot Service
Speech Interaction Service
Huawei HiLens
Video Intelligent Analysis Service
Developer Tools
SDK Developer Guide
API Request Signing Guide
Terraform
Koo Command Line Interface
Content Delivery & Edge Computing
Content Delivery Network
Intelligent EdgeFabric
CloudPond
Intelligent EdgeCloud
Solutions
SAP Cloud
High Performance Computing
Developer Services
ServiceStage
CodeArts
CodeArts PerfTest
CodeArts Req
CodeArts Pipeline
CodeArts Build
CodeArts Deploy
CodeArts Artifact
CodeArts TestPlan
CodeArts Check
CodeArts Repo
Cloud Application Engine
MacroVerse aPaaS
KooMessage
KooPhone
KooDrive

Connecting to Redis on Lettuce (Java)

Updated on 2024-07-29 GMT+08:00

This section describes how to access a Redis instance on Lettuce. For more information about how to use other Redis clients, visit the Redis official website.

Spring Data Redis is already integrated with Jedis and Lettuce for Spring Boot projects. In addition, Spring Boot 1.x is integrated with Jedis, and Spring Boot 2.x with Lettuce. Therefore, you do not need to import Lettuce in Spring Boot 2.x and later projects.

Prerequisites

  • A DCS Redis instance has been created and is in the Running state.
  • View the IP address and port number of the DCS Redis instance to be accessed.

    For details, see Viewing Details of a DCS Instance.

Pom Configuration

<!-- Enable Spring Data Redis, Lettuce-supported SDK is integrated by default -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

application.properties Configuration

  • Single-node, master/standby, and Proxy Cluster
    #Redis host
    spring.redis.host=<host>
    #Redis port
    spring.redis.port=<port>
    #Redis database number
    spring.redis.database=0
    #Redis password
    spring.redis.password=<password>
    #Redis read/write timeout
    spring.redis.timeout=2000
  • Redis Cluster
    #Redis Cluster node information
    spring.redis.cluster.nodes=<ip:port>,<ip:port>,<ip:port>
    #Redis Cluster max redirecting times
    spring.redis.cluster.max-redirects=3
    #Redis Cluster node password
    spring.redis.password=<password>
    #Redis Cluster timeout
    spring.redis.timeout=2000
    #Enable adaptive topology refresh
    spring.redis.lettuce.cluster.refresh.adaptive=true
    #Enable topology refresh every 10 seconds
    spring.redis.lettuce.cluster.refresh.period=10S

Bean Configuration

  • Single-node, master/standby, and Proxy Cluster
    import java.time.Duration;
    
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.data.redis.connection.RedisConnectionFactory;
    import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
    import org.springframework.data.redis.connection.lettuce.LettuceClientConfiguration;
    import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
    
    import io.lettuce.core.ClientOptions;
    import io.lettuce.core.SocketOptions;
    
    /**
    * Lettuce non-pooling configuration (use either this or the application.properties configuration)
    */
    @Configuration
    public class RedisConfiguration {
    
        @Value("${redis.host}")
        private String redisHost;
    
        @Value("${redis.port:6379}")
        private Integer redisPort = 6379;
    
        @Value("${redis.database:0}")
        private Integer redisDatabase = 0;
    
        @Value("${redis.password:}")
        private String redisPassword;
    
        @Value("${redis.connect.timeout:2000}")
        private Integer redisConnectTimeout = 2000;
    
        @Value("${redis.read.timeout:2000}")
        private Integer redisReadTimeout = 2000;
    
        @Bean
        public RedisConnectionFactory redisConnectionFactory(LettuceClientConfiguration clientConfiguration) {
    
            RedisStandaloneConfiguration standaloneConfiguration = new RedisStandaloneConfiguration();
            standaloneConfiguration.setHostName(redisHost);
            standaloneConfiguration.setPort(redisPort);
            standaloneConfiguration.setDatabase(redisDatabase);
            standaloneConfiguration.setPassword(redisPassword);
    
            LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory(standaloneConfiguration, clientConfiguration);
            connectionFactory.setDatabase(redisDatabase);
            return connectionFactory;
        }
    
        @Bean
        public LettuceClientConfiguration clientConfiguration() {
    
            SocketOptions socketOptions = SocketOptions.builder().connectTimeout(Duration.ofMillis(redisConnectTimeout)).build();
    
            ClientOptions clientOptions = ClientOptions.builder()
                    .autoReconnect(true)
                    .pingBeforeActivateConnection(true)
                    .cancelCommandsOnReconnectFailure(false)
                    .disconnectedBehavior(ClientOptions.DisconnectedBehavior.ACCEPT_COMMANDS)
                    .socketOptions(socketOptions)
                    .build();
    
            LettuceClientConfiguration clientConfiguration = LettuceClientConfiguration.builder()
                    .commandTimeout(Duration.ofMillis(redisReadTimeout))
                    .clientOptions(clientOptions)
                    .build();
            return clientConfiguration;
        }
    }
  • Pooling configuration for single-node, master/standby, and Proxy Cluster instances
    Enable the pooling component
    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-pool2</artifactId>
        <version>2.11.1</version>
    </dependency>

    Code

    import java.time.Duration;
    
    import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.data.redis.connection.RedisConnectionFactory;
    import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
    import org.springframework.data.redis.connection.lettuce.LettuceClientConfiguration;
    import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
    import org.springframework.data.redis.connection.lettuce.LettucePoolingClientConfiguration;
    
    import io.lettuce.core.ClientOptions;
    import io.lettuce.core.SocketOptions;
    
    /**
    * Lettuce pooling configuration
    */
    @Configuration
    public class RedisPoolConfiguration {
        @Value("${redis.host}")
        private String redisHost;
    
        @Value("${redis.port:6379}")
        private Integer redisPort = 6379;
    
        @Value("${redis.database:0}")
        private Integer redisDatabase = 0;
    
        @Value("${redis.password:}")
        private String redisPassword;
    
        @Value("${redis.connect.timeout:2000}")
        private Integer redisConnectTimeout = 2000;
    
        @Value("${redis.read.timeout:2000}")
        private Integer redisReadTimeout = 2000;
    
        @Value("${redis.pool.minSize:50}")
        private Integer redisPoolMinSize = 50;
    
        @Value("${redis.pool.maxSize:200}")
        private Integer redisPoolMaxSize = 200;
    
        @Value("${redis.pool.maxWaitMillis:2000}")
        private Integer redisPoolMaxWaitMillis = 2000;
    
        @Value("${redis.pool.softMinEvictableIdleTimeMillis:1800000}")
        private Integer redisPoolSoftMinEvictableIdleTimeMillis = 30 * 60 * 1000;
    
        @Value("${redis.pool.timeBetweenEvictionRunsMillis:60000}")
        private Integer redisPoolBetweenEvictionRunsMillis = 60 * 1000;
    
        @Bean
        public RedisConnectionFactory redisConnectionFactory(LettuceClientConfiguration clientConfiguration) {
    
            RedisStandaloneConfiguration standaloneConfiguration = new RedisStandaloneConfiguration();
            standaloneConfiguration.setHostName(redisHost);
            standaloneConfiguration.setPort(redisPort);
            standaloneConfiguration.setDatabase(redisDatabase);
            standaloneConfiguration.setPassword(redisPassword);
    
            LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory(standaloneConfiguration, clientConfiguration);
            connectionFactory.setDatabase(redisDatabase);
            //Disable sharing native connection before enabling pooling
            connectionFactory.setShareNativeConnection(false);
            return connectionFactory;
        }
    
        @Bean
        public LettuceClientConfiguration clientConfiguration() {
    
            SocketOptions socketOptions = SocketOptions.builder().connectTimeout(Duration.ofMillis(redisConnectTimeout)).build();
    
            ClientOptions clientOptions = ClientOptions.builder()
                    .autoReconnect(true)
                    .pingBeforeActivateConnection(true)
                    .cancelCommandsOnReconnectFailure(false)
                    .disconnectedBehavior(ClientOptions.DisconnectedBehavior.ACCEPT_COMMANDS)
                    .socketOptions(socketOptions)
                    .build();
    
            LettucePoolingClientConfiguration poolingClientConfiguration = LettucePoolingClientConfiguration.builder()
                    .poolConfig(redisPoolConfig())
                    .commandTimeout(Duration.ofMillis(redisReadTimeout))
                    .clientOptions(clientOptions)
                    .build();
            return poolingClientConfiguration;
        }
    
        private GenericObjectPoolConfig redisPoolConfig() {
            GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();
            //Minimum idle connections in the pool
            poolConfig.setMinIdle(redisPoolMinSize);
            //Maximum idle connections in the pool
            poolConfig.setMaxIdle(redisPoolMaxSize);
            //Maximum total connections in the pool
            poolConfig.setMaxTotal(redisPoolMaxSize);
            //Wait when pool is exhausted? Set to true to wait. To validate setMaxWait, it has to be true.
            poolConfig.setBlockWhenExhausted(true);
            //Max allowed time to wait for connection after pool is exhausted. The default value -1 indicates to wait indefinitely.
            poolConfig.setMaxWait(Duration.ofMillis(redisPoolMaxWaitMillis));
            //Set to true to enable connectivity test on creating connections. Default: false.
            poolConfig.setTestOnCreate(false);
            //Set to true to enable connectivity test on borrowing connections. Default: false. Set to false for heavy-traffic services to reduce overhead.
            poolConfig.setTestOnBorrow(true);
            //Set to true to enable connectivity test on returning connections. Default: false. Set to false for heavy-traffic services to reduce overhead.
            poolConfig.setTestOnReturn(false);
            //Indicates whether to check for idle connections. If this is set to false, idle connections are not evicted.
            poolConfig.setTestWhileIdle(true);
            //Idle duration after which a connection is evicted. If the actual duration is greater than this value and the maximum number of idle connections is reached, idle connections are directly evicted.
            poolConfig.setSoftMinEvictableIdleTime(Duration.ofMillis(redisPoolSoftMinEvictableIdleTimeMillis));
            //Disable eviction policy MinEvictableIdleTimeMillis().
            poolConfig.setMinEvictableIdleTime(Duration.ofMillis(-1));
            //Interval for checking and evicting idle connections. Default: 60s.
            poolConfig.setTimeBetweenEvictionRuns(Duration.ofMillis(redisPoolBetweenEvictionRunsMillis));
            return poolConfig;
        }
    }
  • Configuration for Redis Cluster instances
    import java.time.Duration;
    import java.util.ArrayList;
    import java.util.List;
    
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.data.redis.connection.RedisClusterConfiguration;
    import org.springframework.data.redis.connection.RedisConnectionFactory;
    import org.springframework.data.redis.connection.RedisNode;
    import org.springframework.data.redis.connection.lettuce.LettuceClientConfiguration;
    import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
    
    import io.lettuce.core.ClientOptions;
    import io.lettuce.core.SocketOptions;
    import io.lettuce.core.cluster.ClusterClientOptions;
    import io.lettuce.core.cluster.ClusterTopologyRefreshOptions;
    
    /**
    * Lettuce Cluster non-pooling configuration (use either this or the application.properties configuration)
    */
    @Configuration
    public class RedisConfiguration {
    
        @Value("${redis.cluster.nodes}")
        private String redisClusterNodes;
    
        @Value("${redis.cluster.maxDirects:3}")
        private Integer redisClusterMaxDirects;
    
        @Value("${redis.password:}")
        private String redisPassword;
    
        @Value("${redis.connect.timeout:2000}")
        private Integer redisConnectTimeout = 2000;
    
        @Value("${redis.read.timeout:2000}")
        private Integer redisReadTimeout = 2000;
    
        @Value("${redis.cluster.topology.refresh.period.millis:10000}")
        private Integer redisClusterTopologyRefreshPeriodMillis = 10000;
    
        @Bean
        public RedisConnectionFactory redisConnectionFactory(LettuceClientConfiguration clientConfiguration) {
    
            RedisClusterConfiguration clusterConfiguration = new RedisClusterConfiguration();
    
            List<RedisNode> clusterNodes = new ArrayList<>();
            for (String clusterNodeStr : redisClusterNodes.split(",")) {
                String[] nodeInfo = clusterNodeStr.split(":");
                clusterNodes.add(new RedisNode(nodeInfo[0], Integer.valueOf(nodeInfo[1])));
            }
            clusterConfiguration.setClusterNodes(clusterNodes);
    
            clusterConfiguration.setPassword(redisPassword);
            clusterConfiguration.setMaxRedirects(redisClusterMaxDirects);
    
            LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory(clusterConfiguration, clientConfiguration);
            return connectionFactory;
        }
    
        @Bean
        public LettuceClientConfiguration clientConfiguration() {
    
            SocketOptions socketOptions = SocketOptions.builder().connectTimeout(Duration.ofMillis(redisConnectTimeout)).build();
    
            ClusterTopologyRefreshOptions topologyRefreshOptions = ClusterTopologyRefreshOptions.builder()
                    .enableAllAdaptiveRefreshTriggers()
                    .enablePeriodicRefresh(Duration.ofMillis(redisClusterTopologyRefreshPeriodMillis))
                    .build();
    
            ClusterClientOptions clientOptions = ClusterClientOptions.builder()
                    .autoReconnect(true)
                    .pingBeforeActivateConnection(true)
                    .cancelCommandsOnReconnectFailure(false)
                    .disconnectedBehavior(ClientOptions.DisconnectedBehavior.ACCEPT_COMMANDS)
                    .socketOptions(socketOptions)
                    .topologyRefreshOptions(topologyRefreshOptions)
                    .build();
    
            LettuceClientConfiguration clientConfiguration = LettuceClientConfiguration.builder()
                    .commandTimeout(Duration.ofMillis(redisReadTimeout))
                    .clientOptions(clientOptions)
                    .build();
            return clientConfiguration;
        }
    }
  • Pooling configuration for Redis Cluster instances
    Enable the pooling component
    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-pool2</artifactId>
        <version>2.11.1</version>
    </dependency>

    Code

    import java.time.Duration;
    import java.util.ArrayList;
    import java.util.List;
    
    import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.data.redis.connection.RedisClusterConfiguration;
    import org.springframework.data.redis.connection.RedisConnectionFactory;
    import org.springframework.data.redis.connection.RedisNode;
    import org.springframework.data.redis.connection.lettuce.LettuceClientConfiguration;
    import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
    import org.springframework.data.redis.connection.lettuce.LettucePoolingClientConfiguration;
    
    import io.lettuce.core.ClientOptions;
    import io.lettuce.core.SocketOptions;
    import io.lettuce.core.cluster.ClusterClientOptions;
    import io.lettuce.core.cluster.ClusterTopologyRefreshOptions;
    
    /**
    * Lettuce pooling configuration
    */
    @Configuration
    public class RedisPoolConfiguration {
    
        @Value("${redis.cluster.nodes}")
        private String redisClusterNodes;
    
        @Value("${redis.cluster.maxDirects:3}")
        private Integer redisClusterMaxDirects;
    
        @Value("${redis.password:}")
        private String redisPassword;
    
        @Value("${redis.connect.timeout:2000}")
        private Integer redisConnectTimeout = 2000;
    
        @Value("${redis.read.timeout:2000}")
        private Integer redisReadTimeout = 2000;
    
        @Value("${redis.cluster.topology.refresh.period.millis:10000}")
        private Integer redisClusterTopologyRefreshPeriodMillis = 10000;
    
        @Value("${redis.pool.minSize:50}")
        private Integer redisPoolMinSize = 50;
    
        @Value("${redis.pool.maxSize:200}")
        private Integer redisPoolMaxSize = 200;
    
        @Value("${redis.pool.maxWaitMillis:2000}")
        private Integer redisPoolMaxWaitMillis = 2000;
    
        @Value("${redis.pool.softMinEvictableIdleTimeMillis:1800000}")
        private Integer redisPoolSoftMinEvictableIdleTimeMillis = 30 * 60 * 1000;
    
        @Value("${redis.pool.timeBetweenEvictionRunsMillis:60000}")
        private Integer redisPoolBetweenEvictionRunsMillis = 60 * 1000;
    
        @Bean
        public RedisConnectionFactory redisConnectionFactory(LettuceClientConfiguration clientConfiguration) {
    
            RedisClusterConfiguration clusterConfiguration = new RedisClusterConfiguration();
    
            List<RedisNode> clusterNodes = new ArrayList<>();
            for (String clusterNodeStr : redisClusterNodes.split(",")) {
                String[] nodeInfo = clusterNodeStr.split(":");
                clusterNodes.add(new RedisNode(nodeInfo[0], Integer.valueOf(nodeInfo[1])));
            }
            clusterConfiguration.setClusterNodes(clusterNodes);
    
            clusterConfiguration.setPassword(redisPassword);
            clusterConfiguration.setMaxRedirects(redisClusterMaxDirects);
    
            LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory(clusterConfiguration, clientConfiguration);
            //Disable native connection sharing before validating connection pool
            connectionFactory.setShareNativeConnection(false);
            return connectionFactory;
        }
    
        @Bean
        public LettuceClientConfiguration clientConfiguration() {
    
            SocketOptions socketOptions = SocketOptions.builder().connectTimeout(Duration.ofMillis(redisConnectTimeout)).build();
    
            ClusterTopologyRefreshOptions topologyRefreshOptions = ClusterTopologyRefreshOptions.builder()
                    .enableAllAdaptiveRefreshTriggers()
                    .enablePeriodicRefresh(Duration.ofMillis(redisClusterTopologyRefreshPeriodMillis))
                    .build();
    
            ClusterClientOptions clientOptions = ClusterClientOptions.builder()
                    .autoReconnect(true)
                    .pingBeforeActivateConnection(true)
                    .cancelCommandsOnReconnectFailure(false)
                    .disconnectedBehavior(ClientOptions.DisconnectedBehavior.ACCEPT_COMMANDS)
                    .socketOptions(socketOptions)
                    .topologyRefreshOptions(topologyRefreshOptions)
                    .build();
    
            LettucePoolingClientConfiguration clientConfiguration = LettucePoolingClientConfiguration.builder()
                    .poolConfig(poolConfig())
                    .commandTimeout(Duration.ofMillis(redisReadTimeout))
                    .clientOptions(clientOptions)
                    .build();
            return clientConfiguration;
        }
    
        private GenericObjectPoolConfig poolConfig() {
            GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();
            //Minimum connections in the pool
            poolConfig.setMinIdle(redisPoolMinSize);
            //Maximum idle connections in the pool
            poolConfig.setMaxIdle(redisPoolMaxSize);
            //Maximum total connections in the pool
            poolConfig.setMaxTotal(redisPoolMaxSize);
            //Wait when pool is exhausted? Set to true to wait. To validate setMaxWait, it has to be true.
            poolConfig.setBlockWhenExhausted(true);
            //Max allowed time to wait for connection after pool is exhausted. The default value -1 indicates to wait indefinitely.
            poolConfig.setMaxWait(Duration.ofMillis(redisPoolMaxWaitMillis));
            //Set to true to enable connectivity test on creating connections. Default: false.
            poolConfig.setTestOnCreate(false);
            //Set to true to enable connectivity test on borrowing connections. Default: false. Set to false for heavy-traffic services to reduce overhead.
            poolConfig.setTestOnBorrow(true);
            //Set to true to enable connectivity test on returning connections. Default: false. Set to false for heavy-traffic services to reduce overhead.
            poolConfig.setTestOnReturn(false);
            //Indicates whether to check for idle connections. If this is set to false, idle connections are not evicted.
            poolConfig.setTestWhileIdle(true);
            //Disable connection closure when the minimum idle time is reached.
            poolConfig.setMinEvictableIdleTime(Duration.ofMillis(-1));
            //Idle duration before a connection being evicted. If the actual duration is greater than this value and the maximum number of idle connections is reached, idle connections are directly evicted. MinEvictableIdleTimeMillis (default eviction policy) is no longer used.
            poolConfig.setSoftMinEvictableIdleTime(Duration.ofMillis(redisPoolSoftMinEvictableIdleTimeMillis));
            //Interval for checking and evicting idle connections. Default: 60s.
            poolConfig.setTimeBetweenEvictionRuns(Duration.ofMillis(redisPoolBetweenEvictionRunsMillis));
    
            return poolConfig;
        }
    
    }

(Optional) Configuring SSL Connections

If SSL is enabled for an instance, to access it using SSL connections, use the following content to replace the LettuceClientConfiguration construction method clientConfiguration() in Bean Configuration. For details about whether your DCS Redis instances support SSL, see Transmitting DCS Redis Data with Encryption Using SSL.

  • Single-node, master/standby, and Proxy Cluster
    @Bean
    public LettuceClientConfiguration clientConfiguration() {
    
        SocketOptions socketOptions = SocketOptions.builder().connectTimeout(Duration.ofMillis(redisConnectTimeout)).build();
    
        SslOptions sslOptions = SslOptions.builder()
            .trustManager(new File(certificationPath))
            .build();
    
        ClientOptions clientOptions = ClientOptions.builder()
            .sslOptions(sslOptions)
            .autoReconnect(true)
            .pingBeforeActivateConnection(true)
            .cancelCommandsOnReconnectFailure(false)
            .disconnectedBehavior(ClientOptions.DisconnectedBehavior.ACCEPT_COMMANDS)
            .socketOptions(socketOptions)
            .build();
    
        LettuceClientConfiguration clientConfiguration = LettuceClientConfiguration.builder()
            .commandTimeout(Duration.ofMillis(redisReadTimeout))
            .clientOptions(clientOptions)
            .useSsl()
            .build();
    
        return clientConfiguration;
    }
  • Redis Cluster
    @Bean
    public LettuceClientConfiguration clientConfiguration() {
    
        SocketOptions socketOptions = SocketOptions.builder().connectTimeout(Duration.ofMillis(redisConnectTimeout)).build();
    
        SslOptions sslOptions = SslOptions.builder()
            .trustManager(new File(certificationPath))
            .build();
    
        ClusterTopologyRefreshOptions topologyRefreshOptions = ClusterTopologyRefreshOptions.builder()
            .enableAllAdaptiveRefreshTriggers()
            .enablePeriodicRefresh(Duration.ofMillis(redisClusterTopologyRefreshPeriodMillis))
            .build();
    
        ClusterClientOptions clientOptions = ClusterClientOptions.builder()
            .sslOptions(sslOptions)
            .autoReconnect(true)
            .pingBeforeActivateConnection(true)
            .cancelCommandsOnReconnectFailure(false)
            .disconnectedBehavior(ClientOptions.DisconnectedBehavior.ACCEPT_COMMANDS)
            .socketOptions(socketOptions)
            .topologyRefreshOptions(topologyRefreshOptions)
            .build();
    
        LettuceClientConfiguration clientConfiguration = LettuceClientConfiguration.builder()
            .commandTimeout(Duration.ofMillis(redisReadTimeout))
            .clientOptions(clientOptions)
            .useSsl()
            .build();
    
        return clientConfiguration;
    }

Parameter Description

Table 1 LettuceConnectionFactory parameters

Parameter

Type

Default Value

Description

configuration

RedisConfiguration

-

Redis connection configuration. Two subsclasses:

  • RedisStandaloneConfiguration
  • RedisClusterConfiguration

clientConfiguration

LettuceClientConfiguration

-

Client configuration parameter. Common subclass:

LettucePoolingClientConfiguration

shareNativeConnection

boolean

true

Indicates whether to share native connections. Set to true to share. Set to false to enable connection pooling.

Table 2 RedisStandaloneConfiguration parameters

Parameter

Default Value

Description

hostName

localhost

IP address for connecting to a DCS Redis instance

port

6379

Port number

database

0

Database subscript

password

-

Password

Table 3 RedisClusterConfiguration parameters

Parameter

Description

clusterNodes

Cluster node connection information, including the node IP address and port number

maxRedirects

Maximum redirecting times. Recommended value: 3.

password

Password

Table 4 LettuceClientConfiguration parameters

Parameter

Type

Default Value

Description

timeout

Duration

60s

Command timeout: Recommended: 2s.

clientOptions

ClientOptions

-

Configuration options.

Table 5 LettucePoolingClientConfiguration parameters

Parameter

Type

Default Value

Description

timeout

Duration

60s

Command timeout: Recommended: 2s.

clientOptions

ClientOptions

-

Configuration options.

poolConfig

GenericObjectPoolConfig

-

Connection pool configuration.

Table 6 ClientOptions parameters

Parameter

Type

Default Value

Description

autoReconnect

boolean

true

Indicates whether to automatically reconnect after disconnection. Recommended: true.

pingBeforeActivateConnection

boolean

true

Indicates whether to test connectivity on established connections. Recommended: true.

cancelCommandsOnReconnectFailure

boolean

true

Indicates whether to cancel commands after a failed reconnection attempt. Recommended: false.

disconnectedBehavior

DisconnectedBehavior

DisconnectedBehavior.DEFAULT

Indicates what to do when a connection drops. Recommended: ACCEPT_COMMANDS.

  • DEFAULT: When autoReconnect is set true, commands are allowed to wait in queue. When autoReconnect is set to false, commands are not allowed to wait in queue.
  • ACCEPT_COMMANDS: Allow commands to wait in queue.
  • REJECT_COMMANDS: Do not allow commands to wait in queue.

socketOptions

SocketOptions

-

Socket configuration.

Table 7 SocketOptions parameters

Parameter

Default Value

Description

connectTimeout

10s

Connection timeout. Recommended: 2s.

Table 8 GenericObjectPoolConfig parameters

Parameter

Default Value

Description

minIdle

-

Minimum connections in the pool.

maxIdle

-

Maximum idle connections in the connection pool.

maxTotal

-

Maximum total connections in the connection pool.

blockWhenExhausted

true

Indicates whether to wait after the connection pool is exhausted. true: Wait. false: Do not wait. To validate maxWaitMillis, this parameter must be set to true.

maxWaitMillis

-1

Maximum amount of time a connection allocation should block before throwing an exception when the pool is exhausted. The default value –1 indicates to wait indefinitely.

testOnCreate

false

Set to true to enable connectivity test on creating connections. Default: false.

testOnBorrow

false

Set to true to enable connectivity test on borrowing connections. Default: false. Set to false for heavy-traffic services to reduce overhead.

testOnReturn

false

Set to true to enable connectivity test on returning connections. Default: false. Set to false for heavy-traffic services to reduce overhead.

testWhileIdle

false

Indicates whether to check for idle connections. If this parameter is set to false, idle connections are not evicted. Recommended value: true.

softMinEvictableIdleTimeMillis

1800000

Duration after which idle connections are evicted. If the idle duration is greater than this value and the maximum number of idle connections is reached, idle connections are directly evicted.

minEvictableIdleTimeMillis

60000

An eviction policy, set to –1 (suggested) to disable it. Use softminEvictableIdleTimeMillis instead.

timeBetweenEvictionRunsMillis

60000

Eviction interval, in milliseconds.

Suggestion for Configuring DCS Instances

  • Pooling connection

    Different from Jedis's BIO, the bottom layer of Lettuce communicates with Redis Server based on Netty's NIO. Combining persistent connections and queues, Lettuce sends and receives multiple requests and responses spontaneously with sequential sending and receiving features of TCP. A single connection supports 3000 to 5000 QPS, but you are not advised to allow more than 3000 QPS in production systems. Pooling is not supported by Lettuce, and is disabled by default in Spring Boot. To enable pooling, validate the commons-pool2 dependency and disable native connection sharing.

    By default, each Lettuce connection needs two thread pools, I/O thread pool and computation thread pool, to support I/O event reading and asynchronous event processing. If you configure connection pooling, each connection creates two thread pools, consuming high memory resources. Lettuce is strong at processing single connections based on its bottom-layer implementation, so you are not advised to use Lettuce with pooling.

  • Topology refresh

    When connecting to a Redis Cluster instance, Lettuce randomly sends cluster nodes to the node list during initialization to obtain the distribution of cluster slots. Cluster topology structure changes when the cluster capacity is increased or decreased or a master/standby switchover occurs. Lettuce does not detect such changes by default. You can enable detection with the following configurations:

    • application.properties configuration
      #Enable adaptive topology refresh.
      spring.redis.lettuce.cluster.refresh.adaptive=true
      #Enable topology refresh every 10 seconds.
      spring.redis.lettuce.cluster.refresh.period=10S
    • API configuration
      ClusterTopologyRefreshOptions topologyRefreshOptions = ClusterTopologyRefreshOptions.builder()
          .enableAllAdaptiveRefreshTriggers()
          .enablePeriodicRefresh(Duration.ofMillis(redisClusterTopologyRefreshPeriodMillis))
          .build();
      
      ClusterClientOptions clientOptions = ClusterClientOptions.builder()
              ...
              ...
              .topologyRefreshOptions(topologyRefreshOptions)
              .build();
  • Blast radius

    The bottom layer of Lettuce uses a combination of single persistent connection and request queue. Once network jitter or intermittent disconnection occurs or connection times out, all requests are affected. Especially when connection times out, an attempt is made to resend TCP pockets until timeout and connection drops. Requests do not recover until connections are reestablished. Requests accumulate during resending attempts. If upper-layer services time out in batches, or the resending timeout is too long in some OSs' kernels, the service system remains unavailable for a long time. Therefore, you are advised to use Jedis instead of Lettuce.

We use cookies to improve our site and your experience. By continuing to browse our site you accept our cookie policy. Find out more

Feedback

Feedback

Feedback

0/500

Selected Content

Submit selected content with the feedback