Nesta página, você encontra orientação sobre o uso ideal do Memorystore para Redis. Essa página também indica possíveis problemas que devem ser evitados.
Para ver uma lista de cenários de solução de problemas, consulte Solução de problemas.
Práticas recomendadas de alta disponibilidade e durabilidade de dados
Recomendamos o uso do nível Standard como o mecanismo principal para alta disponibilidade (HA). O nível Standard oferece uma instância de alta disponibilidade com várias réplicas e permite uma recuperação rápida usando o failover automático se a instância principal falhar. Além disso, ativar snapshots de RDB em instâncias do nível Standard oferece proteção extra contra falhas de nó.
Em alguns cenários, também é recomendável garantir que seja possível recuperar dados de backups de snapshot. Nesses cenários, os backups e a capacidade de restaurar dados de snapshots do RDB podem fornecer proteção extra contra perda de dados.
Se você ativar os snapshots do RDB e precisar recuperar seus dados, o Memorystore para Redis poderá fazer isso usando o snapshot mais recente. Esses snapshots são apenas para recuperação interna do sistema e não podem ser acessados.
Limitações de durabilidade e práticas recomendadas
Embora o nível Standard ofereça alta disponibilidade por meio de replicação e failover automático, ela não garante a durabilidade total dos dados. O Memorystore para Redis não pode fornecer durabilidade total de dados, mesmo com a HA ativada durante determinados eventos catastróficos, como falhas regionais temporárias.
Para ajudar a proteger seus dados e fornecer um nível básico de persistência, os snapshots do RDB são ativados por padrão quando você cria uma instância do Memorystore para Redis usando o console do Google Cloud .
Para cargas de trabalho de produção, considere as seguintes práticas recomendadas para melhorar ainda mais a resiliência dos dados:
- Recuperação de desastres: o Memorystore para Redis não é compatível com a replicação entre regiões. Se a estratégia de recuperação de desastres exigir replicação entre regiões para uma verdadeira resiliência regional, recomendamos usar uma instância do Memorystore for Valkey. Para mais informações sobre como configurar e gerenciar instâncias secundárias em várias regiões, consulte Trabalhar com replicação entre regiões na documentação do Memorystore for Valkey.
- Durabilidade máxima: se o aplicativo exigir o maior nível possível de durabilidade de dados, recomendamos usar uma instância do Memorystore for Valkey configurada com replicação entre regiões, backups diários automatizados e persistência de arquivo somente anexação (AOF, na sigla em inglês). Essa combinação oferece a proteção mais robusta contra perda de dados. Para mais informações, consulte Visão geral da persistência na documentação do Memorystore for Valkey.
Práticas recomendadas para planejamento de capacidade
Para garantir que você possa provisionar recursos e criar arquiteturas resilientes, recomendamos as seguintes práticas recomendadas de planejamento de capacidade:
- Implante em vários locais: se não for possível criar uma instância na zona preferida devido a restrições temporárias de recursos, tente criar a instância em uma zona diferente na mesma região ou em uma região diferente.
- Usar o acesso entre regiões: configure seus clientes para acessar as instâncias localizadas em regiões diferentes. Se você precisar provisionar uma instância em uma região diferente devido a restrições de recursos locais, seus clientes poderão se conectar à instância.
- Escolha um nível de capacidade diferente: se você encontrar restrições de recursos devido ao tamanho de uma instância, selecione um nível de capacidade diferente ou redimensione a instância. Para mais informações, consulte Desempenho do nível de capacidade.
Exportação de RDB
Ao exportar um backup do RDB, siga estas orientações:
- Exporte durante um período de baixa taxa de gravação.
- Ao exportar durante um período de alta taxa de gravação, reduza a configuração de
maxmemorytemporariamente a 50% da capacidade da instância para oferecer sobrecarga suficiente para uma operação bem-sucedida.
Operações com uso intensivo de recursos
Para instâncias do Redis de nível Padrão, as seguintes operações usam memória extra durante a operação:
O upgrade, o escalonamento e o failover manual de versões usam memória extra (para instâncias do nível Padrão) devido à replicação. Essas operações seguem o processo de replicação descrito em Comportamento de upgrade da instância do nível Padrão.
As operações de importação e exportação exigem memória extra devido ao processo Redis interrompido e ao gerenciamento de dados de cópia em gravação associados a essas operações.
Para diminuir as desvantagens das operações que usam muitos recursos, é necessário:
- reduzir a configuração maxmemory para 80% da capacidade da instância durante a operação. Isso proporciona uma sobrecarga suficiente para uma operação bem-sucedida;
- monitorar a métrica de proporção de uso da memória do sistema e garantir que essa métrica seja inferior a 80% antes de executar uma dessas operações;
- Execute essas operações durante períodos de baixo tráfego de instâncias (como durante a noite ou no fim de semana).
- deixar a lógica de repetição em espera exponencial antes de executar essas operações.
Operações e cenários que exigem uma nova tentativa de conexão
As operações e os cenários a seguir interrompem a conexão de rede entre sua rede e a instância do Redis:
- Upgrade da versão
- Como fazer escalonamento vertical/redução
- Importando
- Failover manual
- Manutenção do sistema
- Rotação da autoridade de certificação para instâncias do Redis que têm a criptografia em trânsito ativada
- Failover de emergência
Essas operações modificam a instância, exigindo uma interrupção de conexão temporária. A lógica de nova tentativa precisa estar em espera exponencial antes da execução dessas operações para que o aplicativo se reconecte automaticamente e continue funcionando normalmente.
Manutenção de rotina
As instâncias do Memorystore para Redis passam por manutenção periodicamente. Para mais detalhes, consulte a política de manutenção do Memorystore para Redis.
Implemente as práticas recomendadas a seguir para se preparar para manutenção de rotina:
- Defina uma janela de manutenção para quando as atualizações de manutenção possam ocorrer.
- Programe janelas de manutenção para tempos de baixo tráfego de instâncias e sobrecarga de memória suficiente. Para saber mais, consulte Impacto das atualizações de manutenção.
- Ative as notificações sobre janelas de manutenção para receber alertas sobre as próximas manutenções.
- Deixe a lógica de repetição em espera exponencial.
- Para instâncias do nível Standard, é possível simular um evento de manutenção usando o failover manual para ver como o failover causado pela manutenção afeta seu aplicativo.
- Para instâncias do nível básico, é possível simular o impacto de uma atualização de manutenção escalonando temporariamente a instância para um tamanho maior. Depois de observar o impacto, é possível voltar ao tamanho original.
Gerenciamento de memória
O gerenciamento de memória pode ser um desafio devido à conhecida fragmentação de memória
que ocorre com o Redis de código aberto. Recomendamos que você reduza a configuração de
maxmemory da instância para se manter sobrecarregado no caso de
alta pressão da memória.
A melhor maneira de monitorar a pressão sobre a memória na instância do Memorystore é usar a métrica de proporção de uso da memória do sistema. Para um guia mais detalhado sobre como gerenciar a memória do Memorystore para Redis, consulte Práticas recomendadas de gerenciamento de memória.
Como gerenciar conexões inativas
Com o tempo, é possível que o número de conexões com sua instância do Memorystore aumente
se as conexões não estiverem sendo encerradas corretamente. Isso pode
ter implicações negativas no desempenho, especialmente se você estiver usando criptografia em trânsito, que impõe limites máximos de conexões
com base no seu nível de capacidade. Para atenuar esse problema, recomendamos o uso do
parâmetro de configuração do Redis
timeout, que permite definir o número de segundos antes que as conexões de clientes inativas
sejam encerradas automaticamente.
Nomes de recursos da Transparência no acesso
Dados sensíveis não devem ser armazenados nos nomes de recursos do Memorystore for Redis. Por nomes de recursos, queremos dizer nomes de instâncias do Memorystore para Redis e metadados de instâncias, como tags. Não há garantia de que os dados armazenados em nomes de recursos sejam protegidos pela Google Cloud Transparência no acesso, e eles podem entrar em conflito com os requisitos de compliance da Transparência no acesso da sua organização.
Conector de acesso VPC sem servidor necessário em alguns ambientes sem servidor
Alguns ambientes sem servidor exigem um conector de acesso VPC sem servidor para se conectar ao Memorystore para Redis. Se quiser se conectar usando um desses ambientes, configure o conector de acesso VPC sem servidor para seu projeto.
Rede
Recomendamos usar o modo de conexão do acesso a serviços privados. O Memorystore para Redis usa dois modos de conexão: acesso particular a serviços e peering direto. O modo de conexão do acesso a serviços privados simplifica o gerenciamento de intervalos de IP e permite o uso da VPC compartilhada, se quiser.
Depois de criar uma instância, não é possível alterar o modo de conexão.
Para mais detalhes, consulte Rede.
Monitoramento e alertas
Recomendamos o uso de monitoramento e alertas, porque eles fornecem indicadores-chave sobre o uso da memória da sua instância do Redis. Elas também fornecem insights sobre a eficiência da sua instância do Redis na resposta às solicitações de cache recebidas.
É necessário configurar os seguintes alertas padrão:
- Configurar um alerta do Cloud Monitoring para uso da memória
- Como definir um alerta do Cloud Monitoring para a proporção de uso da memória do sistema
Práticas recomendadas para uso da CPU
O uso inadequado de comandos caros do Redis leva a alta latência, falta de resposta ou problemas de conectividade. As instâncias do nível Standard fornecem alta disponibilidade durante a recuperação de desastres e dependem da replicação assíncrona entre os nós primário e de réplica. Se um dos nós tiver um processamento de comando caro que bloqueia a linha de execução principal do Redis, a replicação pode ser afetada. Se o problema persistir e houver uma interrupção no local, os dados mais recentes gravados no local da interrupção talvez não estejam disponíveis no outro local.
Recomendamos usar o Cloud Monitoring
para definir alertas para a métrica Segundos de CPU da linha de execução principal
(redis.googleapis.com/stats/cpu_utilization_main_thread) para garantir que
o uso da CPU não exceda 0,8 segundo para o nó principal ou 0,5 segundo
para cada nó de réplica, quando a réplica for designada como uma réplica de leitura.
Se a instância do Redis exceder os valores recomendados, escalone a instância para um nível de capacidade mais alto ou siga as instruções de solução de problemas para evitar operações que consomem muita CPU.
Se a instância tiver alta utilização de CPU ou se os recursos dela forem esgotados (por exemplo, por ter muitas conexões), ela poderá se comportar de maneira inadequada e as métricas externas poderão estar ausentes.
Comandos que consomem muitos recursos
Recomendamos que você evite usar comandos do Redis que consomem muitos recursos. O uso desses comandos pode resultar nos seguintes problemas de desempenho:
- Latência alta e tempos limite do cliente
- Pressão de memória causada por comandos que aumentam o uso da memória
- Perda de dados durante a replicação e sincronização de nós porque a linha de execução principal do Redis está bloqueada
- Verificações de integridade, observabilidade e replicação sem recursos
A tabela a seguir lista exemplos de comandos do Redis que consomem muitos recursos e oferece alternativas que são eficientes em termos de recursos.
| Categoria | Comando que consome muitos recursos | Alternativa com uso eficiente de recursos |
|---|---|---|
| Executar para todo o keyspace | KEYS |
SCAN |
| Executar para um conjunto de chaves de comprimento variável | LRANGE |
Limite o tamanho do intervalo usado para uma consulta. |
ZRANGE |
Limite o tamanho do intervalo usado para uma consulta. | |
HGETALL |
HSCAN |
|
SMEMBERS |
SSCAN |
|
| Bloquear a execução de um script | EVAL |
Verifique se o script não é executado indefinidamente. |
EVALSHA |
Verifique se o script não é executado indefinidamente. | |
| Remover arquivos e links | DEL |
UNLINK |
| Publicar e assinar | PUBLISH |
SPUBLISH |
SUBSCRIBE |
SSUBSCRIBE |
Práticas recomendadas para clientes Redis
Nesta seção, fornecemos orientações sobre como usar o cliente do Redis de maneira ideal.
Detectar e processar conexões que não respondem
Recomendamos configurar o aplicativo cliente para detectar conexões que não respondem ao Memorystore para Redis. Quando uma conexão que não responde é detectada, o cliente precisa redefini-la. Para criar um aplicativo resiliente, recomendamos as seguintes configurações de cliente:
- Configure os parâmetros de sinal de atividade do TCP: defina os parâmetros
TCP keepalive time,TCP keepalive intervaleTCP keepalive probespara que os clientes detectem e descartem conexões que não respondem de maneira proativa, mesmo quando as conexões estão inativas. Por exemplo, se você definir o parâmetroTCP keepalive timecomo 30 segundos,TCP keepalive intervalcomo 10 segundos eTCP keepalive probescomo 3, os clientes vão redefinir as conexões inativas que não respondem em um minuto. - Configurar tempos limite do usuário TCP: defina esse tempo limite nos clientes para redefinir conexões que têm solicitações pendentes e parar de responder. Por exemplo, se você definir o tempo limite como 15 segundos, os clientes vão redefinir as conexões que não respondem e que têm solicitações pendentes após 15 segundos.
Práticas recomendadas específicas do cliente
Se você escalonar horizontalmente seus aplicativos, poderá receber erros READONLY
em comandos de gravação. O Memorystore para Redis usa uma implantação que não é do Sentinel com
endpoints estáticos, e os clientes não recebem informações de papel dinâmicas antecipadamente.
Se você usar uma única conexão de cliente para os endpoints principal e de réplica, o cliente poderá enviar acidentalmente comandos de gravação para a réplica somente leitura. A réplica retorna um erro READONLY porque não pode
processar comandos de gravação.
Para evitar o roteamento incorreto de gravações, não use uma única conexão para leituras e gravações. Em vez disso, divida as operações criando as seguintes instâncias de cliente separadas:
- Cliente principal: conecta-se apenas ao endpoint principal.
- Cliente de réplica: conecte-se apenas ao endpoint de réplica.
As guias a seguir mostram como configurar os modelos separados em Go, Java, Node.js e Python.
Go
package main import ( "context" "fmt" "github.com/redis/go-redis/v9" ) func main() { ctx := context.Background() // Initialize the primary client connecting only to the primary endpoint primaryClient := redis.NewClient(&redis.Options{ Addr: "PRIMARY_HOST:6379", Password: "YOUR_PASSWORD", DB: 0, }) defer primaryClient.Close() // Initialize the replica client connecting only to the replica endpoint replicaClient := redis.NewClient(&redis.Options{ Addr: "REPLICA_HOST:6379", Password: "YOUR_PASSWORD", DB: 0, }) defer replicaClient.Close() // Use the primary client for all mutating commands err := primaryClient.Set(ctx, "example_key", "example_value", 0).Err() if err != nil { fmt.Printf("Failed to write to primary: %v\n", err) } // Use the replica client for all read-only commands val, err := replicaClient.Get(ctx, "example_key").Result() if err != nil { fmt.Printf("Failed to read from replica: %v\n", err) } else { fmt.Printf("Successfully read value: %s\n", val) } }
Java
@Bean public RedisConnectionFactory primaryConnectionFactory() { RedisStandaloneConfiguration config = new RedisStandaloneConfiguration("PRIMARY_HOST", 6379); config.setPassword(RedisPassword.of("YOUR_PASSWORD")); return new LettuceConnectionFactory(config); } @Bean public RedisConnectionFactory replicaConnectionFactory() { RedisStaticMasterReplicaConfiguration config = new RedisStaticMasterReplicaConfiguration("PRIMARY_HOST", 6379); config.addNode("REPLICA_HOST", 6379); config.setPassword(RedisPassword.of("YOUR_PASSWORD")); LettuceClientConfiguration clientConfig = LettuceClientConfiguration.builder() .readFrom(ReadFrom.REPLICA_PREFERRED) .build(); return new LettuceConnectionFactory(config, clientConfig); } @Bean public RedisTemplate<String, Object> primaryRedisTemplate( @Qualifier("primaryConnectionFactory") RedisConnectionFactory factory) { RedisTemplate<String, Object> template = new RedisTemplate<>(); template.setConnectionFactory(factory); return template; } @Bean public RedisTemplate<String, Object> replicaRedisTemplate( @Qualifier("replicaConnectionFactory") RedisConnectionFactory factory) { RedisTemplate<String, Object> template = new RedisTemplate<>(); template.setConnectionFactory(factory); return template; }
Node.js
import { createClient } from 'redis'; async function main() { // Initialize the primary client connecting only to the primary endpoint const primaryClient = createClient({ url: 'redis://PRIMARY_HOST:6379', password: 'YOUR_PASSWORD' }); // Initialize the replica client connecting only to the replica endpoint const replicaClient = createClient({ url: 'redis://REPLICA_HOST:6379', password: 'YOUR_PASSWORD' }); primaryClient.on('error', (err) => console.error('Primary Client Error', err)); replicaClient.on('error', (err) => console.error('Replica Client Error', err)); await primaryClient.connect(); await replicaClient.connect(); // Use the primary client for all mutating commands try { await primaryClient.set('example_key', 'example_value'); console.log('Successfully wrote to primary'); } catch (err) { console.error('Failed to write to primary:', err); } // Use the replica client for all read-only commands try { const val = await replicaClient.get('example_key'); console.log(`Successfully read value: ${val}`); } catch (err) { console.error('Failed to read from replica:', err); } await primaryClient.disconnect(); await replicaClient.disconnect(); } main();
Python
import redis def main(): # Initialize the primary client connecting only to the primary endpoint primary_client = redis.Redis( host='PRIMARY_HOST', port=6379, password='YOUR_PASSWORD', decode_responses=True ) # Initialize the replica client connecting only to the replica endpoint replica_client = redis.Redis( host='REPLICA_HOST', port=6379, password='YOUR_PASSWORD', decode_responses=True ) # Use the primary client for all mutating commands try: primary_client.set('example_key', 'example_value') print('Successfully wrote to primary') except redis.RedisError as e: print(f'Failed to write to primary: {e}') # Use the replica client for all read-only commands try: val = replica_client.get('example_key') print(f'Successfully read value: {val}') except redis.RedisError as e: print(f'Failed to read from replica: {e}') if __name__ == '__main__': main()