#Как получить доступ к экземпляру Sentinel
В этом руководстве показано, как устанавливать соединения с экземплярами Redis Sentinel с использованием стандартных клиентских библиотек. Примеры охватывают детали конфигурации для go-redis, Jedis, Lettuce и Redisson. Для дополнительных вариантов клиентов обратитесь к разделу Connect with Redis client API libraries.
#Содержание
Требования к аутентификацииСправочник по конечным точкам подключенияВнутренний доступ в кластереДля внешнего доступа к кластеруИнтерактивная отладкаПримеры интеграции клиентов#Требования к аутентификации
Экземпляры Redis Sentinel поддерживают следующие варианты аутентификации:
- Аутентификация по паролю: при настройке пароля все клиентские подключения должны предоставлять действительные учетные данные
- Доступ без пароля: если опция Set Password отключена при создании экземпляра, клиенты могут подключаться без аутентификации
Для производственных сред настоятельно рекомендуется использовать аутентификацию по паролю для защиты ваших данных. Подробные инструкции по настройке и управлению безопасными учетными данными см. в разделе User Management.
#Справочник по конечным точкам подключения
#Внутренний доступ в кластере
Для приложений, развернутых в том же Kubernetes-кластере, доступны внутренние конечные точки через вкладку Access Method в разделе Access within the Cluster.
| Параметр | Описание |
|---|---|
| Connection Address | Имя сервиса Kubernetes и комбинации портов для Redis Sentinel. |
#Для внешнего доступа к кластеру
Для приложений, подключающихся из внешней среды Kubernetes, доступны внешние конечные точки, если они были настроены при создании экземпляра. Эти конечные точки можно найти во вкладке Access Method в разделе Access from outside the Cluster.
| Параметр | Описание |
|---|---|
| Sentinel Node Access Address | Внешние IP-адреса и порты подов sentinel в Redis Sentinel, обеспечивающие подключение из внешней сети Kubernetes. |
#Интерактивная отладка
На странице сведений об экземпляре нажмите Terminal Console в правом верхнем углу и используйте команду redis-cli для подключения к каждому узлу Redis.
redis-cli -h <internal-routing-ip> -p 6379Ниже приведён пример сеанса отладки. Пример отладки с демонстрацией команд set/get:
192.168.0.10:6379> set a 1
OK
192.168.0.10:6379> get a
"1"
192.168.0.10:6379>#Примеры интеграции клиентов
Ниже приведены примеры лучших практик подключения к экземплярам Redis Sentinel с использованием различных клиентских библиотек.
Примечание: имя мастер-слейв кластера, зарегистрированное в режиме Sentinel, фиксировано как
mymaster.
package main
import (
"context"
"fmt"
"time"
// Рекомендуется периодически обновлять клиент до последней версии для получения последних исправлений ошибок.
"github.com/redis/go-redis/v9"
)
func main() {
client := redis.NewFailoverClient(&redis.FailoverOptions{
SentinelAddrs: []string{"<address>"},
MasterName: "mymaster",
Password: "<password>",
OnConnect: func(ctx context.Context, conn *redis.Conn) error {
ctx, cancel := context.WithTimeout(ctx, 500*time.Millisecond)
defer cancel()
return conn.Ping(ctx).Err()
},
// Имя клиента для идентификации и отслеживания
ClientName: "go-demo",
// Использование Context для контроля таймаута
ContextTimeoutEnabled: true,
// Максимальное количество повторных попыток
MaxRetries: 3,
// Минимальное время ожидания между повторными попытками
MinRetryBackoff: 20 * time.Millisecond,
// Максимальное время ожидания между повторными попытками
MaxRetryBackoff: 200 * time.Millisecond,
// Таймаут подключения
DialTimeout: 3 * time.Second,
// Таймаут чтения
ReadTimeout: 5 * time.Second,
// Таймаут записи
WriteTimeout: 10 * time.Second,
// Размер пула соединений для каждого узла
PoolSize: 100,
// Максимальное время ожидания доступных соединений в пуле
PoolTimeout: time.Second,
// Минимальное количество простаивающих соединений для каждого узла
MinIdleConns: 5,
// Максимальное количество простаивающих соединений для каждого узла
MaxIdleConns: 10,
// Максимальное количество активных соединений для каждого узла
MaxActiveConns: 100,
// Максимальное время простоя соединений
ConnMaxIdleTime: time.Minute * 5,
})
defer client.Close()
if val, err := client.Get(context.TODO(), "test").Result(); err != nil {
panic(err)
} else {
fmt.Println(val)
}
}Для более подробной конфигурации смотрите community documentation.
package io.alauda.demo.redis;
// Рекомендуется периодически обновлять клиент до последней версии для получения последних исправлений ошибок.
import redis.clients.jedis.DefaultJedisClientConfig;
import redis.clients.jedis.JedisSentinelPool;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.HostAndPort;
import java.time.Duration;
import java.util.Set;
import java.util.HashSet;
public class Main {
public static void main(String []args) {
JedisPoolConfig poolConfig = new JedisPoolConfig();
// Установить максимальный размер пула соединений, -1 означает неограниченно. Если текущее количество соединений превысит это значение, новые подключения будут отклонены.
poolConfig.setMaxTotal(200);
// Установить максимальное количество простаивающих соединений; простаивающие соединения сверх этого числа будут немедленно освобождены.
poolConfig.setMaxIdle(10);
// Установить минимальное количество простаивающих соединений; если количество упадет ниже этого, будут созданы новые простаивающие соединения.
poolConfig.setMinIdle(3);
// Максимальное время ожидания для бизнес-логики, когда нет доступных соединений и достигнут максимум соединений.
poolConfig.setMaxWait(Duration.ofSeconds(1));
// Проверять соединение с помощью ping при взятии из пула.
poolConfig.setTestOnBorrow(true);
// Проверять простаивающие соединения, находить и освобождать недействительные соединения; эта настройка действует только если timeBetweenEvictionRunsMillis больше 1 мс.
poolConfig.setTestWhileIdle(true);
// Установить минимальное время простоя для соединений; соединения старше этого времени будут освобождены; -1 означает не освобождать, действует только если timeBetweenEvictionRunsMillis больше 0. Значение по умолчанию 30 мин.
poolConfig.setMinEvictableIdleDuration(Duration.ofMinutes(5));
// Количество соединений, проверяемых при каждой проверке простаивающих соединений; -n означает 1/n от общего числа.
poolConfig.setNumTestsPerEvictionRun(-1);
// Интервал между проверками; -1 означает отключено.
poolConfig.setTimeBetweenEvictionRuns(Duration.ofMinutes(1));
DefaultJedisClientConfig clientConfig = DefaultJedisClientConfig.builder()
// Имя клиента для отладки и отслеживания источника подключения.
.clientName("demo-jedis")
// Таймаут TCP подключения
.connectionTimeoutMillis(2000)
// Таймаут команды
.timeoutMillis(10000)
.password("<password>")
.build();
DefaultJedisClientConfig sentinelConfig = DefaultJedisClientConfig.builder()
.connectionTimeoutMillis(2000)
.timeoutMillis(10000)
.build();
Set<HostAndPort> nodes = new HashSet<>();
nodes.add(new HostAndPort("<ip1>", <port1>));
nodes.add(new HostAndPort("<ip2>", <port2>));
JedisSentinelPool pool = new JedisSentinelPool("mymaster", nodes, poolConfig, clientConfig, sentinelConfig);
try {
try (Jedis jedis = pool.getResource()) {
String val = jedis.get("test");
System.out.printf("%s", val);
}
} catch (Exception e) {
e.printStackTrace();
}
pool.close();
}
}Для более подробной конфигурации смотрите community documentation.
package io.alauda.demo.redis;
// Рекомендуется периодически обновлять клиент до последней версии для получения последних исправлений ошибок.
import io.lettuce.core.*;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.support.ConnectionPoolSupport;
import org.apache.commons.pool2.impl.GenericObjectPool;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import java.time.Duration;
import java.util.List;
public class Main {
public static void main(String[] args) {
RedisURI.Builder redisUriBuilder = RedisURI.builder();
redisUriBuilder.withSentinel(RedisURI.create("<ip1>", <port1>));
redisUriBuilder.withSentinel(RedisURI.create("<ip2>", <port2>));
redisUriBuilder.withPassword("<password>");
// Имя клиента для отладки и отслеживания источника подключения.
redisUriBuilder.withClientName("demo-lettuce");
redisUriBuilder.withSentinelMasterId("mymaster");
// Установить таймаут подключения клиента
redisUriBuilder.withTimeout(Duration.ofSeconds(2));
RedisURI redisUri = redisUriBuilder.build();
// Конфигурация SocketOptions
SocketOptions socketOptions = SocketOptions.builder()
// Установить таймаут подключения
.connectTimeout(Duration.ofSeconds(10))
.tcpNoDelay(true)
// Включить TCP keepalive для быстрого обнаружения разорванных соединений
// Это значение не строго необходимо для запросов не типа pub/sub; подключение можно поддерживать своевременным освобождением простаивающих соединений.
.keepAlive(true)
.build();
ClientOptions clientOptions = ClientOptions.builder()
.socketOptions(socketOptions)
// Автоматическое переподключение
.autoReconnect(true)
// Настроить поведение клиента при разрыве соединения
// DEFAULT - при autoReconnect = true оставшиеся команды не будут отклонены; иначе команды будут отклонены
.disconnectedBehavior(ClientOptions.DisconnectedBehavior.DEFAULT)
.build();
RedisClient redisClient = RedisClient.create(redisUri);
redisClient.setOptions(clientOptions);
// Конфигурация пула
GenericObjectPoolConfig<StatefulRedisConnection<String, String>> poolConfig = new GenericObjectPoolConfig<>();
// Размер пула соединений не должен быть слишком большим, иначе это может привести к излишнему расходу ресурсов сервера или даже исчерпанию числа соединений, что приведет к сбоям проверки состояния экземпляра.
// Оцените вашу бизнес-конкурентность; рекомендуемый уровень конкуренции — 1.2-1.5 от масштаба вашего бизнеса.
poolConfig.setMaxTotal(200);
// Минимальное количество простаивающих соединений для ускорения ответа бизнес-логики.
poolConfig.setMinIdle(3);
// Максимальное количество простаивающих соединений; простаивающие соединения сверх этого числа будут немедленно освобождены.
poolConfig.setMaxIdle(10);
// Установить минимальное время простоя для соединений; соединения старше этого времени будут освобождены; -1 означает не освобождать; действует только если timeBetweenEvictionRunsMillis больше 0. Значение по умолчанию 30 мин.
poolConfig.setMinEvictableIdleDuration(Duration.ofMinutes(5));
// Количество соединений, проверяемых при каждой проверке простаивающих соединений; -n означает 1/n от общего числа.
poolConfig.setNumTestsPerEvictionRun(3);
// Интервал между проверками; -1 означает отключено.
poolConfig.setTimeBetweenEvictionRuns(Duration.ofMinutes(1));
// Максимальное время ожидания для бизнес-логики, когда нет доступных соединений и достигнут максимум соединений.
poolConfig.setMaxWait(Duration.ofSeconds(1));
// Проверять соединение с помощью ping при взятии из пула.
poolConfig.setTestOnBorrow(true);
// Проверять простаивающие соединения, находить и освобождать недействительные соединения; эта настройка действует только если timeBetweenEvictionRunsMillis больше 1 мс.
poolConfig.setTestWhileIdle(true);
GenericObjectPool<StatefulRedisConnection<String, String>> pool = ConnectionPoolSupport.createGenericObjectPool(redisClient::connect, poolConfig);
try {
try (StatefulRedisConnection<String, String> connection = pool.borrowObject()) {
String val = connection.sync().get("test");
System.out.printf("%s", val);
}
} catch (Exception e) {
e.printStackTrace();
}
pool.close();
}
}Для более подробной конфигурации смотрите community documentation.
package io.alauda.demo.redis;
// Рекомендуется периодически обновлять клиент до последней версии для получения последних исправлений ошибок.
import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import java.util.List;
import java.util.ArrayList;
public class Main {
public static void main(String[] args) {
List<String> nodes = new ArrayList<>();
nodes.add("redis://<ip1>:<port1>");
nodes.add("redis://<ip2>:<port2>");
Config config = new Config();
config.setNettyThreads(64)
.useSentinelServers()
.addSentinelAddress(nodes.toArray(new String[0]))
.setPassword("<password>")
.setMasterName("mymaster")
// Включить обнаружение узлов sentinel.
.setSentinelsDiscovery(true)
// Проверять соединение каждые 30 с на доступность.
// Если KeepAlive включен, это значение можно увеличить.
.setPingConnectionInterval(30000)
// Интервал сканирования топологии кластера.
.setScanInterval(2000)
// Таймаут подключения.
.setConnectTimeout(10000)
// Таймаут команды.
.setTimeout(10000)
// Таймаут простаивающего соединения, установлен в 60 с, чтобы избежать слишком короткого значения по умолчанию.
.setIdleConnectionTimeout(60000)
// Размер пула соединений, не должен быть слишком большим, чтобы избежать излишнего расхода ресурсов сервера или исчерпания числа соединений, что приведет к сбоям проверки состояния экземпляра.
// Оцените вашу бизнес-конкурентность; рекомендуемый уровень конкуренции — 1.2-1.5 от масштаба вашего бизнеса.
.setMasterConnectionPoolSize(200)
// Минимальное количество простаивающих соединений для ускорения ответа бизнес-логики.
.setMasterConnectionMinimumIdleSize(3)
// Количество повторных попыток для неудачных команд.
.setRetryAttempts(3)
// Интервал повторных попыток для неудачных команд.
.setRetryInterval(1500)
// Включить механизм TCP KeepAlive для быстрого обнаружения разорванных соединений.
.setKeepAlive(true)
// Включить TCP no delay.
.setTcpNoDelay(true)
// Имя клиента для отладки и отслеживания источника подключения.
.setClientName("demo-redisson");
RedissonClient redissonClient = Redisson.create(config);
System.out.printf("%s", redissonClient.getBucket("test").get().toString());
redissonClient.shutdown();
}
}Для более подробной конфигурации смотрите community documentation.