加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

【原创】SpringBoot2默认RedisCluster配置的坑

(2020-04-30 15:41:05)
标签:

springboot2

redis

cluster

集群

分类: redis
背景:
      SpringBoot2的应用,连接redis 集群,application.yml配置如下:
 redis:
    cluster:
      nodes: 192.168.x.x:7101,192.168.x.x:7102,192.168.x.x:7103,1192.168.x.x:7101,192.168.x.x:7102,......
  max-redirects: 30
    password: xxxx
    timeout: 15s
    lettuce:
      pool:
        max-active: 50
        max-idle: 10
        min-idle: 3

   redis的版本为:5.0.3 ,6主6从
192.168.x.x:7001 (3ec8ae28...) -> 119943618 keys | 2731 slots | 1 slaves.
192.168.x.x:7006 (64dfc290...) -> 119828403 keys | 2731 slots | 1 slaves.
192.168.x.x:7003 (4b4701bd...) -> 117518202 keys | 2730 slots | 1 slaves.
192.168.x.x:7004 (018d6328...) -> 117563400 keys | 2730 slots | 1 slaves.
192.168.x.x:7005 (94c3a6c8...) -> 119839657 keys | 2731 slots | 1 slaves.
192.168.x.x:7002 (921179ca...) -> 120069963 keys | 2731 slots | 1 slaves.
[OK] 714763243 keys in 6 masters.
43625.69 keys per slot on average.

问题现象:
      redis5.0.3本身好象有bug,当发生主节点coredump时,cluster集群自动完成主备节点的切换,此时SpringBoot2开发的应用无法继续操作redis,不停地报错。

问题原因:
      SpringBoot2默认配置时,redis连接池用的是Lettuce的连接工厂,默认情况下,没有起用拓扑刷新,当redis集群发生主备切换时,集群的拓扑已经发生改变,Lettuce连接工厂连的还是还是原来的主用节点,肯定报异常

解决办法:
      用代码的方式,自定义连接工厂,起用拓扑刷新功能,以使发生主备切换是,自动刷新拓扑
    public static LettucePoolingClientConfiguration getLettuceClusterPoolingConfig(Integer maxActive, Integer maxIdle, Integer minIdle, Duration timeout){
        GenericObjectPoolConfig genericObjectPoolConfig=getGenericObjectPoolConfig(maxActive, maxIdle, minIdle);
        ClusterTopologyRefreshOptions clusterTopologyRefreshOptions = ClusterTopologyRefreshOptions.builder()
                .enableAllAdaptiveRefreshTriggers()
                .adaptiveRefreshTriggersTimeout(Duration.ofSeconds(30))
                .build();
        ClusterClientOptions clusterClientOptions = ClusterClientOptions.builder().validateClusterNodeMembership(false)
                .topologyRefreshOptions(clusterTopologyRefreshOptions).build();
        LettucePoolingClientConfiguration poolingClientConfiguration=LettucePoolingClientConfiguration.builder()
                .poolConfig(genericObjectPoolConfig)
                .clientOptions(clusterClientOptions)
                .commandTimeout(timeout)
                .build();
        return poolingClientConfiguration;
    }
    public static RedisConnectionFactory getLettuceClusterConnectionFactory(List nodes, String password,
                                                                            Integer maxActive, Integer maxIdle, Integer minIdle, Duration timeout){
        LettucePoolingClientConfiguration clientConfiguration=getLettuceClusterPoolingConfig(maxActive,maxIdle,minIdle,timeout);
        RedisClusterConfiguration redisClusterConfiguration = new RedisClusterConfiguration(nodes);
        redisClusterConfiguration.setPassword(RedisPassword.of(password));
        return new LettuceConnectionFactory(redisClusterConfiguration,clientConfiguration);
    }

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有