SpringBoot series of tutorials Redis cluster environment configuration

Before the introduction of several redis Bowen presentation are described based on redis stand-alone basis, but in the actual production environment, the possibility of using redis clusters should be greater than the stand-alone version of redis, then redis clusters of how to operate it? What is the difference between it and stand-alone configuration, what needs to pay attention to it?

This article deals mainly introduces SpringBoot project integration redis clusters, and instructions for problems arising in the course of this, and the corresponding solutions

I. environment-related

First you need to install redis cluster environment, you can refer Bowen: redis- Cluster Setup Guide

Then initializes springboot item, the corresponding structure is as follows pom

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.1.7</version>
    <relativePath/> <!-- lookup parent from update -->
</parent>

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <spring-cloud.version>Finchley.RELEASE</spring-cloud.version>
    <java.version>1.8</java.version>
</properties>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-pool2</artifactId>
    </dependency>
</dependencies>

<build>
    <pluginManagement>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </pluginManagement>
</build>
<repositories>
    <repository>
        <id>spring-milestones</id>
        <name>Spring Milestones</name>
        <url>https://repo.spring.io/milestone</url>
        <snapshots>
            <enabled>false</enabled>
        </snapshots>
    </repository>
</repositories

Note that, we have introduced two packages, one is necessary spring-boot-starter-data-redis, an operating redis package start official tool by means of which we can be very convenient to operate directly RedisTemplate redis

Another is commonos-pool2this package, mainly when we configured redis connection pool when the need to use it, otherwise it will throw a Class Not Found exception

II. Environmental Integration and Pit

Here I will redis clusters built on a centos LAN machines, from the back of the profile can be seen (Why such a deal? Primarily to elicit a back problem)

1. application.yml

First let's follow the default configuration to get our RedisTemplateorder to achieve the fastest access redis clusters

spring:
  redis:
    password:
    cluster:
      nodes: 192.168.0.203:7000,192.168.0.203:7001,192.168.0.203:7002
      max-redirects: 3
    lettuce:
      pool:
        max-idle: 16
        max-active: 32
        min-idle: 8

We built redis clusters, call the shots did not prepare (or need six instances), in order to save trouble, there is no password (a production environment, which is strictly prohibited)

2. Use test

Because we use the default configuration, so you can get directly bean object RedisTemplate was operated by redis clusters

@SpringBootApplication
public class Application {

    public Application(RedisTemplate redisTemplate) {
        redisTemplate.opsForValue().set("spring-r-cluster-1", 123);
        redisTemplate.opsForValue().set("spring-r-cluster-2", 456);
        redisTemplate.opsForValue().set("spring-r-cluster-3", 789);
    }

    public static void main(String[] args) {
        SpringApplication.run(Application.class);
    }
}

a. refuse to connect

After executing the above, the first error is reported connection refused, but I was in (203) can be connected successfully in the machine redis cluster is located, but the unit is connected error

The above problem occurs, generally there are two reasons, one is not caused by a firewall port for external access, a configuration is redis

Confirmation way firewall

  • Determine whether the firewall is turned on: firewall-cmd --stateIf you are prompted not running means not open
  • View firewall rules: firewall-cmd --list-all

Then according to the actual scene, add port

# 永久开启7000端口的公共访问权限
sudo firewall-cmd --zone=public --add-port=7000/tcp --permanent
sudo firewall-cmd --reload

Of course, the test environment, including the network, you can turn off the firewall directly

//Disable firewall
systemctl disable firewalld
systemctl stop firewalld
systemctl status firewalld

//Enable firewall
systemctl enable firewalld
systemctl start firewalld
systemctl status firewalld

redis Configuration

If the confirmation is not a firewall issue, then mostly redis need to change the configuration, in the redis.confmiddle, there is a line bind 127.0.0.1configuration enabled by default, indicates that only allow access to the machine, other machines do not have access

The solution is to modify the configuration and reboot

bind 0.0.0.0

b. Unable to connect to 127.0.0.1:7001

The implementation of the previous test, found to throw a strange anomaly follows

Stack key information is as follows

