API Memcache para serviços em pacote legados

Nesta página, você terá uma visão geral do serviço Memcache do App Engine. É comum que, para algumas tarefas, os aplicativos da Web escalonáveis de alto desempenho usem um cache de dados na memória distribuído em frente a, ou no lugar de, um armazenamento permanente robusto. O App Engine inclui um serviço de cache de memória para essa finalidade. Para saber como configurar, monitorar e usar o serviço Memcache, consulte Como usar o Memcache.

Quando usar um cache de memória

Um dos usos de um cache de memória é acelerar consultas comuns no armazenamento de dados. Se muitas solicitações fizerem a mesma consulta com os mesmos parâmetros e as alterações nos resultados não precisarem aparecer no site imediatamente, o aplicativo poderá armazenar os resultados no Memcache. As solicitações subsequentes poderão verificar o Memcache e só executar a consulta no armazenamento de dados se não houver resultados ou se eles tiverem expirado. Os dados da sessão, as preferências do usuário e outros dados retornados por consultas a páginas da Web são bons candidatos para armazenamento em cache.

O Memcache pode ser útil para outros valores temporários. No entanto, para decidir se quer armazenar um valor apenas no Memcache e não em outro armazenamento permanente, verifique se o comportamento do aplicativo é aceitável quando o valor se torna indisponível de repente. Um valor pode expirar no Memcache a qualquer momento, inclusive antes do prazo de expiração definido para ele. Por exemplo, se o funcionamento da sessão for prejudicado pela ausência repentina dos dados de sessão do usuário, provavelmente é melhor armazená-los em outro local além do Memcache.

Níveis de serviço

Dois níveis do serviço Memcache são aceitos pelo App Engine:

  • O Memcache compartilhado é o padrão gratuito dos aplicativos do App Engine. Fornece a capacidade do cache de forma mais eficiente e está sujeito à demanda geral de todos os aplicativos do App Engine que usam o serviço Memcache compartilhado.

  • No Memcache dedicado, a capacidade do cache é fixa e atribuída exclusivamente ao aplicativo. Ele é faturado por GB/hora do tamanho do cache e exige que o faturamento esteja ativado. Ter controle sobre o tamanho do cache significa que o aplicativo pode ter desempenho mais previsível e com menos leituras de um armazenamento durável e mais caro.

Os dois níveis do serviço Memcache usam a mesma API. Para configurar o serviço Memcache no aplicativo, consulte Como usar o Memcache.

A tabela a seguir contém um resumo das diferenças entre as duas classes do serviço Memcache:

Recurso Memcache dedicado Memcache compartilhado
Preço US$ 0,06 por GB/hora Gratuito
Capacidade
us-central
1 a 100 GB
asia-northeast1, europe-west, europe-west3, and us-east1:
1 a 20GB
outras regiões:
1 a 2GB
Sem capacidade garantida
Desempenho Até 10.000 leituras ou 5.000 gravações (exclusivas) por segundo por GB (itens menores que 1 KB). Para mais detalhes, consulte Estatísticas de cache. Não garantido
Armazenamento durável Não Não
SLA Nenhum Nenhum

O faturamento dedicado do Memcache é cobrado em acréscimos de 15 minutos. Se você não paga em dólar americano, valem os preços na sua moeda local listados na página SKUs do Cloud Platform.

Se o aplicativo precisar de mais capacidade de Memcache, entre em contato com nossa equipe de vendas.

Limites

Os limites a seguir se aplicam ao uso do serviço Memcache:

  • O tamanho máximo de um valor de dados em cache é 1 MiB (2^20 bytes), menos o tamanho da chave, menos uma sobrecarga que depende da implementação e é de aproximadamente 73 bytes.
  • Uma chave não pode ter mais de 250 bytes. No ambiente de execução do Java, as chaves que são objetos ou strings com mais de 250 bytes gerarão hash. O comportamento é diferente em outros ambientes de execução.
  • As operações "multi" em lote podem ter qualquer número de elementos. O tamanho total da chamada e dos dados buscados não pode ser superior a 32 megabytes.
  • Uma chave de Memcache não pode conter um byte nulo.

Conselhos e práticas recomendadas

