Problemas de conexão persistentes - Amazon ElastiCache

As traduções são geradas por tradução automática. Em caso de conflito entre o conteúdo da tradução e da versão original em inglês, a versão em inglês prevalecerá.

Problemas de conexão persistentes

Os seguintes itens devem ser verificados ao solucionar problemas persistentes de conectividade com o ElastiCache:

Grupos de segurança

Os grupos de segurança são firewalls virtuais que protegem o cliente do ElastiCache (instância do EC2, função AWS Lambda, contêiner do Amazon ECS etc.) e cache do ElastiCache. Os grupos de segurança têm estado, o que significa que depois que o tráfego de entrada ou saída é permitido, as respostas para esse tráfego serão automaticamente autorizadas no contexto desse grupo de segurança específico.

O recurso stateful (com estado) requer que o grupo de segurança mantenha o controle de todas as conexões autorizadas e há um limite para conexões controladas. Se o limite for atingido, as novas conexões apresentarão falha. Consulte a seção de solução de problemas para obter ajuda sobre como identificar se os limites foram atingidos do lado do cliente ou do ElastiCache.

Você pode ter um único grupo de segurança atribuído ao mesmo tempo ao cliente e ao cluster do ElastiCache, ou grupos de segurança individuais para cada um.

Em ambos os casos, você precisa permitir o tráfego de saída TCP na porta do ElastiCache da origem e o tráfego de entrada na mesma porta para o ElastiCache. A porta padrão é 11211 para Memcached e 6379 para Valkey ou Redis OSS. Por padrão, os grupos de segurança permitem todo o tráfego de saída. Nesse caso, somente a regra de entrada no grupo de segurança de destino é necessária.

Para obter mais informações, consulte Padrões de acesso para acessar um cluster do ElastiCache em uma Amazon VPC.

Network ACLs

As listas de controle de acesso à rede (ACLs) são regras sem estado. O tráfego deve ser permitido em ambas as direções (entrada e saída) para ter êxito. As ACLs de rede são atribuídas a sub-redes, não a recursos específicos. É possível ter a mesma ACL atribuída ao ElastiCache e ao recurso do cliente, especialmente se eles estiverem na mesma sub-rede.

Por padrão, as ACLs de rede permitem todo o tráfego. No entanto, é possível personalizá-las para negar ou permitir tráfego. Além disso, a avaliação das regras da ACL é sequencial, o que significa que a regra com o menor número correspondente ao tráfego irá permiti-lo ou negá-lo. A configuração mínima para permitir o tráfego Valkey ou Redis OSS é:

ACL de rede do lado do cliente:

  • Regras de entrada:

  • Número da regra: preferencialmente inferior a qualquer regra de negação;

  • Type: Custom TCP Rule;

  • Protocolo: TCP

  • Port Range: 1024-65535

  • Source: 0.0.0.0/0 (ou criar regras individuais para as sub-redes do cluster do ElastiCache)

  • Allow/Deny: Allow

  • Regras de saída:

  • Número da regra: preferencialmente inferior a qualquer regra de negação;

  • Type: Custom TCP Rule;

  • Protocolo: TCP

  • Port Range: 6379

  • Source 0.0.0.0/0 (ou as sub-redes do cluster do ElastiCache. Tenha em mente que o uso de IPs específicos pode criar problemas em caso de failover ou escalabilidade do cluster)

  • Allow/Deny: Allow

ACL de rede do ElastiCache:

  • Regras de entrada:

  • Número da regra: preferencialmente inferior a qualquer regra de negação;

  • Type: Custom TCP Rule;

  • Protocolo: TCP

  • Port Range: 6379

  • Source: 0.0.0.0/0 (ou criar regras individuais para as sub-redes do cluster do ElastiCache)

  • Allow/Deny: Allow

  • Regras de saída:

  • Número da regra: preferencialmente inferior a qualquer regra de negação;

  • Type: Custom TCP Rule;

  • Protocolo: TCP

  • Port Range: 1024-65535

  • Source 0.0.0.0/0 (ou as sub-redes do cluster do ElastiCache. Tenha em mente que o uso de IPs específicos pode criar problemas em caso de failover ou escalabilidade do cluster)

  • Allow/Deny: Allow

Para obter mais informações, consulte ACLs de rede.

Tabelas de rotas

Da mesma forma que as ACLs de rede, cada sub-rede pode ter tabelas de rota diferentes. Se os clientes e o cluster do ElastiCache estiverem em sub-redes diferentes, certifique-se de que suas tabelas de rota permitam que eles cheguem uns aos outros.

Ambientes mais complexos, envolvendo várias VPCs, roteamento dinâmico ou firewalls de rede, podem se tornar difíceis para a solução de problemas. Consulte Validação da conectividade de rede para confirmar se as configurações de rede são apropriadas.

Resolução do DNS

O ElastiCache fornece os endpoints de serviço com base em nomes do DNS. Os endpoints disponíveis são os endpoints Configuration, Primary, Reader, e Node. Para obter mais informações, consulte Encontrar endpoints de conexão.

Em caso de failover ou modificação de cluster, o endereço associado ao nome do endpoint pode mudar e será atualizado automaticamente.

Configurações de DNS personalizadas (ou seja, não usando o serviço de DNS da VPC) podem não estar cientes dos nomes de DNS fornecidos pelo ElastiCache. Certifique-se de que seu sistema possa resolver com êxito os endpoints do ElastiCache usando ferramentas do sistema como o dig (como mostrado a seguir) ou o nslookup.

$ dig +short example.xxxxxx.ng.0001.use1.cache.amazonaws.com example-001.xxxxxx.0001.use1.cache.amazonaws.com. 1.2.3.4

Você também pode forçar a resolução de nomes por meio do serviço de DNS da VPC:

$ dig +short example.xxxxxx.ng.0001.use1.cache.amazonaws.com @169.254.169.253 example-001.tihewd.0001.use1.cache.amazonaws.com. 1.2.3.4

Identificação de problemas com o diagnóstico do lado do servidor