Caused by: org.springframework.data.redis.RedisSystemException: Redis exception; nested exception is io.lettuce.core.RedisException: io.lettuce.core.RedisConnectionException: Unable to connect to 127.0.0.1:7001
    at org.springframework.data.redis.connection.lettuce.LettuceExceptionConverter.convert(LettuceExceptionConverter.java:74) ~[spring-data-redis-2.0.9.RELEASE.jar:2.0.9.RELEASE]
    at org.springframework.data.redis.connection.lettuce.LettuceExceptionConverter.convert(LettuceExceptionConverter.java:41) ~[spring-data-redis-2.0.9.RELEASE.jar:2.0.9.RELEASE]
    at org.springframework.data.redis.PassThroughExceptionTranslationStrategy.translate(PassThroughExceptionTranslationStrategy.java:44) ~[spring-data-redis-2.0.9.RELEASE.jar:2.0.9.RELEASE]
    at org.springframework.data.redis.FallbackExceptionTranslationStrategy.translate(FallbackExceptionTranslationStrategy.java:42) ~[spring-data-redis-2.0.9.RELEASE.jar:2.0.9.RELEASE]
    at org.springframework.data.redis.connection.lettuce.LettuceConnection.convertLettuceAccessException(LettuceConnection.java:257) ~[spring-data-redis-2.0.9.RELEASE.jar:2.0.9.RELEASE]
    at org.springframework.data.redis.connection.lettuce.LettuceStringCommands.convertLettuceAccessException(LettuceStringCommands.java:718) ~[spring-data-redis-2.0.9.RELEASE.jar:2.0.9.RELEASE]
    at org.springframework.data.redis.connection.lettuce.LettuceStringCommands.set(LettuceStringCommands.java:143) ~[spring-data-redis-2.0.9.RELEASE.jar:2.0.9.RELEASE]
    at org.springframework.data.redis.connection.DefaultedRedisConnection.set(DefaultedRedisConnection.java:231) ~[spring-data-redis-2.0.9.RELEASE.jar:2.0.9.RELEASE]
    at org.springframework.data.redis.core.DefaultValueOperations$3.inRedis(DefaultValueOperations.java:202) ~[spring-data-redis-2.0.9.RELEASE.jar:2.0.9.RELEASE]
    at org.springframework.data.redis.core.AbstractOperations$ValueDeserializingRedisCallback.doInRedis(AbstractOperations.java:59) ~[spring-data-redis-2.0.9.RELEASE.jar:2.0.9.RELEASE]
    at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:224) ~[spring-data-redis-2.0.9.RELEASE.jar:2.0.9.RELEASE]
    at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:184) ~[spring-data-redis-2.0.9.RELEASE.jar:2.0.9.RELEASE]
    at org.springframework.data.redis.core.AbstractOperations.execute(AbstractOperations.java:95) ~[spring-data-redis-2.0.9.RELEASE.jar:2.0.9.RELEASE]
    at org.springframework.data.redis.core.DefaultValueOperations.set(DefaultValueOperations.java:198) ~[spring-data-redis-2.0.9.RELEASE.jar:2.0.9.RELEASE]
    at com.git.hui.boot.redis.cluster.Application.<init>(Application.java:14) [classes/:na]
    at com.git.hui.boot.redis.cluster.Application$$EnhancerBySpringCGLIB$$ac0c03ba.<init>(<generated>) ~[classes/:na]
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[na:1.8.0_171]
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) ~[na:1.8.0_171]
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[na:1.8.0_171]
    at java.lang.reflect.Constructor.newInstance(Constructor.java:423) ~[na:1.8.0_171]
    at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:170) ~[spring-beans-5.0.8.RELEASE.jar:5.0.8.RELEASE]
    ... 19 common frames omitted
Caused by: io.lettuce.core.RedisException: io.lettuce.core.RedisConnectionException: Unable to connect to 127.0.0.1:7001
    at io.lettuce.core.LettuceFutures.awaitOrCancel(LettuceFutures.java:125) ~[lettuce-core-5.0.4.RELEASE.jar:na]
    at io.lettuce.core.cluster.ClusterFutureSyncInvocationHandler.handleInvocation(ClusterFutureSyncInvocationHandler.java:118) ~[lettuce-core-5.0.4.RELEASE.jar:na]
    at io.lettuce.core.internal.AbstractInvocationHandler.invoke(AbstractInvocationHandler.java:80) ~[lettuce-core-5.0.4.RELEASE.jar:na]
    at com.sun.proxy.$Proxy44.set(Unknown Source) ~[na:na]
    at org.springframework.data.red