Ao usar o Memcache, recomendamos que você projete os aplicativos para:

  • Gerencie o caso em que um valor em cache nem sempre está disponível.

    • O Memcache não é um armazenamento durável. De acordo com a política de remoção, as chaves são removidas quando o cache é preenchido. Também é possível que alterações na configuração do cache ou eventos de manutenção do data center liberem o cache parcial ou totalmente.
    • O Memcache poderá passar por indisponibilidade temporária. As operações do Memcache podem falhar por vários motivos, incluindo alterações na configuração do cache ou eventos de manutenção do data center. Os aplicativos precisam ser projetados para capturar operações com falha sem expor esses erros aos usuários finais. Essa orientação se aplica especialmente às operações Set.
  • Use a capacidade de lote da API quando possível.

    • Isso melhora o desempenho e a eficiência do app, especialmente para itens pequenos.
  • Distribua a carga no keyspace do Memcache.

    • Ter um só item ou um pequeno grupo de itens do Memcache representando um volume de tráfego desproporcional impedirá o dimensionamento do aplicativo. Essa orientação se aplica tanto às operações por segundo quanto à largura de banda. Muitas vezes, a fragmentação explícita dos dados pode diminuir o problema.

      Por exemplo, é possível dividir um contador atualizado frequentemente entre várias chaves, lendo-as e somando-as apenas quando um total for necessário. Da mesma forma, é possível dividir 500.000 partes de dados que precisem ser lidas em todas as solicitações HTTP em várias chaves e fazer a leitura usando uma única chamada da API em lote. Melhor ainda seria armazenar o valor em cache na memória da instância. Para o Memcache dedicado, a taxa de acesso de pico em uma única chave precisa ser de uma a duas ordens de magnitude menor do que a taxa por GB.

  • Mantenha suas próprias chaves para recuperar valores do cache.

    • O Memcache não fornece um método para listar chaves. Devido à natureza do cache, não é possível listar chaves sem interromper o cache. Além disso, algumas linguagens, como Python, chaves longas de hash e chaves originais, são conhecidas apenas pelo aplicativo.

APIs disponíveis

O Memcache do App Engine é compatível com duas interfaces: uma Memcache API de baixo nível e a especificação JCache. As seções a seguir fornecem mais informações sobre cada interface.

API de baixo nível

A Memcache API de baixo nível aceita mais funcionalidades em comparação com o JCache. Alguns exemplos:

  • Aumentar e diminuir atomicamente os valores do contador de inteiros.
  • Expor mais estatísticas de cache, como a quantidade de tempo desde quando a entrada menos usada recentemente foi acessada e o tamanho total de todos os itens no cache.
  • Verificar e definir operações para armazenar dados condicionalmente.
  • Usar AsyncMemcacheService para executar as operações do Memcache de maneira assíncrona.

A API de baixo nível oferece MemcacheService e AsyncMemcacheService para acessar o serviço do Memcache. Essa API é mais abrangente do que a fornecida por JCache.

Consulte Exemplos de Memcache para ver exemplos de uso síncrono e assíncrono da Memcache API de baixo nível.

JCache

O SDK do App Engine para Java é compatível com a API JCache. O JCache tem uma interface para dados armazenados em cache parecida com um mapa. Armazene e recupere valores no cache usando chaves. As chaves e valores podem ser de qualquer tipo ou classe serializável. Para mais detalhes, consulte Como usar o Memcache.

Recursos incompatíveis do JCache

O JCache não é compatível com os seguintes recursos:

  • A API do listener do JCache é parcialmente compatível com listerners executáveis durante o processamento de uma chamada de API de um aplicativo, como no caso dos listeners onPut e onRemove. Listerners que requerem processamento em segundo plano, como onEvict, não são compatíveis.
  • É possível que um aplicativo teste se o cache contém uma determinada chave, mas não que teste se o cache contém um determinado valor (containsValue() não é compatível).
  • Um aplicativo não pode despejar o conteúdo de chaves ou valores do cache.
  • Um aplicativo não pode redefinir manualmente as estatísticas do cache.
  • O método put() não retorna o valor conhecido anterior de uma chave. Ele sempre retorna null.

Como os dados em cache expiram

O Memcache contém pares de chave/valor. Os pares na memória são alterados a qualquer momento, à medida que os itens são gravados e recuperados do cache.

