Spring boot is compatible with both stand-alone and cluster configurations. I won't say it to ordinary people

Keywords: Database Redis Spring Boot

preface

Most web development data are stored in the database, but with the increase of data, our interface will be very slow. At this time, we will introduce redis to cache data that will not change frequently, so as to achieve the effect of fast data response

stand-alone

In spring, redis is introduced to configure the link factory of redis. In spring boot, we only need to simply configure the serialization of redisTemplate and cache factory in the configuration class.

@Bean
@Primary
public RedisTemplate<Object, Object> redisTemplate() throws CommonException {
   RedisTemplate template = new RedisTemplate();
   template.setConnectionFactory(getRedisConnectionFactory());
   // Use Jackson2JsonRedisSerializer to serialize and deserialize the value of redis (the JDK serialization method is used by default)
   Jackson2JsonRedisSerializer serializer = new Jackson2JsonRedisSerializer(Object.class);
   ObjectMapper mapper = new ObjectMapper();
   mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
   mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
   mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
   mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
   serializer.setObjectMapper(mapper);
   // shiro uses the jdk by default, so this serialization uses the default jdk to facilitate shirosession processing
   template.setValueSerializer(serializer);
   // Use StringRedisSerializer to serialize and deserialize the key value of redis
   template.setKeySerializer(serializer);
   //template.setValueSerializer(serializer);
   template.setHashKeySerializer(serializer);
   template.setHashValueSerializer(serializer);
   template.afterPropertiesSet();
   return template;
}
​
@Bean
public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory factory) {
   StringRedisTemplate stringRedisTemplate = new StringRedisTemplate();
   stringRedisTemplate.setConnectionFactory(factory);
   return stringRedisTemplate;
}

colony

However, with the deepening of the project, problems will still appear. The biggest problem with a single machine is that if the redis service goes down due to an accident, our programs will also be involved, resulting in the direct unavailability of our services.

Based on this situation, redis cluster came into being. The advantage of clustering is that we don't need to worry about service downtime. We should deploy separate services for each node. One of them goes down, and the others will resume election and data disaster recovery operations. For our users, there is no need to worry about downtime.

There are also data. There are master nodes and slave nodes in the redis cluster. The master node is responsible for writing data and the slave node is responsible for synchronizing data. Data synchronization within the cluster allows us to avoid data loss.

In stand-alone configuration, we can find that we need RedisConnectionFactory factory when configuring RedisTemplate. The factory is not configured above, mainly because we need to transform it in the cluster. Therefore, it is configured together in the cluster chapter.

For factory configuration, we mainly configure JedisConnectionFactory. Point source code, we can see a method

public JedisConnectionFactory(RedisClusterConfiguration clusterConfig) {
    this((RedisClusterConfiguration)clusterConfig, (JedisClientConfiguration)(new JedisConnectionFactory.MutableJedisClientConfiguration()));
}

Therefore, we only need to construct RedisClusterConfiguration object for cluster configuration. If it is a single machine, we use the parameterless construction

@Bean
public JedisConnectionFactory getRedisConnectionFactory() throws CommonException {
   JedisConnectionFactory connectionFactory = null;
   if (connectionFactory == null && redisProperties != null && redisProperties.getHost() != null) {
      // stand-alone
      connectionFactory = new JedisConnectionFactory();
   }
   if (connectionFactory == null && redisProperties != null && redisProperties.getCluster().getNodes() != null) {
      // colony
      connectionFactory = new JedisConnectionFactory(getClusterConfig());
   }
   if (null == connectionFactory) {
      throw new CommonException("Unable to initialize redis Connection pool");
   }
   try {
      connectionFactory.setUsePool(true);
      JedisPoolConfig config = getJedisPoolConfig();
      connectionFactory.setPoolConfig(config);
      connectionFactory.setHostName(redisProperties.getHost());
      connectionFactory.setPort(redisProperties.getPort());
      connectionFactory.setDatabase(redisProperties.getDatabase());
      connectionFactory.setPassword(redisProperties.getPassword());
   } catch (Exception e) {
      logger.error("redis connection factory init failed");
   }
   return connectionFactory;
}

summary

redis cluster greatly improves the availability and high availability of our project. Let's learn about the data synchronization principle and election mechanism within the cluster sometime

Author: don't give up when you should have worked hard
Link: https://juejin.cn/post/7018476112464314405
Source: rare earth Nuggets

Posted by tymlls05 on Wed, 13 Oct 2021 06:40:54 -0700