Pylos和Memcached

3

有人在他们的Web应用程序中使用这种组合吗?我在配置方面遇到了一些麻烦,找不到任何教程或指南。由于我最近开始使用Pylons,所以对此不太熟悉,请保持建议非常适合新手(我甚至没有经常使用像Beaker这样的模块)。

我正在使用MySQL,在运行pastie HTTP服务器,刚刚在Debian上安装了memcached包,在我的Pylons应用程序中使用SQLAlchemy ORM与我的DB进行交互,现在我不确定该做什么。

2个回答

7

memcached 是一款非常好用且不依赖于框架的软件,你只需要写一点代码就可以与它进行交互。memcached 的基本思想是:

object = try_memcached()
if not object:
    object = real_query()
    put_in_memcached(object)

在您的情况下,这很可能是在您的SQLAlchemy抽象中完成的。由于我不熟悉您的整个平台(只了解memcached),因此我进行了一些Google搜索。 这位博主似乎已经将它们结合起来,并提供了他使用的代码链接。相关代码似乎是这样的,这可能对您有意义:
#!/usr/bin/python
"""
memcached objects for use with SQLAlchemy
"""
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.

import memcache
import sqlalchemy
import sqlalchemy.orm

SQLA_SESSION = sqlalchemy.orm.sessionmaker()

MEMCACHED_CLIENT = memcache.Client(['127.0.0.1:11211'])

class DetachedORMObject(object):
    """
    Session-detached object for use with ORM Mapping.  As the SQLAlchemy
    documentation indicates, creating and closing a session is not analogous
    to creating and closing a database connection.  Connections are pooled by
    the database engine by default.  Creating new sessions is of a minimal
    cost.  Also, objects using this wrapper will not likely interact in with
    the database through the full power of SQLAlchemy queries.

    """
    @classmethod
    def fetch_by_field(cls, field, value):
        """Fetch a mapped orm object with the give field and value"""
        session = SQLA_SESSION()
        try:
            class_object = session.query(cls).filter(field == value).one()
        except sqlalchemy.orm.exc.NoResultFound:
            class_object = None
        finally:
            session.close()
        return class_object

    def update(self):
        """Update the database with the values of the object"""
        session = SQLA_SESSION()
        session.add(self)
        session.commit()
        session.refresh(self)
        session.close()

    def refresh(self):
        """Refresh the object with the values of the database"""
        session = SQLA_SESSION()
        session.add(self)
        session.refresh(self)
        session.close()

    def delete(self):
        """Delete the object from the database"""
        session = SQLA_SESSION()
        session.add(self)
        session.delete(self)
        session.commit()
        session.close()


class MemcachedObject(object):
    """
    Object Wrapper for serializing objects in memcached. Utilizes an abstract
    method, get_isntance_key, to understand how to get and set objects that
    impliment this class.
    """
    @classmethod
    def get_cached_instance(cls, instance_key):
        """Retrieve and return the object matching the instance_key"""
        key = str(cls.__module__ + '.' + cls.__name__ + ':' \
           + str(instance_key))
        print "Memcached Getting:", key
        return MEMCACHED_CLIENT.get(key)

    def set_cached_instance(self, time=0, min_compress_len=0):
        """Set the cached instance of an object"""
        print "Memcached Setting:", self.get_cache_key()
        return MEMCACHED_CLIENT.set(self.get_cache_key(), self, time, \
            min_compress_len)

    def delete_cached_instance(self, time=0):
        """Wrapper for the memcached delete method"""
        print "Memcached Deleting:", self.get_cache_key()
        return MEMCACHED_CLIENT.delete(self.get_cache_key(), time)

    def get_cache_key(self):
        """Prepends the full class path of the object to the instance key"""
        return self.__class__.__module__ + '.' + \
            self.__class__.__name__ + ':' + self.get_instance_key()

    def get_instance_key(self):
        """Get the instance key, must be implemented by child objects"""
        raise NotImplementedError \
            ("'GetInstanceKey' method has not been defined.")


class MemcachedORMObject(DetachedORMObject, MemcachedObject):
    """
    Putting it all together now.  Implements both of the above classes. Worth
    noting is the method for checking to see if the fetch_by_field method is
    invoked using a primary key of the class.  The same technique is used to
    generate an instance key for an instance of the class.
    """
    @classmethod
    def fetch_by_field(cls, field, value):
        """Fetch the requested object from the cache and database"""
        orm_object = None
        matched_primary_key = True
        for key in cls._sa_class_manager.mapper.primary_key:
            if field.key != key.key:
                matched_primary_key = False
        if matched_primary_key:
            orm_object = cls.get_cached_instance('(' + str(value) + ')')
        if orm_object is None:
            orm_object = super(MemcachedORMObject, cls). \
                fetch_by_field(field, value)
            if orm_object is not None:
                orm_object.set_cached_instance()
        return orm_object

    def update(self):
        """Update the object in the database and memcached"""
        DetachedORMObject.update(self)
        self.set_cached_instance()

    def refresh(self):
        """Refresh the object from the database and memcached"""
        DetachedORMObject.refresh(self)
        self.set_cached_instance()

    def delete(self):
        """Delete the object from the database and memcached"""
        DetachedORMObject.delete(self)
        self.delete_cached_instance()

    def get_instance_key(self):
        """Get the instance key, implimenting abstract method in base"""
        key = []
        for column in self._sa_instance_state.manager.mapper.primary_key:
            key.append('(' + str(getattr(self, column.key)) + ')')
        return ''.join(key)

不确定这是否有帮助,但是您可以看到 memcached 惯用语的使用:

    if matched_primary_key:
        orm_object = cls.get_cached_instance('(' + str(value) + ')')
    if orm_object is None:
        orm_object = super(MemcachedORMObject, cls). \
            fetch_by_field(field, value)

1
Pylons 推荐使用 Beaker 进行缓存,它具有 Memcache 后端。请参见 这里

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接