Breakpoints can be seen through the node ip / port cluster is accurate, but can not connect out of a prompt abnormal 127.0.0.1:7001, the cause of this problem occurs mainly when we create redis clusters, cluster nodes use settings such as the following command

redis/src/redis-cli --cluster create 127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002

Created by redis clusters above this way, and there is no problem, but in the integration springbot's, acquired by redis cluster node information is 127.0.0.1:7000... then lead to the above problem, so a solution is to create a cluster of time , designated under the ip

First of all data and configuration, and then re-established cluster relations

# 删除数据配置
rm xxx/data/*

redis/src/redis-cli  --cluster create 192.168.0.203:7000 192.168.0.203:7001 192.168.0.203:7002

Ok then tested again

3. jedis Configuration

In front of the default configuration will be used as a redis letttuce bridge tool, if we want to use the underlying jedis, how you can operate?

First add jedis depend in pom dependencies

<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
</dependency>

yml configuration file does not substantially change are ok, in the actual project, the connection pool is slightly changed a bit, does not affect the reading, not posted here

Next is the definition RedisConnectionFactoyto replace the default

The following configuration and previous blog post Jedis configuration 181101-SpringBoot advanced version of Redis of almost all the same, to note that we use RedisClusterConfigurationto replace theRedisStandaloneConfiguration

@Configuration
public class RedisAutoConfig {

    @Bean
    public RedisConnectionFactory redisConnectionFactory(JedisPoolConfig jedisPool,
            RedisClusterConfiguration jedisConfig) {
        JedisConnectionFactory factory = new JedisConnectionFactory(jedisConfig, jedisPool);
        factory.afterPropertiesSet();
        return factory;
    }

    @Configuration
    public static class JedisConf {
        @Value("${spring.redis.cluster.nodes:127.0.0.1:7000,127.0.0.1:7001,127.0.0.1:7002}")
        private String nodes;
        @Value("${spring.redis.cluster.max-redirects:3}")
        private Integer maxRedirects;
        @Value("${spring.redis.password:}")
        private String password;
        @Value("${spring.redis.database:0}")
        private Integer database;

        @Value("${spring.redis.jedis.pool.max-active:8}")
        private Integer maxActive;
        @Value("${spring.redis.jedis.pool.max-idle:8}")
        private Integer maxIdle;
        @Value("${spring.redis.jedis.pool.max-wait:-1}")
        private Long maxWait;
        @Value("${spring.redis.jedis.pool.min-idle:0}")
        private Integer minIdle;

        @Bean
        public JedisPoolConfig jedisPool() {
            JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
            jedisPoolConfig.setMaxIdle(maxIdle);
            jedisPoolConfig.setMaxWaitMillis(maxWait);
            jedisPoolConfig.setMaxTotal(maxActive);
            jedisPoolConfig.setMinIdle(minIdle);
            return jedisPoolConfig;
        }

        @Bean
        public RedisClusterConfiguration jedisConfig() {
            RedisClusterConfiguration config = new RedisClusterConfiguration();

            String[] sub = nodes.split(",");
            List<RedisNode> nodeList = new ArrayList<>(sub.length);
            String[] tmp;
            for (String s : sub) {
                tmp = s.split(":");
                // fixme 先不考虑异常配置的case
                nodeList.add(new RedisNode(tmp[0], Integer.valueOf(tmp[1])));
            }

            config.setClusterNodes(nodeList);
            config.setMaxRedirects(maxRedirects);
            config.setPassword(RedisPassword.of(password));
            return config;
        }
    }
}

Then the other is still, at this time the underlying connection RedisTemplate becomes Jedis

III. Other

Project Scope & Related Bowen

Bowen association

1. A gray Blog

Believe everything the book is not as good, above, is purely one of the words, due to limited personal capacity, it is inevitable omissions and mistakes, such as find a bug or have better suggestions are welcome criticism and generous gratitude

Here a gray personal blog, recording all study and work in the blog, welcome to go around

一灰灰blog

Guess you like

Origin www.cnblogs.com/yihuihui/p/11604501.html