Anda di halaman 1dari 13

Aplicando o memcached para aumentar

o desempenho do site
Descubra as possibilidades de Virtualização com Storage HP

A ferramenta de software livre memcached é um cache para armazenar informações


frequentemente usadas para evitar o carregamento (e processamento) de informações de
origens mais lentas, como discos ou um banco de dados. Ela pode ser implementada em
uma situação dedicada ou como um método para usar memória sobressalente em um
ambiente existente. Apesar da simplicidade do memcached, ele é algumas vezes usado
incorretamente ou usado como uma solução no tipo errado de ambiente. Aprenda onde é
melhor tirar vantagem do uso do memcached.

Introdução

O memcached é usado para acelerar processos de aplicativos e, aqui, teremos como foco
as melhores práticas para sua implementação dentro de seus aplicativos e ambientes.
Isto inclui o que deveria e o que não deveria ser armazenado, como tratar a distribuição
flexível de dados e como regular o método para atualizar o memcached e versões
armazenadas dos dados. Também será coberto o suporte a soluções de alta
disponibilidade, incluindo o IBM WebSphere eXtreme Scale.

Todos os aplicativos, especialmente muitos aplicativos web, precisam otimizar a


velocidade com que acessam e retornam informações para o cliente. Frequentemente, no
entanto, as mesmas informações são retornadas. Carregar os dados de sua origem de
dados (banco de dados ou sistema de arquivos) é ineficiente, especialmente se forem
executadas as mesmas consultas toda vez que quiser acessar as informações.

Apesar de vários servidores web poderem ser configurados para usar um cache para
retornar informações, isto não funciona com a natureza dinâmica da maioria dos
aplicativos. É aqui que o memcached pode ajudar. Ele fornece um armazenamento
generalizado em memória que pode conter qualquer coisa, incluindo objetivos nativos
de linguagens, permitindo o armazenamento de uma variedade de informações e acessá-
las de muitos aplicativos e ambientes.

Os fundamentos

O memcached é um projeto de software livre projetado para fazer uso da RAM


sobressalente em muitos servidores para agir como um cache de memória para
informações acessadas com frequência. O elemento chave é o uso da palavra cache: o
memcached fornece armazenamento temporário, em memória, das informações que
podem ser carregadas de outro local.

Por exemplo, considere um aplicativo típico baseado em web. Mesmo um web site
servido dinamicamente provavelmente tem alguns componentes de informações
constantes durante a vida da página.
Dentro de um blog, é improvável que a lista de categorias para os tópicos individuais do
blog altere regularmente entre visualizações de páginas. Carregar estas informações
toda vez durante uma consulta ao banco de dados é comparativamente caro,
especialmente quando os dados não alteraram. É possível ver na Figura 1 alguns dos
fragmentos de página dentro de um blog que poderiam ser armazenadas em cache.

Figura 1. Elementos que poderiam ser colocados em cache em uma página de blog
típica

Extrapole esta estrutura para outros elementos do blog, informações da pessoa que o
publicou, comentários mesmo os tópicos do blog em si e é possível identificar 10-20
consultas ao banco de dados e formatações que ocorrem somente para exibir o conteúdo
da página principal. Repita isto para centenas, ou mesmo milhares de visualizações de
páginas a cada dia, e seus servidores e aplicativos estarão executando muito mais
consultas do que o necessário para exibir o conteúdo da página.

Usando o memcached, é possível armazenar as informações formatadas carregadas do


banco de dados em um formulário pronto para ser usado diretamente na página web. E
como as informações estão sendo carregadas da RAM, e não do disco por meio de um
banco de dados e outros processamentos, o acesso às informações é quase instantâneo.
Para reiterar, o memcached é um cache para armazenar informações usadas
frequentemente para evitar o carregamento e o processamento de informações de
origens mais lentas, como discos ou um banco de dados.

A interface para o memcached é fornecida por meio de uma conexão à rede. Isto
significa que é possível compartilhar um único servidor do memcached (ou vários
servidores, como será demonstrado posteriormente neste artigo) com vários clientes. A
interface de rede é rápida e, para melhorar o desempenho, o servidor deliberadamente
não suporta autenticação ou comunicação segura.

