(莴苣)readonly您不能针对只读从机进行编写

jfgube3f  于 2021-06-10  发布在  Redis
关注(0)|答案(1)|浏览(521)

我需要一些帮助,我们的服务使用莴苣5.1.6版本,总共部署了22个docker节点。
每当部署服务时,多个docker节点都会出现错误:readonly您不能针对只读从属服务器进行写入。
重新启动有问题的docker节点错误不再出现
redis服务器配置:
8主8从
停止写入bgsave错误否
从服务器过时数据是
从属只读是
群集已启用是
集群配置文件“/data/server/redis cluster/{port}/conf/node.conf”
莴苣配置:

ClientResources res = DefaultClientResources.builder()
        .commandLatencyPublisherOptions(
                DefaultEventPublisherOptions.builder()
                        .eventEmitInterval(Duration.ofSeconds(5))
                        .build()
        )
        .build();
redisClusterClient = RedisClusterClient.create(res, REDIS_CLUSTER_URI);
redisClusterClient.setOptions(
        ClusterClientOptions.builder()
                .maxRedirects(99)
                .socketOptions(SocketOptions.builder().keepAlive(true).build())
                .topologyRefreshOptions(
                        ClusterTopologyRefreshOptions.builder()
                                .enableAllAdaptiveRefreshTriggers()
                                .build())
                .build());
RedisAdvancedClusterCommands<String, String> command = redisClusterClient.connect().sync();
command.setex("some key", 18000, "some value");

出现的异常:

io.lettuce.core.RedisCommandExecutionException: READONLY You can't write against a read only slave.
    at io.lettuce.core.ExceptionFactory.createExecutionException(ExceptionFactory.java:135)
    at io.lettuce.core.LettuceFutures.awaitOrCancel(LettuceFutures.java:122)
    at io.lettuce.core.cluster.ClusterFutureSyncInvocationHandler.handleInvocation(ClusterFutureSyncInvocationHandler.java:123)
    at io.lettuce.core.internal.AbstractInvocationHandler.invoke(AbstractInvocationHandler.java:80)
    at com.sun.proxy.$Proxy135.setex(Unknown Source)
    at com.xueqiu.infra.redis4.RedisClusterImpl.lambda$setex$164(RedisClusterImpl.java:1489)
    at com.xueqiu.infra.redis4.RedisClusterImpl$$Lambda$1422/1017847781.apply(Unknown Source)
    at com.xueqiu.infra.redis4.RedisClusterImpl.execute(RedisClusterImpl.java:526)
    at com.xueqiu.infra.redis4.RedisClusterImpl.executeTotal(RedisClusterImpl.java:491)
    at com.xueqiu.infra.redis4.RedisClusterImpl.setex(RedisClusterImpl.java:1489)
jv2fixgn

jv2fixgn1#

面对分布式中间件,客户端会在客户端放置一些分区、分片等关系进行管理。
redis cluster的slotMap管理:
所采用的方法是使用一个slotcache数组,以数组的形式在本地缓存每个slot对应的节点。
当有密钥需要读写到服务器时,通过客户端的crc16计算出时隙,然后在缓存中获取节点。
redis集群服务器进行集群管理时,在每个节点的local node.conf中记录slot与节点的Map关系。
当乒乓球数据通过gossip协议交换时,这些元数据信息被广播以形成最终一致的元数据信息。
但是,如果服务器端的插槽Map关系中存在错误,客户端将使用这些错误的数据。
这次问题出现在这里。服务器部分节点将插槽Map到从属节点,这样客户端缓存的插槽Map到从属节点,读写请求被发送到从属节点,从而导致错误。

相关问题