As métricas do CloudWatch e as informações de tempo de execução do mecanismo ElastiCache são fontes ou informações comuns para identificar potenciais fontes de problemas de conexão. Uma boa análise geralmente começa com os seguintes itens:

  • Uso da CPU: Valkey e Redis OSS são aplicativos multithread. No entanto, a execução de cada comando ocorre em um único thread (principal). Por esse motivo, o ElastiCache fornece as métricas CPUUtilization e EngineCPUUtilization. EngineCPUUtilization fornece a utilização da CPU dedicada ao processo do Valkey ou Redis OSS, e CPUUtilization, o uso em todas as vCPUs. Os nós com mais de uma vCPU geralmente têm valores diferentes para CPUUtilization e EngineCPUUtilization, sendo o segundo comumente maior. Um EngineCPUUtilization alto pode ser causado por um número elevado de solicitações ou operações complexas que levem uma quantidade significativa de tempo da CPU para ser concluída. Você pode identificar ambos com o seguinte:

    • Número elevado de solicitações: verifique se há aumentos em outras métricas que correspondam ao padrão EngineCPUUtilization. As métricas úteis são:

      • CacheHits e CacheMisses: o número de solicitações ou solicitações bem-sucedidas que não encontraram um item válido no cache. Se a proporção de erros em comparação com acertos for alta, a aplicação está desperdiçando tempo e recursos com solicitações infrutíferas.

      • SetTypeCmds e GetTypeCmds:eEssas métricas correlacionadas com EngineCPUUtilization podem ajudar a entender se a carga é significativamente maior para solicitações de gravação, medida por SetTypeCmds, ou leituras, medido por GetTypeCmds. Se a carga for predominantemente de leituras, o uso de várias réplicas de leitura pode equilibrar as solicitações em vários nós e poupar o primário para gravações. Em clusters com modo cluster desabilitado, o uso de réplicas de leitura pode ser feito criando uma configuração de conexão adicional na aplicação usando o endpoint leitor do ElastiCache. Para obter mais informações, consulte Encontrar endpoints de conexão. As operações de leitura devem ser enviadas para essa conexão adicional. As operações de gravação serão feitas através do endpoint primário regular. No modo cluster habilitado, é aconselhável usar uma biblioteca com suporte a réplicas de leitura nativamente. Com os sinalizadores certos, a biblioteca será capaz de descobrir automaticamente a topologia do cluster, os nós de réplica, habilitar as operações de leitura através do comando READONLY do Valkey Redis OSS e enviar as solicitações de leitura para as réplicas.

    • Número elevado de conexões:

      • CurrConnections e NewConnections: CurrConnection é o número de conexões estabelecidas no momento da coleta de pontos de dados, enquanto NewConnections mostra quantas conexões foram criadas no período.

        Criar e manipular conexões implica em sobrecarga significativa da CPU. Além disso, o handshake de três vias de TCP necessário para criar novas conexões afetará negativamente os tempos de resposta gerais.

        Um nó do ElastiCache com milhares de NewConnections por minuto indica que uma conexão é criada e usada por apenas alguns comandos, o que não é ideal. Manter as conexões estabelecidas e reutilizá-las para novas operações é uma prática recomendada. Isso é possível quando a aplicação cliente oferece suporte e implementa corretamente o grupo de conexões ou as conexões persistentes. Com o grupo de conexões, o número de currConnections não tem grandes variações, e o NewConnections deve ser o mais baixo possível. Valkey e Redis OSS oferecem desempenho ideal com um pequeno número de currConnections. Manter currConnection na ordem de dezenas ou centenas minimiza o uso de recursos para suportar conexões individuais, como buffers de cliente e ciclos de CPU para servir a conexão.

    • Throughput da rede

      • Determine a largura de banda: os nós do ElastiCache têm largura de banda proporcional ao tamanho do nó. Como as aplicações têm características diferentes, os resultados podem variar de acordo com a workload. Como exemplos, aplicações com alta taxa de pequenas solicitações tendem a afetar mais o uso da CPU do que o throughput da rede, enquanto chaves maiores causarão maior utilização da rede. Por esse motivo, é aconselhável testar os nós com a workload real para uma melhor compreensão dos limites.

        A simulação da carga da aplicação forneceria resultados mais precisos. No entanto, as ferramentas de benchmark podem dar uma boa ideia dos limites.

      • Para casos em que as solicitações são predominantemente leituras, o uso de réplicas para operações de leitura aliviará a carga no nó primário. Se o caso de uso for predominantemente gravações, o uso de muitas réplicas amplificará o uso da rede. Para cada byte gravado no nó primário, N bytes serão enviados para as réplicas, sendo N o número de réplicas. A prática recomendada para workloads intensas de gravação é usar o ElastiCache para Redis OSS com modo cluster habilitado para que as gravações possam ser balanceadas em vários fragmentos ou haver aumento de escala vertical para um tipo de nó com mais recursos de rede.

      • As métricas NetworkBytesIn e NetworkBytesOut do Cloudwatch fornecem a quantidade de dados que entram ou saem do nó, respectivamente. ReplicationBytes é o tráfego dedicado à replicação de dados.

      Para obter mais informações, consulte Limites relacionados à rede.

    • Comandos complexos: os comandos do Redis OSS são servidos em um único thread, o que significa que as solicitações são atendidas sequencialmente. Um único comando lento pode afetar outras solicitações e conexões, culminando em tempos limite. O uso de comandos que atuem sobre vários valores, chaves ou tipos de dados deve ser feito com cuidado. As conexões podem ser bloqueadas ou terminadas dependendo do número de parâmetros ou do tamanho de seus valores de entrada ou saída.

      Um exemplo notório é o comando KEYS. Ele varre todo o keyspace procurando por um determinado padrão e bloqueia a execução de outros comandos durante sua execução. O Redis OSS usa a notação "Big O" para descrever sua complexidade de comandos.

      O comando Keys tem complexidade de tempo O(N), sendo N o número de chaves no banco de dados. Portanto, quanto maior o número de chaves, mais lento será o comando. KEYS pode causar problemas de maneiras diferentes: se nenhum padrão de pesquisa for usado, o comando retornará todos os nomes de chaves disponíveis. Em bancos de dados com milhares ou milhões de itens, uma enorme saída será criada e inundará os buffers de rede.

      Se um padrão de pesquisa for usado, somente as chaves correspondentes ao padrão retornarão ao cliente. No entanto, o mecanismo ainda varrerá todo o keyspace procurando por ele, e o tempo para concluir o comando será o mesmo.

      Uma alternativa a KEYS é o comando SCAN. Ele itera sobre o keyspace e limita as iterações em um número específico de itens, evitando bloqueios prolongados no mecanismo.

      A varredura tem o parâmetro COUNT, usado para definir o tamanho dos blocos de iteração. O valor padrão é 10 (10 itens por iteração).

      Dependendo do número de itens no banco de dados, blocos com pequenos valores de COUNT irão exigir mais iterações para concluir uma verificação completa, e valores maiores manterão o mecanismo ocupado por mais tempo em cada iteração. Enquanto pequenos valores de contagem farão SCAN mais lento em grandes bancos de dados, valores maiores podem causar os mesmos problemas mencionados para KEYS.

      Como exemplo, a execução do comando SCAN com valor de contagem de 10 vai requer 100.000 repetições em um banco de dados com 1 milhão de chaves. Se o tempo médio de ida e volta da rede for de 0,5 milissegundos, aproximadamente 50.000 milissegundos (50 segundos) serão gastos transferindo solicitações.

      Por outro lado, se o valor da contagem fosse 100.000, uma única iteração seria necessária e apenas 0,5 ms seriam gastos transferindo-a. No entanto, o mecanismo seria totalmente bloqueado para outras operações até que o comando terminasse de varrer todo o keyspace.

      Além de KEYS, vários outros comandos são potencialmente prejudiciais se não forem usados corretamente. Para ver uma lista de todos os comandos e suas respectivas complexidades de tempo, acesse Comandos Valkey e Redis OSS.

      Exemplos de possíveis problemas:

      • Scripts Lua: o Valkey e Redis OSS fornecem um interpretador Lua incorporado, permitindo a execução de scripts no lado do servidor. Os scripts Lua no Valkey e no Redis OSS são executados no nível do mecanismo e são atômicos por definição, o que significa que nenhum outro comando ou script terá execução permitida enquanto um script estiver em execução. Os scripts Lua fornecem a possibilidade de executar vários comandos, algoritmos de tomada de decisão, análise de dados e outros diretamente no mecanismo. Embora a atomicidade dos scripts e a chance de descarregar a aplicação sejam tentadoras, os scripts devem ser usados com cuidado e para pequenas operações. No ElastiCache, o tempo de execução dos scripts Lua é limitado a 5 segundos. Scripts que não forem gravados no keyspace serão encerrados automaticamente após o período de 5 segundos. Para evitar a corrupção de dados e inconsistências, o nó fará failover se a execução do script não tiver sido concluída em 5 segundos e tiver qualquer gravação durante sua execução. Transações são a alternativa para garantir a consistência de múltiplas modificações de chaves relacionadas no Redis OSS. Uma transação permite a execução de um bloco de comandos, observando as chaves existentes para modificações. Se qualquer uma das chaves observadas mudar antes da conclusão da transação, todas as modificações serão descartadas.

      • Exclusão em massa de itens: o comando DEL aceita vários parâmetros, que são os nomes das chaves a serem excluídas. As operações de exclusão são síncronas e gastarão um tempo significativo da CPU se a lista de parâmetros for grande ou contiver uma grande lista, conjunto, conjunto ordenado ou hash (estruturas de dados contendo vários subitens). Em outras palavras, até mesmo a exclusão de uma única chave pode levar um tempo significativo se tiver muitos elementos. A alternativa a DEL é UNLINK, que é um comando assíncrono disponível desde o Redis OSS 4. UNLINK deve ter preferência sobre DEL sempre que possível. Começando no ElastiCache para Redis OSS 6x, o parâmetro lazyfree-lazy-user-del faz com que o parâmetro DEL se comporte como UNLINK quando habilitado. Para mais informações, consulte Alterações de parâmetro do Redis OSS 6.0.

      • Comandos que atuam sobre várias chaves: DEL foi mencionado anteriormente como um comando que aceita vários argumentos e seu tempo de execução será diretamente proporcional a isso. No entanto, o Redis OSS fornece muitos outros comandos que funcionam de forma semelhante. Como exemplos, MSET e MGET permitem a inserção ou recuperação de várias chaves de string ao mesmo tempo. Seu uso pode ser benéfico para reduzir a latência de rede inerente a vários comandos individuais SET ou GET. No entanto, uma extensa lista de parâmetros afetará o uso da CPU.

        Embora a utilização da CPU por si só não seja a causa de problemas de conectividade, gastar muito tempo para processar um único ou poucos comandos através de várias chaves pode causar falha de outras solicitações e aumentar a utilização geral da CPU.

        O número de chaves e seu tamanho afetarão a complexidade do comando e, consequentemente, o tempo de conclusão.

        Outros exemplos de comandos que podem atuar sobre várias chaves: HMGET, HMSET, MSETNX, PFCOUNT, PFMERGE, SDIFF, SDIFFSTORE, SINTER, SINTERSTORE, SUNION, SUNIONSTORE, TOUCH, ZDIFF, ZDIFFSTORE, ZINTER ou ZINTERSTORE.

      • Comandos atuando sobre vários tipos de dados: o Redis OSS também fornece comandos que atuam em uma ou várias chaves, independentemente do tipo de dados. O ElastiCache para Redis OSS fornece a métrica KeyBasedCmds para monitorar esses comandos. Essa métrica soma a execução dos seguintes comandos no período selecionado:

        • Complexidade de O(N):

          • KEYS

        • O(1)

          • EXISTS

          • OBJECT

          • PTTL

          • RANDOMKEY

          • TTL

          • TYPE

          • EXPIRE

          • EXPIREAT

          • MOVE

          • PERSIST

          • PEXPIRE

          • PEXPIREAT

          • UNLINK (O(N) para recuperar memória. No entanto, a tarefa de recuperação de memória ocorre em um thread separado e não bloqueia o mecanismo

        • Diferentes tempos de complexidade dependendo do tipo de dados:

          • DEL

          • DUMP

          • RENAME é considerado um comando com complexidade O(1), mas executa DEL Internamente. O tempo de execução varia de acordo com o tamanho da chave renomeada.

          • RENAMENX

          • RESTORE

          • SORT

        • Hashes grandes: hash é um tipo de dado que permite uma única chave com vários subitens de valor-chave. Cada hash pode armazenar 4.294.967.295 itens e operações em hashes grandes podem se tornar caras. Da mesma forma que KEYS, hashes têm o comando HKEYS com complexidade de tempo O(N), N sendo o número de itens no hash. HSCAN deve ter preferência sobre HKEYS para evitar comandos de longa execução. HDEL, HGETALL, HMGET, HMSET e HVALS são comandos que devem ser usados com cautela em hashes grandes.

      • Outras estruturas grandes de dados: além de hashes, outras estruturas de dados podem ser intensas em CPU. Conjuntos, listas, conjuntos classificados e HyperLogLogs também podem levar um tempo significativo para serem manipulados, dependendo do tamanho e dos comandos usados. Para obter mais informações sobre esses comandos, consulte Comandos Valkey e Redis OSS.

Validação da conectividade de rede

Depois de analisar as configurações de rede relacionadas à resolução de DNS, grupos de segurança, ACLs de rede e tabelas de rota, a conectividade pode ser validada com o VPC Reachability Analyzer e as ferramentas do sistema.

O Reachability Analyzer testará a conectividade de rede e confirmará se todos os requisitos e permissões estão satisfeitos. Para os testes abaixo, você precisará do ID da ENI (Identificação de interface de rede elástica) de um dos nós do ElastiCache disponíveis em sua VPC. É possível fazer isso da seguinte maneira:

  1. Acesse https://console.aws.amazon.com/ec2/v2/home?#NIC:

  2. Filtre a lista de interfaces pelo nome do cluster do ElastiCache ou pelo endereço IP obtido das validações de DNS anteriormente.

  3. Anote ou salve o ID da ENI. Se várias interfaces forem exibidas, revise a descrição para confirmar que elas pertencem ao cluster correto do ElastiCache e escolha uma delas.

  4. Prossiga para a próxima etapa.

  5. Crie um caminho de análise em https://console.aws.amazon.com/vpc/home?#ReachabilityAnalyzer e escolha as seguintes opções:

    • Source Type (Tipo de origem): escolha Instance (Instância) se seu cliente ElastiCache for executado em uma instância do Amazon EC2, ou Network Interface (Interface de rede) se ele usar outro serviço, como o Amazon ECS AWS Fargate com rede awsvpc, AWS Lambda, etc.), e o respectivo ID de recurso (instância EC2 ou ID da ENI);

    • Destination Type (Tipo de destino): escolha Network Interface (Interface de rede) e selecione a ElastiCache ENI (ENI do ElastiCache) na lista.

    • Destination port (Porta de destino): especifique 6379 para o ElastiCache para Redis OSS ou 11211 para o ElastiCache para Memcached. Essas são as portas definidas com a configuração padrão e este exemplo pressupõe que elas não foram alteradas.

    • Protocolo: TCP