Mas isto não deveria limitar as opções de implementação. O servidor do memcached


deverá existir na parte interna de sua rede. A praticidade da interface de rede e a
facilidade com que é possível implementar várias instâncias do memcached permitem o
uso de RAM sobressalente em várias máquinas e aumentar o tamanho geral de seu
cache.

O método de armazenamento com o memcached é um par simples de palavra-


chave/valor, similar ao hash ou matriz associativa disponível em várias linguagens. As
informações são armazenadas no memcached fornecendo a chave e o valor, e
recuperadas solicitando as informações pela chave especificada.

As informações são retidas no cache indefinidamente, a não ser que um dos seguintes
ocorra:

1. A memória alocada para o cache foi esgotada Neste caso, o memcached usa o
método least-recently used (LRU) para remover itens do cache. Itens que não
tenham sido usados recentemente são excluídos do cache, primeiro as com
acesso mais antigo.
2. O item é especificamente excluído É sempre possível excluir um item do
cache.
3. O item expirou Itens individuais podem ter uma expiração para permitir que
sejam retirados do cache quando as informações armazenadas com relação à
chave são provavelmente muito antigas.

Essas situações podem ser usadas em combinação com a lógica de seu aplicativo para
garantir que as informações no cache estejam atualizadas. Com isso em mente, vamos
examinar o quão melhor é usar o memcached em seus aplicativos.

Quando usar o memcached

Há uma série de processos e etapas chave que podem ser modificados ao usar o
memcached para melhorar o desempenho do aplicativo.

Ao carregar informações, o cenário típico é o mostrado na Figura 2.

Figura 2. Sequência típica para carregar informações para exibição


Em termos gerais, as etapas são:

1. Executar uma ou mais consultas para carregar as informações do banco de dados


2. Formatar as informações adequadas para exibição (ou processamento adicional)
3. Usar ou exibir os dados formatados

Ao usar o memcached, a lógica do aplicativo é ligeiramente alterada para acomodar o


cache:

 Tentar carregar as informações do cache


 Se elas existirem, usar a versão em cache das informações
 Se não existirem:

1. Executar uma ou mais consultas para carregar as informações do banco de dados


2. Formatar as informações adequadas para exibição ou processamento adicional
3. Armazenar as informações no cache
4. Usar os dados formatados

Isto é resumido na Figura 3.


Figura 3. Carregando informações para exibição ao usar o memcached

O carregamento dos dados, então, se torna um processo de no máximo três estágios,


carregando os dados do cache ou do banco de dados e armazenando no cache, se
adequado.

Na primeira vez que este processo ocorre, os dados serão carregados do banco de dados
ou outra origem, como normalmente, e, a seguir, armazenados no memcached. Da
próxima vez que as informações forem armazenadas, elas serão retiradas do
memcached, em vez de serem carregadas do banco de dados, economizando tempo e
ciclos de CPU.

O outro lado da equação é garantir que, se as informações que possam ser armazenadas
dentro do memcached forem alteradas, a versão do memcached é atualizada ao mesmo
tempo em que são atualizadas as informações no backend. Isto modifica a sequência
típica daquela mostrada na Figura 4 para a ligeira modificação na Figura 5.
Figura 4. Atualizando ou armazenando dados em um aplicativo típico

A Figura 5 mostra a sequência modificada usando o memcached.

Figura 5. Atualizando ou armazenando dados ao usar o memcached

Por exemplo, usando o blog como base, quando o sistema do blog atualiza a lista de
categorias no banco de dados, a atualização deverá seguir esta sequência:

1. Atualizar a lista de categorias no banco de dados


2. Formatar as informações
3. Armazenar as informações no memcached
4. Retornar as informações para o cliente

Operações de armazenamento dentro do memcached são atômicas, portanto as


