RedisTemplateConfig sentinel(哨兵模式)/ cluster(集群模式) 常用配置 以及如何 一键配置切换

本文涉及的产品
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
简介: RedisTemplateConfig sentinel(哨兵模式)/ cluster(集群模式) 常用配置 以及如何 一键配置切换

紧接着上文 《redisTemplete config sentinel(哨兵)模式 常用配置》


开发中经常会遇到一个场景,同样一套代码,对不同客户时也许客户要求的redis集群不一样,向我们面对银行A客户时他们要求只能用他们现有的哨兵集群,但面对另一个银行客户B时又只能用cluster集群 ,所以基于最小改动原则,尽量让代码保持不变,通过配置文件修改一个属性达到目的。


本文主要来说一下如何在代码中同时存在sentinel 哨兵模式,以及cluster 模式配置,并且可以通过配置文件(例如nacos, apollo,application.yml application.properties 等)达到一键式切换

package cn.goswan.orient.gateway.config;
import io.lettuce.core.ReadFrom;
import io.lettuce.core.cluster.ClusterClientOptions;
import io.lettuce.core.cluster.ClusterTopologyRefreshOptions;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
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.RedisSentinelConfiguration;
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 org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
/**
 * RedisTemplate  config配置
 *
 * @author alan.wang
 */
// @EnableCaching TODO
@Configuration
@AllArgsConstructor
@AutoConfigureBefore(RedisAutoConfiguration.class)
@Slf4j
public class RedisTemplateConfig {
  @Bean
  public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
    RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
    redisTemplate.setKeySerializer(new StringRedisSerializer());
    redisTemplate.setHashKeySerializer(new StringRedisSerializer());
    redisTemplate.setValueSerializer(new JdkSerializationRedisSerializer());
    redisTemplate.setHashValueSerializer(new JdkSerializationRedisSerializer());
    redisTemplate.setConnectionFactory(redisConnectionFactory);
    return redisTemplate;
  }
  @Bean
  public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
    StringRedisTemplate stringRedisTemplate = new StringRedisTemplate();
    stringRedisTemplate.setKeySerializer(new StringRedisSerializer());
    stringRedisTemplate.setConnectionFactory(redisConnectionFactory);
    return stringRedisTemplate;
  }
  @Autowired
  RedisProperties redisProperties;
  @Bean
  public GenericObjectPoolConfig poolConfig() {
    GenericObjectPoolConfig config = new GenericObjectPoolConfig();
    config.setMinIdle(redisProperties.getLettuce().getPool().getMinIdle());
    config.setMaxIdle(redisProperties.getLettuce().getPool().getMaxIdle());
    config.setMaxTotal(redisProperties.getLettuce().getPool().getMaxActive());
    config.setMaxWaitMillis(redisProperties.getLettuce().getPool().getMaxWait().toMillis());
    return config;
  }
  @Bean
  @ConditionalOnProperty(value = "spring.redis.mode",havingValue = "sentinel")
  public RedisSentinelConfiguration redisSentinelConfiguration() {
    RedisSentinelConfiguration redisConfig = new RedisSentinelConfiguration();
    redisConfig.setMaster(redisProperties.getSentinel().getMaster());
    if(redisProperties.getSentinel().getNodes()!=null) {
      List<RedisNode> sentinelNode=new ArrayList<RedisNode>();
      for(String sen : redisProperties.getSentinel().getNodes()) {
        String[] arr = sen.split(":");
        sentinelNode.add(new RedisNode(arr[0],Integer.parseInt(arr[1])));
      }
      redisConfig.setDatabase(redisProperties.getDatabase());
      redisConfig.setPassword(redisProperties.getPassword());
      redisConfig.setSentinelPassword(redisConfig.getPassword());
      redisConfig.setSentinels(sentinelNode);
    }
    return redisConfig;
  }
  @Bean
  @ConditionalOnProperty(value = "spring.redis.mode",havingValue = "sentinel")
  public RedisConnectionFactory redisConnectionFactory(@Qualifier("poolConfig") GenericObjectPoolConfig config,
                             RedisSentinelConfiguration redisConfig) {//注意传入的对象名和类型RedisSentinelConfiguration
    LettuceClientConfiguration clientConfiguration = LettucePoolingClientConfiguration.builder().poolConfig(config).build();
    return new LettuceConnectionFactory(redisConfig, clientConfiguration);
  }
  @Bean
  @ConditionalOnProperty(value = "spring.redis.mode",havingValue = "cluster")
  public RedisClusterConfiguration redisClusterConfiguration() {
    RedisClusterConfiguration redisClusterConfiguration = new RedisClusterConfiguration(redisProperties.getCluster().getNodes());
    redisClusterConfiguration.setPassword(redisProperties.getPassword());
    return redisClusterConfiguration;
  }
  @Bean
  @ConditionalOnProperty(value = "spring.redis.mode",havingValue = "cluster")
  public RedisConnectionFactory redisConnectionFactory(RedisClusterConfiguration redisClusterConfiguration) {
    ClusterTopologyRefreshOptions clusterTopologyRefreshOptions = ClusterTopologyRefreshOptions.builder()
        .enablePeriodicRefresh()
        .enableAllAdaptiveRefreshTriggers()
        .refreshPeriod(Duration.ofSeconds(5))
        .build();
    ClusterClientOptions clusterClientOptions = ClusterClientOptions.builder()
        .topologyRefreshOptions(clusterTopologyRefreshOptions).build();
    LettuceClientConfiguration lettuceClientConfiguration = LettuceClientConfiguration.builder()
        .readFrom(ReadFrom.REPLICA_PREFERRED)
        .clientOptions(clusterClientOptions).build();
    return new LettuceConnectionFactory(redisClusterConfiguration, lettuceClientConfiguration);
  }
}

