Otimização utilizando o memcached

Postado por: Flávio Rodrigues em

Então galerinha, continuando na linha de novos recursos (nem tão novos assim) vou postar hoje pra vocês sobre o MEMCACHED para alguns desconhecidos, para outros um forte aliado…

Um projeto é muito interessante, e que pode ser usado pra aumentar o desempenho de aplicativos web. Pela descrição do site do projeto, o “memcached é um sistema distribuído de alto desempenho para o cacheamento de objetos na memória, genérico por natureza, mas feito para se aumentar a velocidade de sites dinâmicos diminuindo a carga no banco de dados”.

O memcached funciona como um grande dicionário, que armazena tuplas do tipo [chave, valor]. Para armazenar um objeto qualquer, basta conectar no memcached e passar uma chave para acessá-lo e o objeto (e opcionalmente outros parâmetros, como tempo de armazenamento). Para buscar o objeto, basta conectar ao memcached e pedir a ele o objeto que possui a chave previamente criada.


Digamos que uma página web precise fazer algumas consultas pesadas em um banco de dados. A idéia é justamente pegar o resultado da consulta e jogar pra dentro do memcached. Na próxima vez que a consulta precisar ser feita, o programa irá primeiro checar se o resultado já está disponível no memcached. Se estiver, ótimo, economizamos uma query pesada. Se não estiver, o programa faz a consulta e guarda o resultado no memcached. Simples assim!

Exemplo em PHP

< ?php
// A query SQL está abreviada, apenas como exemplo
// Digamos que essa consulte demore cerca de 1 segundo
// para ser completada
$sql = "SELECT * FROM tabela INNER JOIN ......";
$res = pg_query($sql);
$arr = pg_fetch_all($res); // array com todos os resultados
?>

Conforme a observação, é recomendado utilizar querys bemmmmm grandes, pois não existe o porque utilizar querys pequenas e específicas, então utilize querys que levem mais de 1 segundo para ser processadas.

Agora veja como essa consulta ficaria utilizando o memcached:

< ?php
// Conecta ao memcached
$mc = new Memcache;
$mc->addServer('ip.do.servidor');

$sql = "SELECT * FROM tabela INNER JOIN ......";
$cache = $mc->get(md5($sql)); // Usamos o md5() da query como chave

if ($cache === false) {
// Resultado não está no cache
$res = pg_query($sql);
$arr = pg_fetch_all($res);
$mc->set(md5($sql), $arr);
}
else {
$arr = $cache;
}
?>

Pelo exemplo acima, temos algumas modificações. Primeiramente conectamos ao memcached. A chamada a addServer() pode ser feita múltiplas vezes, caso existam vários memcached rodando em máquinas separadas. Pode ser dado um “peso” pra cada servidor também, de acordo com a memória disponível em cada um.

Logo em seguida, é feita a verificação no memcached se o resultado da consulta já está lá. Como chave, usei o hash md5 da consulta, pra gerar uma identificação única. O método get() pode retornar false, caso a chave não esteja no memcached, ou retornar o objeto que foi guardado.

A checagem é simples. Se o get() retornou false, então o sistema faz a consulta como já fazia antes, e no fim guarda o resultado no memcached, pra agilizar as próximas consultas. E caso não tenha retornado false, temos já o resultado da consulta diretamente. Ao fim do bloco if, teremos, de uma forma ou de outra, o resultado da consulta em $arr.
A diferença é que rodando a consulta no banco, o tempo será de cerca de 1 segundo (tempo que estimamos para a execução da consulta), e pegando o resultado direto do memcached, a consulta demorará algo da ordem de milissegundos para ser completada.

Problema

Um dos problemas clássicos em qualquer abordagem que use cache é como saber se as informações em cache ainda estão atuais. Com o memcached, isso não é diferente. Existem algumas formas de se lidar com o problema.

A primeira delas, mais simples, e que pode ser usada livremente caso não seja de suma importância que os dados estejam atuais, é mexer no tempo em que a informação ficará no cache. O tempo pode ser especificado na chamada ao método set(), da seguinte forma:

< ?php $mc->set(md5($sql), $arr, MEMCACHE_COMPRESSED, 60);  ?>

O site do projeto tem um Wiki que responde a maior parte das dúvidas que se pode ter, em relação a instalação e ao uso. No caso do PHP, as funções são bem documentadas na parte do manual sobre memcache.

Seu banco de dados agradece.

Posts Relacionados

Confira também outros artigos interessantes postados aqui no blog.

Sobre Flávio Rodrigues

Flávio Rodrigues é programador pleno, tecnólogo em Sistemas de Informação pelo Curso e Colégio Nova Era em Joinville - SC

6 Responses to “Otimização utilizando o memcached”

  1. Cara parabéns se ta abordando coisas novas e fugindo do beaba, ta abrindo horizonte para muitos vlw

  2. Todo mundo usa memcached?

  3. Carlos Alan

    Muito bom.. parabéns pela iniciativa.

  4. Realmente preciso muito interessante o post. Dou os parabéns pelo mesmo argumento do Alexandre Broggio! Fugiu do baba

  5. Bom artigo, fiz um teste aqui local e não deu certo, só essa condição que é aceita “if ($cache === false) {” se der um var_dump na variavel $cache é exibido bool(false) … ela num deveria ser true apos o primeiro acesso a pagina ?? oq esta faltando pra funcionar ??

  6. Ai encontrei o problema, soh a configuração do PHP não basta tem que ter o serviço do memcached rodando. Obrigado.

Leave a Reply