informações serão atualizadas sem que os clientes recebam somente dados parciais; eles
receberão a versão antiga ou a versão nova.
Para a maioria dos aplicativos, estas são as duas únicas operações com as quais você
precisa se preocupar. Quando você acessar dados que as pessoas usam, eles são
automaticamente adicionados ao cache e alterações àqueles dados são automaticamente
atualizadas no cache.

Chaves, espaços de nome e valores

Uma consideração importante com o memcached é como organizar e nomear os dados


armazenados dentro do cache. Dos exemplos anteriores do blog, deveria estar claro que
é preciso usar uma estrutura de nomeação consistente, para que possa carregar
categorias, histórico e outras informações do blog e, a seguir, usar isto ao carregar
informações (e atualizar o cache) ou ao atualizar os dados (e, novamente, atualizar o
cache).

O sistema exato de nomenclatura que você usar é específico do aplicativo, mas


normalmente é possível usar uma estrutura similar a seu aplicativo existente, que
provavelmente será baseado em algum tipo de identificador exclusivo. Isto ocorre ao
retirar informações do banco de dados ou ao examinar uma coleção de informações.

Usando o exemplo de tópico do blog, é possível armazenar a lista de categorias em uma


entrada com a chave category-list. Os valores associados com um único tópico com
relação ao ID do tópico, como blogpost-29, poderiam ser usados, enquanto que
comentários com relação à entrada poderiam ser armazenados em blogcomments-29,
onde 29 é o ID do tópico do blog. Desta forma, é possível armazenar uma grande
variedade de informações no cache usando diferentes prefixos para identificar as
informações.

A simplicidade do armazenamento de chave/valor do memcached (e a falta de


segurança) significa que, se quiser dar suporte a vários aplicativos usando o mesmo
servidor do memcached ao mesmo tempo, talvez seja melhor considerar alguma outra
forma de quantificador para identificar os dados como pertencentes a um aplicativo
específico. Por exemplo, é possível adicionar um prefixo do aplicativo como
blogapp:blogpost-29. As chaves têm forma livre, portanto é possível usar qualquer
cadeia de caractere que quiser como nome da chave.

Em termos de armazenar valores, é preciso assegurar que as informações armazenadas


no cache sejam adequadas para seu aplicativo. Por exemplo, com o sistema do blog,
talvez você queira armazenar o objeto usado pelo aplicativo do blog para formatar as
informações do tópico, em vez de HTML bruto. Isto pode ser mais prático se a mesma
estrutura básica for usada em vários locais dentro de seu aplicativo.

A maioria das interfaces de linguagem, incluindo Java, Perl, PHP e muitas outras,
podem serializar objetos de linguagem para armazenamento com o memcached. Isto
permite armazenar e, posteriormente, recuperar objetos inteiros do cache de memória,
em vez de reconstruí-los manualmente dentro de seu aplicativo.

Muitos objetos, ou as estruturas que eles usam, são baseados em algum tipo de hash ou
estrutura de matriz. Para ambientes entre linguagens, como quando você deseja
compartilhar as mesmas informações entre seu ambiente JSP e um ambiente JavaScript,
é possível usar o formato independente de arquitetura, como o JavaScript Object
Notation (JSON) ou mesmo XML.

Preenchendo e usando o memcached

Como um produto de software livre, e um originalmente desenvolvido para trabalhar


dentro de um ambiente existente de software livre, o memcached é suportado por uma
ampla gama de ambientes e plataformas. As interfaces para comunicação com um
servidor do memcached são várias, frequentemente com várias implementações para
todas as linguagens. Consulte Recursos ao final do artigo para obter bibliotecas e kits de
ferramentas comuns.

Seria impossível listar todas as interfaces suportadas e ambientes oferecidos, mas todos
suportam a API básica fornecida pelo protocolo do memcached. Essas descrições foram
simplificadas e deverão ser interpretadas dentro do contexto de diferentes linguagens,
onde os erros podem ser indicados usando diferentes valores. As funções principais são:

 get(key) Obtém as informações do memcached armazenadas com a chave


especificada. Retorna um erro se a chave não existir.
 set(key, value [, expiry]) Armazena o valor especificado usando a chave do
