Grande número de conexões (Valkey e Redis OSS)
Caches de tecnologia sem servidor e nós individuais do ElastiCache (Redis OSS) dão suporte a até 65 mil conexões de cliente simultâneas. No entanto, para otimizar o desempenho, recomendamos que as aplicações cliente não funcionem de maneira constante nesse nível de conexões. O Valkey e o Redis OSS têm um processo de thread único baseado em um loop de eventos no qual as solicitações de cliente recebidas são processadas sequencialmente. Isso significa que o tempo de resposta de um determinado cliente aumenta à medida que o número de clientes conectados aumenta.
É possível realizar o seguinte conjunto de ações para evitar um gargalo de conexões em um servidor Valkey ou Redis OSS:
Realize operações de leitura a partir das réplicas de leitura. Isso pode ser feito usando-se os endpoints de leitor do ElastiCache em modo cluster desabilitado ou usando réplicas para leituras em modo de cluster habilitado, inclusive um cache sem servidor.
Distribua tráfego de gravação em vários nós primários. É possível fazer isso de duas maneiras. É possível usar um cluster multifragmentado do Valkey ou Redis OSS com um cliente compatível com o modo cluster. Também é possível gravar em vários nós primários em modo de cluster desabilitado com fragmentação do lado do cliente. Isso é feito automaticamente em um cache sem servidor.
Use um pool de conexões quando disponível na biblioteca cliente.
Em geral, criar uma conexão TCP é uma operação cara em termos computacionais em comparação com os comandos típicos do Valkey ou Redis OSS. Por exemplo, lidar com uma solicitação SET/GET é uma ordem de magnitude mais rápida ao reutilizar uma conexão existente. O uso de um pool de conexões de clientes com um tamanho finito reduz a sobrecarga do gerenciamento de conexões. Isso também limita o número de conexões de entrada simultâneas da aplicação cliente.
O seguinte exemplo de código do PHPRedis mostra que uma nova conexão é criada para cada nova solicitação do usuário:
$redis = new Redis(); if ($redis->connect($HOST, $PORT) != TRUE) { //ERROR: connection failed return; } $redis->set($key, $value); unset($redis); $redis = NULL;
Comparamos esse código em um loop em uma instância do Amazon Elastic Compute Cloud (Amazon EC2) conectada a um nó Graviton2 (m6g.2xlarge) do ElastiCache (Redis OSS). Colocamos o cliente e o servidor na mesma zona de disponibilidade. A latência média de toda a operação foi de 2,82 milissegundos.
Quando atualizamos o código e usamos conexões persistentes e um pool de conexões, a latência média de toda a operação foi de 0,21 milissegundo:
$redis = new Redis(); if ($redis->pconnect($HOST, $PORT) != TRUE) { // ERROR: connection failed return; } $redis->set($key, $value); unset($redis); $redis = NULL;
Configurações de redis.ini necessárias:
redis.pconnect.pooling_enabled=1
redis.pconnect.connection_limit=10
O seguinte código é um exemplo de um pool de conexões do Redis-py
conn = Redis(connection_pool=redis.BlockingConnectionPool(host=HOST, max_connections=10)) conn.set(key, value)
O seguinte código é um exemplo de um pool de conexões do Lettuce
RedisClient client = RedisClient.create(RedisURI.create(HOST, PORT)); GenericObjectPool<StatefulRedisConnection> pool = ConnectionPoolSupport.createGenericObjectPool(() -> client.connect(), new GenericObjectPoolConfig()); pool.setMaxTotal(10); // Configure max connections to 10 try (StatefulRedisConnection connection = pool.borrowObject()) { RedisCommands syncCommands = connection.sync(); syncCommands.set(key, value); }