Práticas recomendadas para usar réplicas de leitura
Muitos aplicativos, como armazenamentos de sessões, tabelas de classificação e mecanismos de recomendação, exigem alta disponibilidade e lidam com muito mais operações de leitura do que operações de gravação. Esses aplicativos geralmente podem tolerar dados um pouco obsoletos (consistência eventual), o que significa que é aceitável que usuários diferentes vejam momentaneamente versões ligeiramente diferentes dos mesmos dados. Por exemplo:
Os resultados das consultas em cache geralmente podem tolerar dados um pouco obsoletos, especialmente para padrões de armazenamento em cache, nos quais a fonte da verdade é externa.
Em uma tabela de classificação de jogos, alguns segundos de atraso nas pontuações atualizadas geralmente não afetam significativamente a experiência do usuário.
Para armazenamentos de sessões, alguns pequenos atrasos na propagação dos dados da sessão entre réplicas raramente afetam a funcionalidade do aplicativo.
Os mecanismos de recomendação geralmente usam análise de dados históricos, portanto, a consistência em tempo real é menos crítica.
A consistência eventual significa que todos os nós de réplica eventualmente retornarão os mesmos dados quando o processo de replicação for concluído, normalmente em milissegundos. Para esses casos de uso, implementar réplicas de leitura é uma estratégia eficaz para reduzir a latência ao ler da sua instância do ElastiCache.
O uso de réplicas de leitura no Amazon ElastiCache pode oferecer benefícios significativos de desempenho por meio de:
Escalabilidade de leitura aprimorada
Distribui as operações de leitura em vários nós de réplica
Descarrega o tráfego de leitura do nó primário
Reduz a latência de leitura ao atender solicitações de réplicas geograficamente mais próximas
Desempenho otimizado do nó primário
Dedica recursos do nó primário às operações de gravação
Reduz a sobrecarga de conexão no nó primário
Melhora o desempenho de gravação e mantém melhores tempos de resposta durante os períodos de pico de tráfego
Uso da leitura da réplica no ElastiCache com tecnologia sem servidor
O ElastiCache com tecnologia sem servidor fornece dois endpoints diferentes, para diferentes requisitos de consistência. Os dois endpoints usam o mesmo nome de DNS, mas portas diferentes. Para usar a porta de leitura a partir da réplica, você deve autorizar o acesso às duas portas do seu aplicativo cliente configurando os grupos de segurança e as listas de controle de acesso à rede da sua VPC.
Endpoint primário (porta 6379)
Use para operações que exigem consistência imediata
Garante a leitura dos dados mais atualizados
Ideal para transações críticas e operações de gravação
Necessário para operações de gravação
Exemplo:
test-12345.serverless.use1.cache.amazonaws.com:6379
Endpoint otimizado para latência (porta 6380)
Otimizado para operações de leitura que podem tolerar uma eventual consistência
Quando possível, o ElastiCache com tecnologia sem servidor encaminha automaticamente as solicitações de leitura para o nó de réplica na zona de disponibilidade local do cliente. Essa otimização fornece menor latência ao evitar a latência adicional de rede resultante da recuperação de dados de um nó em uma zona de disponibilidade diferente.
O ElastiCache com tecnologia sem servidor seleciona automaticamente os nós disponíveis em outras zonas se um nó local não estiver disponível
Exemplo:
test-12345.serverless.use1.cache.amazonaws.com:6380Clientes como Glide e Lettuce detectarão e rotearão automaticamente as leituras para o endpoint com latência otimizada se você fornecer a leitura da configuração da réplica. Se seu cliente não oferece suporte à configuração de roteamento (por exemplo, valkey-java e versões mais antigas do jedis), você deve definir a porta e a configuração do cliente corretas para ler as réplicas.
Conexão com réplicas de leitura no ElastiCache com tecnologia sem servidor - Valkey and Glide
O trecho de código a seguir mostra como você pode configurar a leitura da réplica para o ElastiCache com tecnologia sem servidor na biblioteca Valkey glide. Você não precisa especificar a porta para leitura das réplicas, mas precisa configurar a configuração de roteamento ReadFrom.PREFER_REPLICA.
package glide.examples; import glide.api.GlideClusterClient; import glide.api.logging.Logger; import glide.api.models.configuration.GlideClusterClientConfiguration; import glide.api.models.configuration.NodeAddress; import glide.api.models.exceptions.ClosingException; import glide.api.models.exceptions.ConnectionException; import glide.api.models.exceptions.TimeoutException; import glide.api.models.configuration.ReadFrom; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; public class ClusterExample { public static void main(String[] args) { // Set logger configuration Logger.setLoggerConfig(Logger.Level.INFO); GlideClusterClient client = null; try { System.out.println("Connecting to Valkey Glide..."); // Configure the Glide Client GlideClusterClientConfiguration config = GlideClusterClientConfiguration.builder() .address(NodeAddress.builder() .host("your-endpoint") .port(6379) .build()) .useTLS(true) .readFrom(ReadFrom.PREFER_REPLICA) .build(); // Create the GlideClusterClient client = GlideClusterClient.createClient(config).get(); System.out.println("Connected successfully."); // Perform SET operation CompletableFuture<String> setResponse = client.set("key", "value"); System.out.println("Set key 'key' to 'value': " + setResponse.get()); // Perform GET operation CompletableFuture<String> getResponse = client.get("key"); System.out.println("Get response for 'key': " + getResponse.get()); // Perform PING operation CompletableFuture<String> pingResponse = client.ping(); System.out.println("PING response: " + pingResponse.get()); } catch (ClosingException | ConnectionException | TimeoutException | ExecutionException e) { System.err.println("An exception occurred: "); e.printStackTrace(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } finally { // Close the client connection if (client != null) { try { client.close(); System.out.println("Client connection closed."); } catch (ClosingException | ExecutionException e) { System.err.println("Error closing client: " + e.getMessage()); } } } } }