Identificador no cache. Se a chave já existir, ela será atualizada. O tempo de
expiração é em segundos e é considerado como um tempo relativo se o valor for
menor do que 30 dias (30*24*60*60) ou um tempo absoluto (época) se for
maior do que este valor.
 add(key, value [, expiry]) Adiciona a chave ao cache se ela não existir ou retorna
um erro se a chave já existir. Isto pode ser útil se quiser adicionar explicitamente
uma nova chave sem atualizá-la, se já existir.
 replace(key, value [, expiry]) Atualiza o valor da chave especificada, retornando
um erro se a chave não existir.
 delete(key [, time]) Exclui o par chave/valor do cache. Se for fornecido um
tempo, adicionar um novo valor com esta chave será bloqueado pelo período
especificado. O tempo limite permite garantir que o valor seja sempre lido
novamente de sua origem de dados.
 incr(key [, value]) Incrementa a chave especificada com um ou com o valor
especificado. Só funciona com valores numéricos.
 decr(key [, value]) Decrementa a chave especificada com um ou com o valor
especificado. Só funciona com valores numéricos.
 flush_all Invalida (ou expira) todos os itens atuais no cache.

Por exemplo, dentro do Perl, uma operação básica de conjunto seria tratada como
mostra a Listagem 1.

Listagem 1. Operação básica de conjunto dentro do Perl

use Cache::Memcached;

my $cache = new Cache::Memcached {


'servers' => [
'localhost:11211',
],
};
$cache->set('mykey', 'myvalue');

A mesma operação básica no Ruby é mostrada na Listagem 2.

Listagem 2. Operação básica de conjunto dentro do Ruby

require 'memcache'
memc = MemCache::new '192.168.0.100:11211'

memc["mykey"] = "myvalue"

É possível ver em ambos os exemplos a mesma estrutura básica: definir o servidor do


memcached e, a seguir, atribuir ou definir o valor. Estão disponíveis outras interfaces,
incluindo aquelas que funcionam dentro da tecnologia Java, permitindo usar o
memcached dentro de seus aplicativos WebSphere.

A classe da interface do memcached permite serializar objetos Java diretamente dentro


do memcached para poder armazenar e carregar estruturas complexas. Ao implementar
dentro de um ambiente como o WebSphere, duas coisas são realmente importantes: a
resiliência do serviço (e o que fazer se o memcached não estiver disponível) e como
aumentar seu armazenamento em cache para melhorar seu desempenho ao usar vários
servidores de aplicativo, ou ambientes como o WebSphere eXtreme Scale. A seguir,
veremos estas duas questões.

Resiliência e disponibilidade

Uma das perguntas mais comuns sobre o memcached é "O que acontece quando o cache
está indisponível?" Como deveria estar claro das seções anteriores, as informações no
cache nunca deverão ser a única origem das informações. É preciso ser capaz de
carregar os dados armazenados no cache a partir de algum outro local.

Apesar de a praticidade ser de que não ser capaz de acessar informações do cache
reduzirá o desempenho de seu aplicativo, ela não deverá impedir que o aplicativo
continue funcionando. Existem alguns cenários que poderão ocorrer:

1. Se o serviço do memcached sair do ar, seu aplicativo deverá voltar a carregar


informações da origem de dados original e formatá-la conforme necessário para
exibição. O aplicativo também deverá continuar a tentar carregar e armazenar as
informações no memcached.
2. Quando o servidor do memcached estiver disponível novamente, seu aplicativo
deverá automaticamente tentar armazenar os dados. Não há necessidade de
recarregar forçosamente os dados armazenados em cache, é possível usar o
acesso padrão para carregar e popular o cache com informações. Eventualmente,
o cache será preenchido novamente com os dados usados mais comumente.

Para reiterar, o memcached é um cache de informações, e não a única origem. Perder


seu servidor do memcached não deverá ser o fim de seu aplicativo, apesar de que poderá
implicar em uma redução no desempenho até que o servidor do memcached esteja
disponível novamente. Na prática, o servidor do memcached é relativamente simples e,
apesar de não estar livre de problemas, a simplicidade leva a menos erros.
Distribuindo seu cache