Crie o caminho de análise e aguarde alguns instantes para o resultado. Se o status estiver inacessível, abra os detalhes da análise e revise Analysis Explorer (Explorador da análise) para obter detalhes sobre onde as solicitações foram bloqueadas.

Se os testes de acessibilidade forem aprovados, avance para a verificação no nível do sistema operacional.

Para validar a conectividade de TCP na porta de serviço do ElastiCache: no Amazon Linux, Nping está disponível no pacote nmap e pode testar a conectividade de TCP na porta do ElastiCache, além de fornecer o tempo de ida e volta da rede para estabelecer a conexão. Use isso para validar a conectividade de rede e a latência atual para o cluster do ElastiCache, conforme mostrado a seguir:

$ sudo nping --tcp -p 6379 example.xxxxxx.ng.0001.use1.cache.amazonaws.com Starting Nping 0.6.40 ( http://nmap.org/nping ) at 2020-12-30 16:48 UTC SENT (0.0495s) TCP ... (Output suppressed ) Max rtt: 0.937ms | Min rtt: 0.318ms | Avg rtt: 0.449ms Raw packets sent: 5 (200B) | Rcvd: 5 (220B) | Lost: 0 (0.00%) Nping done: 1 IP address pinged in 4.08 seconds

Por padrão,nping envia 5 testes com um atraso de 1 segundo entre eles. Você pode usar a opção "-c" para aumentar o número de testes e “--delay“ para alterar o tempo de envio de um novo teste.

Se os testes com nping falharem e os testes do VPC Reachability Analyzer forem aprovados, peça ao administrador do sistema para revisar possíveis regras de firewall baseadas em host, regras de roteamento assimétricas ou qualquer outra restrição possível no nível do sistema operacional.

No console do ElastiCache, verifique se Encryption in-transit (Criptografia em trânsito) está habilitada nos detalhes do cluster do ElastiCache. Se a criptografia em trânsito estiver habilitada, confirme se a sessão de TLS pode ser estabelecida com o seguinte comando:

openssl s_client -connect example.xxxxxx.use1.cache.amazonaws.com:6379

Uma saída extensa é esperada se a conexão e a negociação de TLS forem bem-sucedidas. Verifique o código de retorno disponível na última linha, o valor deve ser de 0 (ok). Se o openssl retornar algo diferente, verifique o motivo do erro em https://www.openssl.org/docs/man1.0.2/man1/verify.html#DIAGNOSTICS.

Se todos os testes de infraestrutura e sistema operacional forem aprovados, mas sua aplicação ainda não conseguir se conectar ao ElastiCache, verifique se as configurações da aplicação estão em conformidade com as configurações do ElastiCache. Erros comuns são:

  • Sua aplicação não suporta o modo de cluster do ElastiCache e o ElastiCache tem modo cluster habilitado;

  • Sua aplicação não oferece suporte a TLS/SSL e o ElastiCache possui criptografia em trânsito habilitada;

  • A aplicação suporta TLS/SSL, mas não possui os sinalizadores de configuração corretos ou autoridades de certificação confiáveis;

Limites relacionados à rede

  • Número máximo de conexões: há limites rígidos para conexões simultâneas. Cada nó do ElastiCache permite até 65.000 conexões simultâneas em todos os clientes. Este limite pode ser monitorado através das métricas CurrConnections métricas no CloudWatch. No entanto, os clientes também têm seus limites para conexões de saída. No Linux, verifique o intervalo de portas efêmeras permitido com o comando:

    # sysctl net.ipv4.ip_local_port_range net.ipv4.ip_local_port_range = 32768 60999

    No exemplo anterior, 28231 conexões serão permitidas da mesma origem, para o mesmo IP de destino (nó ElastiCache) e porta. O comando a seguir mostra quantas conexões existem para um nó do ElastiCache específico (IP 1.2.3.4):

    ss --numeric --tcp state connected "dst 1.2.3.4 and dport == 6379" | grep -vE '^State' | wc -l

    Se o número for muito alto, seu sistema pode ficar sobrecarregado tentando processar as solicitações de conexão. É aconselhável considerar a implementação de técnicas como grupo de conexões ou conexões persistentes para lidar melhor com as conexões. Sempre que possível, configure o grupo de conexões para limitar o número máximo de conexões a algumas centenas. Além disso, a lógica de recuo para lidar com tempo limite ou outras exceções de conexão seria aconselhável para evitar rotatividade de conexão em caso de problemas.

  • Limites de tráfego de rede: verifique as seguintes métricas do CloudWatch para o Redis OSS para identificar possíveis limites de rede que estejam sendo atingidos no nó do ElastiCache:

    • NetworkBandwidthInAllowanceExceeded/NetworkBandwidthOutAllowanceExceeded: pacotes de rede modelados porque o throughput excedeu o limite de largura de banda agregada.

      É importante observar que cada byte gravado no nó primário será replicado para N réplicas, sendo N o número de réplicas. Clusters com tipos de nó pequenos, várias réplicas e solicitações de gravação intensiva podem não conseguir lidar com o backlog de replicação. Nesses casos, é uma prática recomendada aumentar a escala vertical (alterar o tipo de nó), aumentar a escala horizontal (adicionar fragmentos em clusters com modo cluster habilitado), reduzir o número de réplicas ou minimizar o número de gravações.

    • NetworkConntrackAllowanceExceeded: pacotes modelados porque o número máximo de conexões monitoradas em todos os grupos de segurança atribuídos ao nó foi excedido. Novas conexões provavelmente falharão durante esse período.

    • NetworkPackets PerSecondAllowanceExceeded: número máximo de pacotes por segundo excedido. Workloads baseadas em uma alta taxa de solicitações muito pequenas podem atingir esse limite antes da largura de banda máxima.

    As métricas acima são a maneira ideal de confirmar que os nós atingem seus limites de rede. No entanto, os limites também são identificáveis por platôs em métricas de rede.

    Se os platôs forem observados por períodos prolongados, eles provavelmente serão seguidos por atraso de replicação, aumento de bytes usados para cache, queda de memória livre, alto swap e uso da CPU. As instâncias do Amazon EC2 também têm limites de rede que podem ser rastreados por meio de Métricas do driver ENA. Instâncias do Linux com suporte de rede aprimorado e drivers ENA 2.2.10 ou mais recentes podem revisar os contadores de limite com o comando:

    # ethtool -S eth0 | grep "allowance_exceeded"

Uso da CPU

A métrica de uso da CPU é o ponto de partida da investigação, e os seguintes itens podem ajudar a reduzir possíveis problemas no lado do ElastiCache:

  • SlowLogs do Redis OSS: a configuração padrão do ElastiCache retém os últimos 128 comandos que levaram mais de 10 milissegundos para serem concluídos. O histórico de comandos lentos é mantido durante o tempo de execução do mecanismo e será perdido em caso de falha ou reinicialização. Se a lista atingir 128 entradas, eventos antigos serão removidos para abrir espaço para novas entradas. O tamanho da lista de eventos lentos e o tempo de execução considerado lento podem ser modificados através dos parâmetros slowlog-max-len e slowlog-log-slower-than em um grupo de parâmetros personalizado. A lista de logs lentos pode ser recuperada executando SLOWLOG GET 128 no mecanismo, 128 sendo os últimos 128 comandos lentos relatados. Cada entrada tem os seguintes campos:

    1) 1) (integer) 1 -----------> Sequential ID 2) (integer) 1609010767 --> Timestamp (Unix epoch time)of the Event 3) (integer) 4823378 -----> Time in microseconds to complete the command. 4) 1) "keys" -------------> Command 2) "*" ----------------> Arguments 5) "1.2.3.4:57004"-> Source

    O evento acima aconteceu em 26 de dezembro, às 19:26:07 UTC, levou 4,8 segundos (4,823 ms) para ser concluído e foi causado pelo comando KEYS solicitado pelo cliente 1.2.3.4.

    No Linux, o carimbo de data/hora pode ser convertido com a data do comando:

    $ date --date='@1609010767' Sat Dec 26 19:26:07 UTC 2020

    Com Python:

    >>> from datetime import datetime >>> datetime.fromtimestamp(1609010767) datetime.datetime(2020, 12, 26, 19, 26, 7)

    Ou no Windows com a PowerShell:

    PS D:\Users\user> [datetimeoffset]::FromUnixTimeSeconds('1609010767') DateTime : 12/26/2020 7:26:07 PM UtcDateTime : 12/26/2020 7:26:07 PM LocalDateTime : 12/26/2020 2:26:07 PM Date : 12/26/2020 12:00:00 AM Day : 26 DayOfWeek : Saturday DayOfYear : 361 Hour : 19 Millisecond : 0 Minute : 26 Month : 12 Offset : 00:00:00Ticks : 637446075670000000 UtcTicks : 637446075670000000 TimeOfDay : 19:26:07 Year : 2020

    Muitos comandos lentos em um curto período de tempo (mesmo minuto ou menos) são motivo de preocupação. Revise a natureza dos comandos e como eles podem ser otimizados (consulte exemplos anteriores). Se comandos com complexidade de tempo O(1) são frequentemente relatados, verifique os outros fatores para o alto uso da CPU mencionado anteriormente.

  • Métricas de latência: o ElastiCache para Redis OSS fornece métricas do CloudWatch para monitorar a latência média de diferentes classes de comandos. O ponto de dados é calculado dividindo o número total de execuções de comandos na categoria pelo tempo total de execução no período. É importante entender que os resultados da métrica de latência são um agregado de vários comandos. Um único comando pode causar resultados inesperados, como tempos limite, sem impacto significativo nas métricas. Para tais casos, os eventos de log lento seriam uma fonte de informação mais precisa. A lista a seguir contém as métricas de latência disponíveis e os respectivos comandos que as afetam.

    • EvalBasedCmdsLatency: relacionado a comandos de scripts Lua, eval, evalsha;

    • GeoSpatialBasedCmdsLatency: geodist, geohash, geopos, georadius, georadiusbymember, geoadd;

    • GetTypeCmdsLatency: comandos de leitura, independentemente do tipo de dados;

    • HashBasedCmdsLatency: hexists, hget, hgetall, hkeys, hlen, hmget, hvals, hstrlen, hdel, hincrby, hincrbyfloat, hmset, hset, hsetnx;

    • HyperLogLogBasedCmdsLatency: pfselftest, pfcount, pfdebug, pfadd, pfmerge;

    • KeyBasedCmdsLatency: comandos que podem atuar em diferentes tipos de dados: dump, exists, keys, object, pttl, randomkey, ttl, type, del, expire, expireat, move, persist, pexpire, pexpireat, rename, renamenx, restoreK, sort, unlink;

    • ListBasedCmdsLatency: lindex, llen, lrange, blpop, brpop, brpoplpush, linsert, lpop, lpush, lpushx, lrem, lset, ltrim, rpop, rpoplpush, rpush, rpushx;

    • PubSubBasedCmdsLatency: psubscribe, publish, pubsub, punsubscribe, subscribe, unsubscribe;

    • SetBasedCmdsLatency: scard, sdiff, sinter, sismember, smembers, srandmember, sunion, sadd, sdiffstore, sinterstore, smove, spop, srem, sunionstore;

    • SetTypeCmdsLatency: comandos de gravação, independentemente do tipo de dados;

    • SortedSetBasedCmdsLatency: zcard, zcount, zrange, zrangebyscore, zrank, zrevrange, zrevrangebyscore, zrevrank, zscore, zrangebylex, zrevrangebylex, zlexcount, zadd. zincrby, zinterstore, zrem, zremrangebyrank, zremrangebyscore, zunionstore, zremrangebylex, zpopmax, zpopmin, bzpopmin, bzpopmax;

    • StringBasedCmdsLatency: bitcount, get, getbit, getrange, mget, strlen, substr, bitpos, append, bitop, bitfield, decr, decrby, getset, incr, incrby, incrbyfloat, mset, msetnx, psetex, set, setbit, setex, setnx, setrange;

    • StreamBasedCmdsLatency: xrange, xrevrange, xlen, xread, xpending, xinfo, xadd, xgroup, readgroup, xack, xclaim, xdel, xtrim, xsetid;

  • Comandos de runtime do Redis OSS:

    • info commandstats: fornece uma lista de comandos executados desde que o mecanismo foi iniciado, seu número de execuções cumulativas, tempo total de execução e tempo médio de execução por comando;

    • client list: fornece uma lista de clientes atualmente conectados e informações relevantes como o uso de buffers, último comando executado, etc.;

  • Backup e replicação: as versões do ElastiCache para Redis OSS anteriores à 2.8.22 usam um processo bifurcado para criar backups e processar sincronizações completas com as réplicas. Esse método pode incorrer em sobrecarga de memória significativa para casos de uso intensivo de gravação.

    Começando com ElastiCache Redis OSS 2.8.22, a AWS introduziu um método de backup e replicação sem bifurcação. O novo método pode atrasar as gravações para evitar falhas. Ambos os métodos podem causar períodos de maior utilização da CPU, levar a tempos de resposta mais altos e, consequentemente, levar a estouro de limites de tempo do cliente durante a execução. Sempre verifique se as falhas do cliente acontecem durante a janela de backup ou a métrica SaveInProgress foi 1 no período. É aconselhável agendar a janela de backup para períodos de baixa utilização para minimizar a possibilidade de problemas com clientes ou falhas de backup.

