Как вызвать кластер Redis с помощью testContainers в JavaJAVA

Программисты JAVA общаются здесь
Ответить
Anonymous
 Как вызвать кластер Redis с помощью testContainers в Java

Сообщение Anonymous »

Я пытаюсь создать кластер Redis с помощью TestContainers для тестирования моего приложения, которое зависит от кластера Redis. Вот что я пробовал до сих пор:
Фрагмент кода для запуска контейнера:
Network network = Network.newNetwork();
RedisContainer redisContainer = new RedisContainer(DockerImageName.parse("redis:7.0.5"))
.withExposedPorts(port)
.withCommand("redis-server --port " + port +
" --requirepass " + redisPassword + // Password for clients
" --masterauth " + redisPassword + // Password for inter-node communication
" --cluster-enabled yes" +
" --cluster-config-file nodes.conf"+
" --cluster-node-timeout 5000"+
" --appendonly yes" +
" --bind 0.0.0.0" )
.withNetwork(network)
.withNetworkMode("bridge")
.withNetworkAliases("redis-" + i)
.waitingFor(Wait.forListeningPort());

1. Кластер с одним узлом
Я попытался создать кластер с одним узлом, для которого для параметра «Включение кластера» установлено значение «Да», а для параметра «Реплика» установлено значение 0. Я попытался подключиться к нему с помощью JedisCluster.
Проблемы и исправления:
Первоначально я получал сообщение об ошибке: Слоты кластера не выделены. Я решил эту проблему, выполнив команду CLUSTER ADDSLOTS для выделения диапазона слотов.
После этого я запустил команду CLUSTER NODES и получил следующий результат:
1f2673c5fdb45ca16d564658ff88f815db5cbf01 172.29.0.2:6379@16379 myself,master - 0 0 1 connected 0-16383

Однако, когда я попытался подключиться к кластеру с помощью JedisCluster, соединение было установлено, я смог получить список узлов с IP-адресом и портом, используя API jedisCluster.getClusterNodes(). Когда я попытался написать какую-то пару ключ-значение, через несколько секунд возникла ошибка ниже.
redis.clients.jedis.exceptions.JedisClusterOperationException: Cluster retry deadline exceeded.
Как ни странно, запуск команд через redis-cli отлично работал как для записи, так и для чтения данных.
Вывод информации о кластере:
cluster_state:ok
cluster_slots_assigned:16384
cluster_slots_ok:16384
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:1
cluster_size:1
cluster_current_epoch:1
cluster_my_epoch:1
cluster_stats_messages_pong_sent:1
cluster_stats_messages_meet_sent:1
cluster_stats_messages_sent:2
cluster_stats_messages_pong_received:1
cluster_stats_messages_meet_received:1
cluster_stats_messages_received:2
total_cluster_links_buffer_limit_exceeded:0

Вывод слотов кластера:
1) 1) (integer) 0
2) (integer) 16383
3) 1) "172.29.0.2"
2) (integer) 6379
3) "b47f7da9be31ce953d4b4fbf9e3a737d1c9b7a58"
4) (empty array)

2. Многоузловой кластер
Я также попробовал настроить кластер из 6 узлов (3 главных и 3 подчиненных).
Наблюдения:
JedisCluster.getClusterNodes() вернул правильную информацию об узлах для всех трех главных узлов (IP и порт).
Однако, когда я попытался записать данные в кластер с помощью JedisCluster, я получил следующее ошибка:
redis.clients.jedis.exceptions.JedisClusterOperationException: Cluster retry deadline exceeded.

Когда я использовал redis-cli -c для записи данных, он зависал в сообщении «Перенаправление в слот [], расположенном в node».
Возможная проблема
Я пытаюсь вызвать Redis в контейнере с помощью модуля TestContainer. Я подозреваю, что узлы в кластере не могут должным образом взаимодействовать друг с другом. В случае кластера с одним узлом некоторая конфигурация может отсутствовать. Некоторые
Любая помощь в решении этой проблемы будет принята с благодарностью. Спасибо!
Изменить:
Код конфигурации JedisCluster:
// Using redisContainer in above code snippet start the container and run to add slots and continue with below code

GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();
poolConfig.setMaxTotal(Runtime.getRuntime().availableProcessors());
poolConfig.setMaxIdle(Runtime.getRuntime().availableProcessors());
poolConfig.setMinIdle(Runtime.getRuntime().availableProcessors());
poolConfig.setMaxWaitMillis(2000);

// Connect to the cluster using Jedis with a password
DefaultJedisClientConfig.Builder jedisClientConfig = DefaultJedisClientConfig.builder()
.password(redisPassword)
.ssl(false)
.connectionTimeoutMillis(10000)
.socketTimeoutMillis(4000);

final Set hosts = new HashSet(redisContainers.size());
int i = 0;
for(RedisContainer redisContainer : redisContainers){
String redisHost = "127.0.0.1";
int redisPort = redisContainer.getMappedPort(basePort+i);
hosts.add(new HostAndPort(redisHost, redisPort));
i += 1;
}

System.out.println("Hosts " + hosts);

try (JedisCluster jedis = new JedisCluster(hosts, jedisClientConfig.build(), 3, poolConfig)) {
Map nodes = jedis.getClusterNodes();
System.out.println("Connected cluster nodes: " + nodes);
nodes.forEach((key, value) -> System.out.println(key));
jedis.set("key", "value"); // This is where the error is seen
System.out.println("Key set in Redis Cluster: " + jedis.get("key"));
}
```


Подробнее здесь: https://stackoverflow.com/questions/793 ... rs-in-java
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «JAVA»