O servidor do memcached é somente um cache armazenando valores com relação a


chaves em uma rede. Se houver várias máquinas, a tentação é definir uma instância do
memcached em todas as suas máquinas sobressalentes para fornecer uma grande
quantidade de armazenamento de cache em RAM na rede.

Ao encarar esta ideia, a tentação é presumir que é necessário algum tipo de mecanismo
de distribuição ou replicação que copiará os pares chave/valor entre as máquinas. O
problema com esta abordagem é que você está, na verdade, diminuindo seu cache
disponível em RAM, e não aumentando. Se observar a Figura 6, você verá que existem
três servidores de aplicativo, cada um com acesso a uma instância do memcached.

Figura 6. uso incorreto de várias instâncias do memcached

Apesar de cada instância do memcached ter 1 GB de tamanho (dando 3 GB de cache de


RAM), se cada servidor de aplicativo tiver somente seu próprio cache (ou houve uma
replicação de dados entre as instâncias do memcached), toda sua instalação ainda teria
somente 1 GB de cache duplicado em cada instância.

Como o memcached fornece suas informações sobre uma interface de rede, um único
cliente pode acessar os dados de qualquer instância do memcached ao qual tenha acesso.
Se os dados não forem copiados ou duplicados em cada instância, o que você terá é 3
GB de cache de RAM disponível para cada servidor de aplicativos, como mostra a
Figura 7.
Figura 7. Uso correto de várias instâncias do memcached

O problema com esta abordagem é escolher qual servidor armazenará seu par
chave/valor e como determinar qual servidor do memcached acessar quando quiser
recuperar um valor. A solução é ignorar complexidades como tabelas de consulta ou
esperar que o servidor do memcached trate o processo para você. Em vez disso, os
clientes do memcached deverão pensar de forma simples.

Em vez de ter que determinar estas informações, os clientes do memcached usam um


algoritmo de hashing simples na chave que for especificada ao armazenar a informação.
Ao armazenar ou obter informações de uma lista de servidores do memcached, o cliente
do memcached deriva um valor numérico da chave usando um algoritmo de hashing
consistente.

Para dar um exemplo, a chave mykey é convertida para o valor 23875. Não importa se
você está armazenando ou obtendo informações, sempre usará a mesma chave como
identificador exclusivo para carregar do servidor do memcached, portanto "mykey"
sempre obterá o hash com um valor de 23875, pelo menos neste exemplo.

Se houver dois servidores, o cliente do memcached obtém este valor numérico e realiza
um cálculo simples nele (por exemplo, módulo) para determinar se deveria armazenar o
valor na primeira ou na segunda instância configurada do memcached.

Ao armazenar um valor, o cliente determina o valor do hash a partir da chave e o


servidor usado para armazená-lo. Ao obter um valor, o cliente determina o mesmo valor
do hash a partir da chave e escolhe o mesmo servidor para obter as informações.

Se você usar a mesma lista de servidores (e na mesma ordem) em cada servidor de


aplicativos, cada servidor de aplicativos escolherá o mesmo servidor quando solicitado a
armazenar ou recuperar a mesma chave. Agora você está compartilhando 3 GB de
espaço de memcached, em vez de duplicar o mesmo 1 GB de espaço, dando mais cache
para usar e, provavelmente, melhorando o desempenho de seu aplicativo para ainda
mais usuários.

Existem complexidades neste processo (como o que acontece quando um servidor está
indisponível), mas a documentação oferece mais informações (consulte detalhes
Recursos).
Como não usar o memcached

Apesar da simplicidade do memcached, a tentação é usar a instância do memcached em


algumas formas inesperadas e, algumas vezes, infelizes.

 O memcached não é um banco de dados

Provavelmente o uso incorreto mais comum do memcached é o uso deste para


armazenamento de dados, e não como um cache. A finalidade principal do memcached
é melhorar os tempos de resposta para dados que, de outra forma, podem ser
construídos ou recuperados de alguma outra origem.

Um exemplo é a recuperação de informações de um banco de dados, particularmente se