可以看到最重点的配置其实就是


@ConditionalOnProperty 里面的配置可以随便自定义,只要达到能区分就好,这样重启之后就会按照配置生成指定bean并注入,下面是我的配置,我们用的是spring cloud nacos 配置中心

1.png

用其他的配置中心或者配置文件也是一样的

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
2月前
|
监控 API 开发者
Sentinel之道:流控模式解析与深度探讨
Sentinel之道:流控模式解析与深度探讨
54 0
|
2月前
|
编解码 算法 定位技术
GEE时序——利用sentinel-2(哨兵-2)数据进行地表物候学分析(时间序列平滑法估算和非平滑算法代码)
GEE时序——利用sentinel-2(哨兵-2)数据进行地表物候学分析(时间序列平滑法估算和非平滑算法代码)
78 3
|
4月前
|
NoSQL Java Redis
SpringBoot2.0整合Redis高可用之Sentinel哨兵
本篇博文分享的是一主二从三哨兵模式。至于为什么用三个哨兵,同第一段。本文是模拟环境,都是一个服务器上面。
73 0
|
6月前
|
存储 NoSQL Redis
【Redis源码】集群之哨兵sentinel初识(十一)
【Redis源码】集群之哨兵sentinel初识(十一)
53 0
|
2月前
|
存储 编解码 人工智能
GEE数据集——哨兵2号Sentinel-2 云概率数据集
GEE数据集——哨兵2号Sentinel-2 云概率数据集
123 2
|
3月前
|
监控 NoSQL 程序员
Redis 高可用篇:你管这叫 Sentinel 哨兵集群原理
Redis 高可用篇:你管这叫 Sentinel 哨兵集群原理
77 5
|
3月前
|
NoSQL Linux Redis
Redis 6.X Sentinel 哨兵集群搭建
Redis 6.X Sentinel 哨兵集群搭建
32 5
|
3月前
|
Prometheus Cloud Native 调度
Sentinel 新版本发布,提升配置灵活性以及可观测配套
Sentinel 新版本发布,提升配置灵活性以及可观测配套
|
4月前
|
定位技术
哨兵2号Sentinel-2分幅条带介绍与MGRS网格矢量文件获取
哨兵2号Sentinel-2分幅条带介绍与MGRS网格矢量文件获取
|
4月前
|
XML 编解码 定位技术
哨兵2号Sentinel-2已经完成大气校正的L2A级遥感影像产品的下载方法
哨兵2号Sentinel-2已经完成大气校正的L2A级遥感影像产品的下载方法
120 0
哨兵2号Sentinel-2已经完成大气校正的L2A级遥感影像产品的下载方法