Redisson + redis sentinel. как обрабатывать отказоустойчивость и писать в Redis?

Я только что отредактировал свой предыдущий вопрос и предоставляю более подробную информацию (надеюсь, кто-нибудь сможет помочь).

У меня есть кластер Redis с 1 мастером и 2 подчиненными. Все 3 узла управляются Sentinel. Отработка отказа работает нормально, и когда новый мастер выбран, я могу писать на новом мастере (из командной строки). Теперь я пытаюсь написать небольшую программу на Java с использованием Redisson, которая в идеале должна записывать записи в redis и иметь возможность обрабатывать отказоустойчивость (что она должна делать, насколько я понял). Это мой код до сих пор.

import org.redisson.Redisson;
import org.redisson.RedissonNode;
import org.redisson.api.*;
import org.redisson.api.annotation.RInject;
import org.redisson.config.Config;
import org.redisson.config.RedissonNodeConfig;
import org.redisson.config.SubscriptionMode;
import java.util.Collections;
import java.util.UUID;


public class RedissonTest {

    public static class RunnableTask implements Runnable {
        @RInject
        RedissonClient client;

        @Override
        public void run(){
            System.out.println("I am in ..");
            RMap<String, String> map = client.getMap("completeNewMap");
            System.out.println("is thread interrupted?? " + Thread.currentThread().isInterrupted());

            NodesGroup ngroup = client.getNodesGroup();
            Collection<Node> nodes = ngroup.getNodes();
            for(Node node : nodes){
                System.out.println("Node ip "+ node.getAddr().toString()+" type: "+node.getType().toString());
            }

            for(int i=0; i < 10000; i++) {
                String key = "bg_key_"+String.valueOf(i);
                String value = String.valueOf(UUID.randomUUID());
                String oldVal = map.get(key);
                map.put(key, value);

                RBucket<String> bck = client.getBucket(key);

                bck.set(value);

                System.out.println("I am going to replace the old value " + oldVal + " with new value " + value + " at key "+key);

            }
            System.out.println("I am outta here!!");
        }
    }

    public static void main(String[] args) {
        Config config = new Config();
        config.useSentinelServers()
                .setMasterName("redis-cluster")
                .addSentinelAddress("192.168.56.101:26379")
                .addSentinelAddress("192.168.56.102:26379")
                .addSentinelAddress("192.168.56.103:26379")
                .setPingTimeout(100)
                .setTimeout(60000)
                .setRetryAttempts(25)
                .setReconnectionTimeout(45000)
                .setRetryInterval(1500)
                .setReadMode(ReadMode.SLAVE)
                .setConnectTimeout(20000)
                .setSubscriptionMode(SubscriptionMode.MASTER);

        RedissonClient client = Redisson.create(config);

        RedissonNodeConfig nodeConfig = new RedissonNodeConfig(config);
        nodeConfig.setExecutorServiceWorkers(Collections.singletonMap("myExecutor6", 1));
        RedissonNode node = RedissonNode.create(nodeConfig);
        node.start();

        System.out.println("Node address "+node.getRemoteAddress().toString());
        RExecutorService e = client.getExecutorService("myExecutor6");
        e.execute(new RunnableTask());
        e.shutdown();
        if(e.isShutdown()) {
            e.delete();
        }
        client.shutdown();
        node.shutdown();
        System.out.println("Hello World!" );
    }

}

При запуске кода происходит пара вещей, которых я не понимаю. Первый:

  • почему Redisson распознает мои 3 хоста как Redis Slave ??
  • почему пары ключ-значение, которые я создал, не сохраняются в Redis ??

Идея состоит в том, что после того, как я смогу писать в Redis, я начал бы тестировать аварийное переключение, убивая мастер и ожидая, что программа будет управлять им и продолжит писать на новый мастер, не теряя сообщения (было бы неплохо чтобы иметь возможность кэшировать сообщения во время аварийного переключения).

Что происходит с этой простой программой, так это то, что я могу писать в redis, но когда я убиваю мастер, выполнение просто зависает на время, близкое к setTimeout, и завершается без завершения задачи.

Любое предложение?


person Gioachino Bartolotta    schedule 16.05.2018    source источник


Ответы (1)


Вы должны установить параметр retryAttempts достаточно большим, чтобы Redisson пережил период переключения при отказе.

person Nikita Koksharov    schedule 28.05.2018
comment
Спасибо за помощь. Как видите, я пробовал и модифицировал свой источник. Но независимо от того, насколько велико значение retryAttempts, setReconnectionTimeout или setRetryInterval ... всякий раз, когда я останавливаю Redis ... он зависает и завершается. Я, наверное, что-то не так делаю .. - person Gioachino Bartolotta; 29.05.2018
comment
вы нашли решение? - person Guardian; 07.09.2020