houver alguma formatação ou manipulação das informações antes que sejam exibidas
ao usuário. O memcached foi projetado para armazenar estas informações em memória
para evitar a realização repetida daquela tarefa cada vez que os dados forem
recuperados.

O memcached nunca deverá ser usado como a única origem de dados de que necessita
para executar seu aplicativo; os dados sempre deverão ser deriváveis de alguma outra
origem. Além disso, tenha em mente que o memcached é somente um armazenamento
de chave/valor.

Não é possível realizar uma consulta sobre os dados ou realizar uma iteração no
conteúdo para extrair informações. Ele deverá ser usado para armazenar blocos ou
objetos de dados que você precisa usar em estilo de atacado.

 Não armazene em cache linhas de banco de dados ou arquivos

Apesar de ser possível usar o memcached para armazenar as linhas de dados como
carregadas de um banco de dados, isto é na verdade armazenamento em cache de
consultas, e a maioria dos bancos de dados fornecem seus próprios mecanismos de
armazenamento de consultas em cache. O mesmo pode ser dito para outros objetos,
como imagens ou arquivos do sistema de arquivos. Muitos aplicativos e servidores web
já têm soluções bem otimizadas para este tipo de trabalho.

Você ganhará mais melhorias de utilidade e desempenho do memcached se usá-lo para


armazenar blocos inteiros de informações depois do carregamento e da formatação.
Usando nosso exemplo do blog, o melhor ponto para armazenar informações é depois
que tiver formatado as categorias do blog como um objeto, ou mesmo depois de
formatar em HTML.

A construção da página do blog pode, então, ser alcançada carregando os componentes


(tópicos do blog, lista de categorias, histórico de tópicos etc.) a partir do memcached e
gravando o HTML completo de volta para o cliente.

 O memcached não é seguro

Para garantir o desempenho máximo, o memcached não fornece nenhum tipo de


segurança, seja autenticação ou criptografia. Isto significa que o acesso a seus
servidores do memcached deverão ser tratados colocando-os na mesma zona privada
que seu ambiente de implementação do aplicativo ou, se a segurança for fundamental,
use os soquetes do UNIX e permita que somente aplicativos no mesmo host atual
acessem o servidor do memcached.

Isto remove parte da flexibilidade e resiliência e sua capacidade de compartilhar um


cache de RAM entre várias máquinas pela rede, mas é a única solução para implementar
segurança em seus dados do memcached nesta situação.

Não se limite

Apesar das coisas para as quais você não deveria usar suas instâncias do memcached, a
flexibilidade do memcached não deve ser ignorada. Como o memcached está no mesmo
nível de arquitetura que seu aplicativo, ele é fácil de integrar e conectar. E alterar seu
aplicativo para tirar vantagem do memcached não é complicado.

Além disso, como o memcached é somente um cache, ele não deverá interromper a
execução de seu aplicativo no caso de um problema. O que ele faz, se usado
corretamente, é diminuir a carga no resto da infraestrutura do servidor (reduz leituras de
bancos de dados e origens de dados), e isto significa suportar mais clientes sem a
necessidade de mais hardware.

Mas lembre-se, é só cache!

Resumo

Neste artigo, abordamos o memcached e como usá-lo da melhor forma. Em particular,


vimos como as informações são armazenadas, como escolher chaves razoáveis e como
escolher as informações a serem armazenadas. Também vimos alguns problemas chave
da implementação pelos quais todos os usuários do memcached passam, incluindo o uso
de vários servidores, o que fazer quando uma instância do memcached fica indisponível
e, talvez o aspecto mais importante, como não usar o memcached.

Como um aplicativo de software livre, e um que tem um objetivo bem simples e direto,
o poder e a utilidade do memcached advêm dessa simplicidade. Ao fornecer um grande
armazenamento em RAM para informações, tornando-as disponíveis na rede e, a seguir,
acessíveis por meio de tal imensa gama de diferentes interfaces e linguagens, é possível
integrar o memcached em uma enorme variedade de instalações.

Anda mungkin juga menyukai