Você adora ler sobre como vários problemas relacionados ao desempenho são rastreados e corrigidos? Em caso afirmativo, aqui está nossa história de como corrigimos os problemas de desempenho do Redis que estávamos enfrentando otimizando o JedisPool. Esperamos que isso o ajude a fortalecer seu ambiente de TI.
Nossos problemas de desempenho do Redis e esforços para encontrar a causa
Um pico no tempo de resposta
O Site24x7 usa estruturas de dados na memória do Redis para reduzir os acessos aos nossos bancos de dados de back-end. Começamos a encontrar picos ocasionais no tempo de resposta do nosso aplicativo. Após investigação, descobrimos que as chamadas de cache do Redis estavam falhando e os servlets começaram a atingir o banco de dados, o que levou a um aumento no tempo de resposta geral do aplicativo. Isso aconteceu aleatoriamente por alguns segundos, depois o aplicativo voltou ao normal com zero falhas do Redis.
Redis BigKeys
Como nosso tráfego para o Redis era quase constante ao longo do dia, descartamos problemas relacionados ao dimensionamento. Em seguida, começamos a monitorar os parâmetros da máquina Redis e descobrimos que sempre que havia uma queda nas conexões Redis, observamos um alerta de CPU alto. Conseguimos então correlacionar o alto uso da CPU com as falhas do Redis, mas o motivo do alto uso da CPU permaneceu um mistério.
Nossas suspeitas apontavam para as BigKeys e comandos com uso intensivo de CPU, como a chave SMEMBERS. A linha de comando do Redis fornece uma opção para verificar as BigKeys (redis-cli –bigkeys) e visualizar a lista de BigKeys com base nos tipos de dados. Como próxima etapa para corrigir o problema, excluímos as BigKeys maiores que 1 MB. Também tentamos usar o Redis Slow Log para listar todos os comandos que poderiam tornar o sistema lento, mas não havia comandos com uso intensivo de CPU listados.
![](https://site24x7.acsoftware.com.br/wp-content/uploads/2022/05/image-1.png)
Conexões Jedis
Neste momento, ficamos um pouco confusos, pois não conseguimos encontrar BigKeys ou comandos lentos no Slow Log, mas ainda observamos picos de CPU e conexões perdidas. Como a criação de novas conexões é uma operação de E/S intensiva, começamos a observar o padrão de novas conexões. Para nossa surpresa, descobrimos que o número de conexões criadas por segundo era igual ao número de comandos executados. Ficamos surpresos com essa revelação porque já estávamos usando o JedisPool, uma coleção de conexões Jedis reutilizáveis, para reutilizar as conexões e não havíamos alterado nossa configuração do JedisPool.
Após pesquisas adicionais, descobrimos que o JedisPool oferece muitas opções para definir a configuração com base nas necessidades do aplicativo. Mas estávamos usando a configuração padrão. Isso funcionou bem quando tínhamos menos servidores de aplicativos. À medida que ampliamos os servidores de aplicativos, a configuração padrão resultou no uso ineficiente do JedisPool.
O que é Jedi?
Jedis é uma das bibliotecas de cliente Java mais usadas para Redis e também um dos clientes recomendados na lista oficial de clientes Redis.
Conexões maxIdle baixas
Por padrão, os valores maxPoolSize e maxIdle relacionados a JedisPool são 8. À medida que nosso produto crescia, precisávamos de mais conexões, então aumentamos maxPoolSize para 150 enquanto maxIdle permaneceu inalterado. Portanto, com essa configuração, o JedisPool pode criar no máximo 150 conexões a qualquer momento. Ainda assim, ele só poderia manter 8 conexões ociosas no pool por vez, e as conexões restantes foram descartadas.
Isso anulou o propósito de usar o JedisPool, pois novas conexões eram criadas a cada segundo. Isso ocorreu em todos os servidores de aplicativos. A criação de conexões aumentou o uso da CPU do Redis, o que, por sua vez, resultou na eliminação das conexões do Redis. Como todos os dedos apontavam para o alto uso de CPU em clusters Redis devido a um alto número de conexões ao Redis por segundo como o principal motivo, nos concentramos na otimização do JedisPool, que pode ser feita ajustando a configuração do JedisPool.
Configuração do JedisPool
A configuração do JedisPool é baseada no GenericObjectPoolConfig do Apache Commons Pool 2. Ao definir o parâmetro GenericObjectPoolConfig para um valor específico, você poderá melhorar o desempenho do Redis. A amostra a seguir mostra como inicializar e usar o JedisPool:
![](https://site24x7.acsoftware.com.br/wp-content/uploads/2022/05/image-2.png)
Definir parâmetros adequados para JedisPoolConfig é crucial, pois isso determina como uma nova conexão será criada.
Otimização JedisPool através do ajuste de parâmetros críticos
Ajustar os parâmetros do pool de conexões com base na carga e em outros fatores relacionados ao ambiente é a melhor maneira de obter melhor desempenho e resolver problemas de desempenho. Aqui estão alguns dos parâmetros cruciais que tentamos ajustar:
maxTotal
O parâmetro maxTotal especifica o número máximo de conexões que podem ser criadas a partir do pool a qualquer momento. Como as instâncias Jedis são de thread único, essa configuração afetará as solicitações simultâneas entre seu aplicativo e o Redis.
O valor padrão é 8, que provavelmente é muito baixo para um aplicativo pesado. Por outro lado, definir um valor alto para esse parâmetro levará à sobrecarga da CPU e da memória. É crucial descobrir o valor maxTotal adequado ao seu ambiente. Aqui estão algumas dicas importantes a serem consideradas ao identificar seu valor maxTotal ideal:
- Determine o número esperado de conexões simultâneas com o Redis.
- Concentre-se em um tempo de resposta médio para executar um comando Redis.
- Defina o número máximo de conexões suportadas por um servidor Redis.
Por padrão, a versão 2.6 do servidor Redis oferece suporte a 10.000 conexões de cliente. O produto do número de instâncias do aplicativo e maxTotal deve sempre ser menor que o número máximo de conexões suportadas pelo Redis.
Vamos considerar o seguinte exemplo:
- Máximo de conexões de cliente suportadas por um servidor Redis = 10.000
- Tempo médio de resposta de uma consulta Redis = 2 ms
- Número esperado de consultas por segundo (QPS) por instância do Redis = 30.000
O número de consultas Redis tratadas por uma única instância Jedis por segundo é calculado dividindo um segundo pelo tempo de resposta, que neste cenário = 500 (1.000 ms / 2 ms = 500).
O maxTotal necessário é calculado dividindo o QPS esperado pelo número de consultas tratadas por uma única instância Jedis por segundo. Assim, maxTotal = 60 (30.000 / 500).
Este é um valor teórico. Você pode usar uma ferramenta de monitoramento como o APM Insight para obter as métricas mencionadas acima. É bom reservar algumas conexões extras para uma carga imprevisível.
É melhor ter em mente que o número total de conexões reservadas em todas as instâncias não deve exceder o número máximo de conexões suportadas pelo Redis. Por exemplo, se você tiver 100 instâncias, o número total de conexões seria 6.000 (100 * 60), que é menor que 10.000. Considerando que, se você tiver 200 instâncias, o total seria de 12.000 conexões, o que pode fazer com que seus comandos falhem.
maxIdle
O parâmetro maxIdle especifica o número máximo de instâncias Jedis ociosas que serão mantidas no pool sem serem despejadas dele. Este é o número real de conexões exigidas pelo aplicativo. O valor maxTotal inclui o número total de maxIdle mais a conexão excedente necessária para uma carga imprevisível.
Se o valor de maxIdle for muito pequeno para seu aplicativo, novas conexões Jedis serão criadas com frequência para atender às solicitações. Criar novas conexões com frequência aumentará o uso da CPU do cluster Redis e afetará negativamente o aplicativo. Se o valor for muito grande para seu aplicativo, as conexões reservadas serão desperdiçadas e outras instâncias do aplicativo poderão não obter recursos suficientes para se comunicar com o Redis.
Ao definir maxIdle com um valor adequado, você pode garantir que maxTotal obtenha o melhor desempenho na maioria dos cenários, pois nenhuma nova conexão será criada quando o tamanho do pool atingir maxIdle.
minIdle
O parâmetro minIdle especifica o número mínimo de conexões inativas que sempre serão mantidas no pool. O valor padrão é zero, o que significa que todas as conexões que estiverem ociosas por um período maior que minEvictableIdleTimeMillis serão despejadas do pool.
Assim, quando a carga aumenta, muitas novas conexões serão criadas, o que pode afetar o desempenho do aplicativo. Podemos evitar isso definindo um valor minIdle mais alto dependendo da carga. Para aplicações com carga flutuante, um mínimo de (maxIdle / 2) deve ser definido, podendo ir até maxIdle.
bloquear quando esgotado
Essa configuração booleana especifica se o cliente deve aguardar uma conexão livre quando o pool estiver esgotado. O valor padrão é verdadeiro. Somente quando o valor blockWhenExhausted for verdadeiro o parâmetro maxWaitMillis será efetivo.
maxWaitMillis
Este parâmetro especifica o tempo máximo que o cliente deve esperar quando nenhuma conexão estiver disponível. Depois disso, uma mensagem de erro de exceção dizendo “Não foi possível obter o recurso do pool” será exibida. Essa configuração terá efeito somente quando blockWhenExhausted for definido como true. O valor padrão é -1 ms, o que significa que ele aguardará indefinidamente pela conexão do pool. Recomendamos definir o mesmo valor do tempo limite da conexão Jedis.
minEvictableIdleTimeMillis
Este parâmetro especifica a quantidade mínima de tempo que uma conexão pode ficar inativa antes do despejo. O valor padrão é 60 segundos, adequado para a maioria dos aplicativos. Você pode alterar esse valor com base em seu ambiente e carga.
Os valores fornecidos aqui são adequados para a maioria das aplicações. No entanto, é melhor monitorar o uso real e decidir os valores para esses parâmetros. Você pode depender de qualquer uma das ferramentas de monitoramento gratuitas disponíveis no mercado, como Site24x7 , ou registrar o uso do JedisPool periodicamente para entender a carga e determinar os valores adequados.
Espero que nossas sugestões sejam úteis para você. Adoraríamos ouvir seus comentários. Por favor, assista a este espaço para mais blogs e dicas dos engenheiros do Site24x7.
Você pode experimentar o Site24x7 dentro da sua empresa sem custo algum. Que tal realizar esse teste agora?
Conheça na prática como o Site24x7 pode ajudar você e o seu negócio. Nossos técnicos estão disponíveis para te apresentar a melhor solução de monitoramento em nuvem para sua infraestrutura, conte sempre com o apoio da equipe ACSoftware.
ACSoftware / Figo Software seu Distribuidor e Revenda ManageEngine no Brasil
Fone (11) 4063 1007 – Vendas (11) 4063 9639