先看一段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)