Conexões sendo encerradas do lado do servidor

A configuração padrão do ElastiCache para Redis OSS mantém as conexões do cliente estabelecidas indefinidamente. No entanto, em alguns casos, o encerramento da conexão pode ser desejável. Por exemplo:

  • Bugs na aplicação do cliente podem fazer com que as conexões sejam esquecidas e mantidas estabelecidas com um estado ocioso. Isso é chamado de "vazamento de conexão", e a conseqüência é um aumento constante no número de conexões estabelecidas observadas na métrica CurrConnections. Esse comportamento pode resultar em saturação no lado do cliente ou do ElastiCache. Quando uma correção imediata não é possível do lado do cliente, alguns administradores definem um valor de "tempo limite" em seu grupo de parâmetros do ElastiCache. O tempo limite é o tempo em segundos permitido para que as conexões ociosas persistam. Se o cliente não enviar qualquer solicitação no período, o mecanismo encerrará a conexão assim que a conexão atingir o valor de tempo limite. Pequenos valores de tempo limite podem resultar em desconexões desnecessárias e os clientes precisarão lidar com eles corretamente e reconectar, causando atrasos.

  • A memória usada para armazenar chaves é compartilhada com buffers do cliente. Clientes lentos com grandes solicitações ou respostas podem exigir uma quantidade significativa de memória para lidar com seus buffers. As configurações padrão do ElastiCache para Redis OSS não restringem o tamanho dos buffers de saída do cliente regulares. Se o limite maxmemory for atingido, o mecanismo tentará despejar itens para cumprir o uso do buffer. Em condições de memória extremamente baixa, o ElastiCache para Redis OSS pode optar por desconectar clientes que consumam grandes buffers de saída de cliente para liberar memória e reter a integridade do cluster.

    É possível limitar o tamanho dos buffers do cliente com configurações personalizadas e os clientes que atingirem o limite serão desconectados. No entanto, os clientes devem ser capazes de lidar com desconexões inesperadas. Os parâmetros para lidar com o tamanho de buffers para clientes regulares são os seguintes:

    • cliente-query-buffer-limit: tamanho máximo de uma única solicitação de entrada;

    • client-output-buffer-limit-normal-soft-limit: limite flexível para conexões de clientes. A conexão será encerrada se permanecer acima do limite flexível por mais do que o tempo em segundos definido em client-output-buffer-limit-normal-soft-seconds ou se atingir o limite rígido;

    • client-output-buffer-limit-normal-soft-seconds: tempo permitido para as ligações que excedem o client-output-buffer-limit-normal-soft-limit;

    • client-output-buffer-limit-normal-hard-limit: uma conexão que atinge esse limite será imediatamente encerrada.

    Além dos buffers de cliente regulares, as seguintes opções controlam o buffer para nós de réplica e clientes Pub/Sub (Publish/Subscribe):

    • client-output-buffer-limit-replica-hard-limit;

    • client-output-buffer-limit-replica-soft-seconds;

    • client-output-buffer-limit-replica-hard-limit;

    • client-output-buffer-limit-pubsub-soft-limit;

    • client-output-buffer-limit-pubsub-soft-seconds;

    • client-output-buffer-limit-pubsub-hard-limit;

