mysql e memcache

Certa vez coloquei um artigo sobre memcache no blog, e agora estou colocando outro  que mostra um pequeno exemplo em python para mascarar da leitura de dados do mysql usando memcache, automaticamente.

A classe abstrata __cache__ servirá de base para criação de outras, que devem fornecer os seguintes parâmetros:

  • __dbinf__: dados do mysql (host, db, user e pass)
  • __query__: o comando a ser executado no banco (tipo SELECT)
  • __label__: a chave que irá guardar os resultados no memcache
  • __tmout__: tempo que a chave ficará na memória (em segundos)

Para rodar esse programa, será necessário instalar o memcached (no debian e ubuntu, basta executar sudo apt-get install memcached), e ter o módulo de cliente do memcached para python. Clientes em outras linguagens também estão disponíveis no wiki do memcached.

Além disso, é necessário ter o mysql instalado, bem como o módulo mysqldb do python (no debian e ubuntu, basta executar sudo apt-get install mysql-server-5.0 python-mysqldb) e criar ao menos um database com alguns dados fictícios, para que o programa possa executar o SELECT.

Na primeira vez que o programa for executado, os dados fornecidos pelo SELECT no mysql serão armazenados no memcache por N segundos (de acordo com __tmout__), e daí em diante a execução consecutiva do mesmo programa irá ler esses dados diretamente da memória, sem usar o mysql.

O código:

#!/usr/bin/env python
# 20090104 AF - mysql and memcache

from memcache import Client
from MySQLdb import connect
from MySQLdb.cursors import DictCursor

mc = Client(['127.0.0.1:11211'], debug=0)

class __cache__:
    __dbinf__ = None
    __query__ = None
    __label__ = None
    __tmout__ = 0

    def __init__(self):
        self.__data__ = mc.get(self.__label__) or self.__load__()

    def __load__(self):
        print 'loading from mysql'
        hs, db, usr, pwd = self.__dbinf__
        cursor = connect(host=hs, db=db, user=usr, passwd=pwd, cursorclass=DictCursor).cursor()
        cursor.execute(self.__query__)
        rs = cursor.fetchall()
        mc.set(self.__label__, rs, time=self.__tmout__)
        return rs

    def __iter__(self):
        for n in self.__data__: yield n

class MyTable(__cache__):
    __dbinf__ = ('localhost', 'mydb', 'myuser', 'mypassword')
    __query__ = 'SELECT * FROM mytable'
    __label__ = 'mydb_mytable'
    __tmout__ = 10

if __name__ == '__main__':
    for item in MyTable(): print item

Reduzir a quantidade de acesso ao banco de dados pode proporcionar um grande desempenho nas aplicações. Por outro lado, armazenar muitos dados na memória pode consumir mais recursos que o desejado, portanto, deve-se usar esse modelo apenas quando o objetivo principal do algoritmo do programa é desempenho.

Ainda, a classe __cache__ pode ser adaptada para suas reais necessidades, e  permitir que determinados dados sejam gravados de volta no mysql quando necessário. A opção cursorclass usada para conectar no mysql oferece um recurso interessante, onde os resultados do SELECT são formatados como dicionários ao invés de simples sets do python – porém, para cada linha retornada, há também o nome das colunas do banco, que causa maior consumo de memória.

Tenho usado bastante o recurso de cache de dados, e minhas aplicações têm se comportado muito bem com isso. Especialmente quando as consultas no banco são demoradas, esse recurso pode otimizar muito o tempo de resposta pois após uma busca, os resultados já ficam na memória e as buscas consecutivas são executadas com extrema rapidez.

Anúncios

2 Comentários on “mysql e memcache”

  1. Uma alternativa é acertar o query_cache do mysql, mas ele limpa o cache a cada alteração na tabela.

    Tem um scriptzinho que ajuda no tuning do mysql:

    http://www.aqua.com.br/tuning-primer.sh

    Abraços

  2. Esqueci de outra coisa..

    essa extensão http://gijsbert.org/cmemcache/ é mais rápida do que a escrita puramente em python.


Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s