alibaba / jetcache

JetCache is a Java cache framework.
Apache License 2.0
5.14k stars 1.06k forks source link

非哨兵模式的读写分离如何配置 #251

Closed yezhoujie closed 5 years ago

yezhoujie commented 5 years ago

非哨兵模式的读写分离如何配置, lettuce 文档里只介绍了哨兵模式和集群模式

areyouok commented 5 years ago

你直接设置readFrom属性就好了,具体可以看代码RedisLettuceAutoConfiguration。

你也可以自己构造RedisClient的,不过那样就不能用yml配置了,需要自己写,getting started文档中“未使用SpringBoot的配置方式”的部分有介绍。

yezhoujie commented 5 years ago

你直接设置readFrom属性就好了,具体可以看代码RedisLettuceAutoConfiguration。

你也可以自己构造RedisClient的,不过那样就不能用yml配置了,需要自己写,getting started文档中“未使用SpringBoot的配置方式”的部分有介绍。

我们现在使用的是aws 中的 elastiCache, 由于aws的限制,自动发现的地址无法连接。 问题: 如何替换RedisLettuceAutoConfiguration.java -> initCache 方法中的 StatefulRedisMasterSlaveConnection 为 StaticMasterSlaveConnector

yezhoujie commented 5 years ago

或者支持一下当redis url传入多个时,不要自动判断为哨兵模式, StatefulRedisMasterSlaveConnection c = MasterSlave.connect( (RedisClient) client, new JetCacheCodec(), RedisURI.create(uri)); 第三个参数传入多个uri

areyouok commented 5 years ago

只要设置了readFrom,RedisLettuceAutoConfiguration就会用MasterSlave初始化,你看看MasterSlave的代码,它是自动发现的,你只填master,只要你uri前面的schema不是redis-sentinel就行:

    public static <K, V> StatefulRedisMasterSlaveConnection<K, V> connect(RedisClient redisClient, RedisCodec<K, V> codec,
            RedisURI redisURI) {

        LettuceAssert.notNull(redisClient, "RedisClient must not be null");
        LettuceAssert.notNull(codec, "RedisCodec must not be null");
        LettuceAssert.notNull(redisURI, "RedisURI must not be null");

        if (isSentinel(redisURI)) {
            return connectSentinel(redisClient, codec, redisURI);
        } else {
            return connectMasterSlave(redisClient, codec, redisURI);
        }
    }

我看MasterSlave.connect代码里面传入多个uri,它也只用第一个。

你试试?

yezhoujie commented 5 years ago

只要设置了readFrom,RedisLettuceAutoConfiguration就会用MasterSlave初始化,你看看MasterSlave的代码,它是自动发现的,你只填master,只要你uri前面的schema不是redis-sentinel就行:

    public static <K, V> StatefulRedisMasterSlaveConnection<K, V> connect(RedisClient redisClient, RedisCodec<K, V> codec,
            RedisURI redisURI) {

        LettuceAssert.notNull(redisClient, "RedisClient must not be null");
        LettuceAssert.notNull(codec, "RedisCodec must not be null");
        LettuceAssert.notNull(redisURI, "RedisURI must not be null");

        if (isSentinel(redisURI)) {
            return connectSentinel(redisClient, codec, redisURI);
        } else {
            return connectMasterSlave(redisClient, codec, redisURI);
        }
    }

我看MasterSlave.connect代码里面传入多个uri,它也只用第一个。

你试试?

AWS 比较奇怪,我设置了readFrom, 确实走了自动发现,但是发现的slaver 地址都是172开头的,也就是说,发现出来的地址是master, slaver 之间的内网地址,我们的服务是没法connect 到 这几个发现的地址的

所以,按照lettuce的官方文档

Example 3. AWS ElastiCache Cluster
RedisClient redisClient = RedisClient.create();

List<RedisURI> nodes = Arrays.asList(RedisURI.create("redis://host1"),
        RedisURI.create("redis://host2"),
        RedisURI.create("redis://host3"));

StatefulRedisMasterSlaveConnection<String, String> connection = MasterSlave
        .connect(redisClient, new Utf8StringCodec(), nodes);
connection.setReadFrom(ReadFrom.MASTER_PREFERRED);

System.out.println("Connected to Redis");

connection.close();
redisClient.shutdown();

应该这样创建StatefulRedisMasterSlaveConnection

或者 使用 StaticMasterSlaveConnector 替换 StatefulRedisMasterSlaveConnection。

areyouok commented 5 years ago

我之前好像看错了,我看看怎么改

areyouok commented 5 years ago

我改好了,你用最新的master代码(master代码是稳定的),自己打包snapshot,然后这样写:

    default:
      type: redis.lettuce
      keyConvertor: fastjson
      readFrom: slavePreferred
      mode: MasterSlave
      uri:
        - redis://127.0.0.1:6379
        - redis://127.0.0.1:6380
        - redis://127.0.0.1:6381
      keyPrefix: lettuceTest2_salve2