Solução de problemas no lado do cliente para instâncias do Amazon EC2

A carga e a capacidade de resposta no lado do cliente também podem afetar as solicitações ao ElastiCache. Os limites de instância e sistema operacional do EC2 precisam ser cuidadosamente revisados ao solucionar problemas de conectividade intermitente ou tempo limite. Alguns pontos-chave a observar:

  • CPU:

    • Uso da CPU da instância do EC2: verifique se a CPU não está saturada ou perto de 100%. A análise histórica pode ser feita via CloudWatch, no entanto, tenha em mente que a granularidade dos pontos de dados é de 1 minuto (com monitoramento detalhado ativado) ou 5 minutos;

    • Se estiver usando as instâncias do EC2 com intermitência, certifique-se de que o saldo de crédito da CPU não tenha se esgotado. Essas informações estão disponíveis na métrica CPUCreditBalance do CloudWatch

    • Períodos curtos de alto uso da CPU podem causar estouros de tempos limite sem refletir em 100% de utilização no CloudWatch. Tais casos exigem monitoramento em tempo real com ferramentas do sistema operacional como top, ps e mpstat.

  • Rede

    • Verifique se o throughput de rede está abaixo de valores aceitáveis de acordo com os recursos da instância. Para obter mais informações, consulte Tipos de instâncias do Amazon EC2

    • Em instâncias com o Driver de rede aprimorado ena, verifique as estatísticas do ena sobre tempo limite ou limites excedidos. As estatísticas a seguir são úteis para confirmar a saturação de limites de rede:

      • bw_in_allowance_exceeded / bw_out_allowance_exceeded: número de pacotes modelados devido ao throughput excessivo de entrada ou saída;

      • conntrack_allowance_exceeded: número de pacotes descartados devido a limites de monitoramento de conexão de grupos de segurança. Novas conexões falharão quando esse limite estiver saturado;

      • linklocal_allowance_exceeded: número de pacotes descartados devido a solicitações excessivas de metadados de instâncias, NTP via VPC DNS. O limite é de 1024 pacotes por segundo para todos os serviços;

      • pps_allowance_exceeded: número de pacotes descartados devido à proporção excessiva de pacotes por segundo. O limite de PPS pode ser atingido quando o tráfego de rede consistir em milhares ou milhões de solicitações muito pequenas por segundo. O tráfego do ElastiCache pode ser otimizado para fazer melhor uso de pacotes de rede por meio de pipelines ou comandos que façam várias operações ao mesmo tempo, como MGET em vez de GET.

