Otimização utilizando o memcached
Postado por: Flávio Rodrigues emEntã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.













Cara parabéns se ta abordando coisas novas e fugindo do beaba, ta abrindo horizonte para muitos vlw
Todo mundo usa memcached?
Muito bom.. parabéns pela iniciativa.
Realmente preciso muito interessante o post. Dou os parabéns pelo mesmo argumento do Alexandre Broggio! Fugiu do baba
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 ??
Ai encontrei o problema, soh a configuração do PHP não basta tem que ter o serviço do memcached rodando. Obrigado.