python pylibmc使用

python pylibmc应用

     先看一段memcached的简单介绍:   

Memcached,高性能的分布式内存对象缓存系统,用于动态Web应用以减轻服务器的负载。通过在内存中缓存数据和对象来减少数据的查询次数,从而达到降低负载并提高吞吐量的双丰收。Memcached使用哈希图来储存键值。Memcached由Danga Interactive开发,而被开源以后就为多家公司所用。然而Memcached到了Facebook的手里明显“凶猛”了很多:每秒处理20万UDPS请求,平均延时只有173微妙(虽然总吞吐量一度达到每秒50万UDP,但是由于延时太高未被采用),对比之前的5万每秒UDP无疑是疯狂的提升。

   而pylibmc是memcached提供的python客户端,使用非常方便,官方文档也给出了详细的使用范例:

      http://sendapatch.se/projects/pylibmc/index.html

 初始化一个客户端,对数据的写入、读取、删除操作,加减这样的原子操作都做了使用介绍;

同时还可以定义behaviors来进行适当的优化和个性化的拓展,在优化方面经过实验并没有良好的效果;

 

我们项目使用的是Tokyo Tyrant开源数据库做数据存储,由日本人发明的,兼容memcache协议,在高并发下具有良好的表现;

支持双机互为主辅模式和master-slave机制;目前应对10000/s的响应表现良好,但是双机主辅限制了可拓展性,迟早要换的东西。

 

下面是pylibmc的应用例子,加入了failover机制,能够在一个server断掉的情况下主动连接下一个;

 

import pylibmc   

DB_LOCAL = (('192.168.1.1',11212),('192.168.1.2',11212))

class LocalDb:

    @classmethod
    def open(cls, host_port):
        cls.client_list = []
        for hp in host_port:
            cls.client_list.append(pylibmc.Client(['%s:%d' % hp]))

        cls.client_len = len(cls.client_list)
        cls.cur_idx = 0
        cls.host_port = host_port

        return cls(cls.client_list[cls.cur_idx])

    def _clientIter(self, c):
        # have gone through all clients
        for client in LocalDb.client_list:
            if (client == self.c):
                continue
            yield client

    def __init__(self, client):
        self.c = client

    def __str__(self):
        return 'LocalDb.open() (%s)' % (self.c)

    def _failover(self, oper, *args, **kwargs):
        result = None
        client_iter = self._clientIter(self.c)
        while True:
            try:
                result = getattr(self.c, oper)(*args, **kwargs)
            except:
                logerr('_failover Err: ')
                # faild to conn and choise another one
                try:
                    dbg('Before TT failover (%s)' % self.c)
                    self.c = client_iter.next()
                    dbg('After TT failover (%s)' % self.c)
                    continue
                except StopIteration:  # gone through all clients
                    break
            break
        return result

    def get(self, key):
        return self._failover('get', key)

    def set(self, key, val):
        result = self._failover('set', key, val)
        if (result is None):
            return False
        return True

    def add(self, key, val):
        result = self._failover('add', key, val)
        if (result is None):
            return False
        return True

    def incr(self, key):
        return self._failover('incr', key)

    def decr(self, key):
        return self._failover('decr', key)