Dissecação do tempo necessário para concluir uma única solicitação

  • Na rede: Tcpdump e Wireshark (tshark na linha de comando) são ferramentas úteis para entender quanto tempo a solicitação levou para viajar pela rede, bater no mecanismo do ElastiCache e obter um retorno. O exemplo a seguir destaca uma única solicitação criada com o seguinte comando:

    $ echo ping | nc example.xxxxxx.ng.0001.use1.cache.amazonaws.com 6379 +PONG

    Paralelamente ao comando acima, tcpdump estava em execução e retornou:

    $ sudo tcpdump -i any -nn port 6379 -tt tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on any, link-type LINUX_SLL (Linux cooked), capture size 262144 bytes 1609428918.917869 IP 172.31.11.142.40966 > 172.31.11.247.6379: Flags [S], seq 177032944, win 26883, options [mss 8961,sackOK,TS val 27819440 ecr 0,nop,wscale 7], length 0 1609428918.918071 IP 172.31.11.247.6379 > 172.31.11.142.40966: Flags [S.], seq 53962565, ack 177032945, win 28960, options [mss 1460,sackOK,TS val 3788576332 ecr 27819440,nop,wscale 7], length 0 1609428918.918091 IP 172.31.11.142.40966 > 172.31.11.247.6379: Flags [.], ack 1, win 211, options [nop,nop,TS val 27819440 ecr 3788576332], length 0 1609428918.918122 IP 172.31.11.142.40966 > 172.31.11.247.6379: Flags [P.], seq 1:6, ack 1, win 211, options [nop,nop,TS val 27819440 ecr 3788576332], length 5: RESP "ping" 1609428918.918132 IP 172.31.11.142.40966 > 172.31.11.247.6379: Flags [F.], seq 6, ack 1, win 211, options [nop,nop,TS val 27819440 ecr 3788576332], length 0 1609428918.918240 IP 172.31.11.247.6379 > 172.31.11.142.40966: Flags [.], ack 6, win 227, options [nop,nop,TS val 3788576332 ecr 27819440], length 0 1609428918.918295 IP 172.31.11.247.6379 > 172.31.11.142.40966: Flags [P.], seq 1:8, ack 7, win 227, options [nop,nop,TS val 3788576332 ecr 27819440], length 7: RESP "PONG" 1609428918.918300 IP 172.31.11.142.40966 > 172.31.11.247.6379: Flags [.], ack 8, win 211, options [nop,nop,TS val 27819441 ecr 3788576332], length 0 1609428918.918302 IP 172.31.11.247.6379 > 172.31.11.142.40966: Flags [F.], seq 8, ack 7, win 227, options [nop,nop,TS val 3788576332 ecr 27819440], length 0 1609428918.918307 IP 172.31.11.142.40966 > 172.31.11.247.6379: Flags [.], ack 9, win 211, options [nop,nop,TS val 27819441 ecr 3788576332], length 0 ^C 10 packets captured 10 packets received by filter 0 packets dropped by kernel

    A partir da saída acima, podemos confirmar que o handshake de três vias do TCP foi concluído em 222 microssegundos (918091 - 917869) e o comando ping foi enviado e retornado em 173 microssegundos (918295 - 918122).

    Demorou 438 microssegundos (918307 - 917869) da solicitação ao fechamento da conexão. Esses resultados confirmam que os tempos de resposta da rede e do mecanismo são bons e que a investigação pode concentrar-se em outros componentes.

  • No sistema operacional: Strace pode ajudar a identificar intervalos de tempo no nível do sistema operacional. A análise de aplicações reais seria muito mais extensa, e profilers ou depuradores especializados de aplicações são aconselhados. O exemplo a seguir mostra apenas se os componentes básicos do sistema operacional estão funcionando como esperado, caso contrário, investigações adicionais podem ser necessárias. Usando do mesmo comando PING do Redis OSS com strace, obtemos:

    $ echo ping | strace -f -tttt -r -e trace=execve,socket,open,recvfrom,sendto nc example.xxxxxx.ng.0001.use1.cache.amazonaws.com (http://example.xxxxxx.ng.0001.use1.cache.amazonaws.com/) 6379 1609430221.697712 (+ 0.000000) execve("/usr/bin/nc", ["nc", "example.xxxxxx.ng.0001.use"..., "6379"], 0x7fffede7cc38 /* 22 vars */) = 0 1609430221.708955 (+ 0.011231) socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0) = 3 1609430221.709084 (+ 0.000124) socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0) = 3 1609430221.709258 (+ 0.000173) open("/etc/nsswitch.conf", O_RDONLY|O_CLOEXEC) = 3 1609430221.709637 (+ 0.000378) open("/etc/host.conf", O_RDONLY|O_CLOEXEC) = 3 1609430221.709923 (+ 0.000286) open("/etc/resolv.conf", O_RDONLY|O_CLOEXEC) = 3 1609430221.711365 (+ 0.001443) open("/etc/hosts", O_RDONLY|O_CLOEXEC) = 3 1609430221.713293 (+ 0.001928) socket(AF_INET, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, IPPROTO_IP) = 3 1609430221.717419 (+ 0.004126) recvfrom(3, "\362|\201\200\0\1\0\2\0\0\0\0\rnotls20201224\6tihew"..., 2048, 0, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("172.31.0.2")}, [28->16]) = 155 1609430221.717890 (+ 0.000469) recvfrom(3, "\204\207\201\200\0\1\0\1\0\0\0\0\rnotls20201224\6tihew"..., 65536, 0, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("172.31.0.2")}, [28->16]) = 139 1609430221.745659 (+ 0.027772) socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) = 3 1609430221.747548 (+ 0.001887) recvfrom(0, 0x7ffcf2f2ca50, 8192, 0, 0x7ffcf2f2c9d0, [128]) = -1 ENOTSOCK (Socket operation on non-socket) 1609430221.747858 (+ 0.000308) sendto(3, "ping\n", 5, 0, NULL, 0) = 5 1609430221.748048 (+ 0.000188) recvfrom(0, 0x7ffcf2f2ca50, 8192, 0, 0x7ffcf2f2c9d0, [128]) = -1 ENOTSOCK (Socket operation on non-socket) 1609430221.748330 (+ 0.000282) recvfrom(3, "+PONG\r\n", 8192, 0, 0x7ffcf2f2c9d0, [128->0]) = 7 +PONG 1609430221.748543 (+ 0.000213) recvfrom(3, "", 8192, 0, 0x7ffcf2f2c9d0, [128->0]) = 0 1609430221.752110 (+ 0.003569) +++ exited with 0 +++

    No exemplo acima, o comando levou um pouco mais de 54 milissegundos para ser concluído (752110 - 697712 = 54398 microssegundos).

    Um tempo significativo, aproximadamente 20 ms, foi levado para instanciar nc e fazer a resolução do nome (de 697712 a 717890), depois disso, 2ms foram necessários para criar o soquete de TCP (745659 a 747858), e 0,4 ms (747858 a 748330) para enviar e receber a resposta para a solicitação.