Por padrão, os valores armazenados no Memcache são retidos o máximo possível. Os valores podem ser removidos do cache quando um novo valor é adicionado e o cache está com pouca memória. Quando a remoção ocorre por pressão sobre a memória, são removidos primeiro os valores usados há mais tempo.

O aplicativo pode fornecer um prazo de validade quando um valor é armazenado, como um número de segundos relativo ao momento em que o valor foi adicionado ou como uma horário Unix absoluto no futuro (um número de segundos desde a meia-noite do dia 1º de janeiro de 1970). O valor será removido até esse horário, mas pode ser removido antes por outros motivos. Incrementar o valor armazenado de uma chave existente não atualiza o prazo de validade dela.

Em circunstâncias raras, os valores também podem desaparecer do cache antes da expiração por outros motivos que não a pressão sobre a memória. O Memcache é resiliente em relação a falhas do servidor, mas os valores não são salvos no disco. Portanto, uma falha no serviço pode fazer com que eles fiquem indisponíveis.

Em geral, o aplicativo não espera que um valor armazenado em cache esteja sempre disponível.

Apague todo o cache de um aplicativo usando a API ou a seção do Memcache do console do Google Cloud.

Estatísticas do cache

Operações por segundo por tamanho do item

O Memcache dedicado é taxado em operações por segundo por GB, em que uma operação é definida como um acesso a itens de cache individuais, como get, set ou delete. A taxa de operação varia conforme o tamanho do item, mais ou menos de acordo com a tabela a seguir. Exceder essas taxas talvez resulte aumento da latência ou erros da API.

As tabelas a seguir mostram o número máximo de operações get-hit ou set sustentadas e exclusivas por GB de cache. Observe que uma operação get-hit é uma chamada get que descobre que há um valor armazenado com a chave especificada e retorna esse valor.

Tamanho do item (KB) Máximo de operações get-hit/s Máximo de operações set/s
≤ 1 10.000 5.000
100 2.000 1.000
512 500 250

Um aplicativo configurado para vários GB de cache pode, teoricamente, alcançar uma taxa de operação agregada calculada como o número de GB multiplicado pela taxa por GB. Por exemplo, um aplicativo configurado para 5 GB de cache pode atingir 50.000 operações do Memcache por segundo em itens de 1 KB. Alcançar esse nível requer uma boa distribuição de carga no keyspace do Memcache.

Para cada padrão de E/S, os limites listados acima são para leituras ou gravações. Para leituras e gravações simultâneas, os limites estão em uma escala móvel. Quanto mais leituras forem feitas, menos gravações poderão ser feitas e vice-versa. Abaixo, veja exemplos de limites de IOPs para leituras e gravações simultâneas de valores de 1 KB por GB de cache:

IOPs de leitura IOPs de gravação
10.000 0
8.000 1.000
5.000 2.500
1.000 4.500
0 5.000

Unidades de computação do Memcache (MCU)

A capacidade de transferência do Memcache pode variar conforme o tamanho do item que você acessa e a operação a ser executada nele. É possível associar um custo aproximado às operações e estime a capacidade de tráfego que você pode esperar do Memcache dedicado usando uma unidade denominada Unidade de computação do Memcache (MCU, na sigla em inglês). A MCU é definida de modo a esperar 10.000 MCU por segundo por GB de Memcache dedicado. O console do Google Cloud mostra a quantidade de MCU que seu app está usando no momento.

Observe que a MCU é uma estimativa estatística aproximada, e não uma unidade linear. Cada operação de cache que lê ou grava um valor tem um custo de MCU correspondente que depende do tamanho do valor. A MCU de um set depende do tamanho do valor: é duas vezes o custo de uma operação get-hit bem-sucedida.

Tamanho do item de valor (KB) Custo de MCU para get-hit Custo de MCU para set
≤ 1 1,0 2,0
2 1,3 2,6
10 1,7 3,4
100 5,0 10,0
512 20,0 40,0
1024 50,0 100,0

Operações que não leem ou gravam um valor têm custo MCU fixo:

Operação MCU
get-miss 1,0
delete 2,0
increment 2,0
flush 100,0
stats 100,0

Observe que uma operação get-miss é um get que descobre que não há um valor armazenado com a chave especificada.

A seguir