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