Archive for July 28th, 2008

python-memcache内存泄露问题

Monday, July 28th, 2008

作为广为流行的、独霸一方的一个组件,python-memcache是给python连接memcache用的(废话)。可是就这么个东西居然是如此的垃圾,每每让我惊叹。

1、跟同事合作开发系统,他用Java/PHP,我用Python,需要共同通信的部分用了4台memcache做分布。Java与PHP连接memcache的组件用得相同的分布算法,兼容很好,如果一个键存到一台机器上,就绝对不用再去另外一台上遍历。而Python的这个,用了作者自己写的一套山寨分布算法,与Java/PHP的不兼容。丫的要是Python在TIOBE上排第一名也就算了。Java和PHP都是牛x大发了的东西,你还敢搞不兼容。

2、一套系统,需要定期清除memcache,使另一个系统在发现找不到cache时来访问我的接口。每秒钟执行20次左右,遍历4台memcache上清除共8个键(我也没写兼容的分布算法,于是遍历)。正常运行状况下发现服务器启动时占用8MB内存,可是每10秒左右就增加 2MB的内存使用量。系统上线后两三个小时就把2GB内存占光了,于是死掉。丫的调试了我4天时间,还熬过两次到4:00,最后才发现是python-memcache里面的内存泄露。我已经不在乎具体哪个点在泄漏了。愤怒之下,自己用socket实现了memcache的通信协议,实现了清除指定键的功能。

见过山寨的东西(Pylons),没见过这么山寨的(python-memcache)。

附使用socket实现的memcache协议,清除key部分:
def clear_cache(md5v):
“””使用socket方式清除memcache”””
key1=KEY_CDNJAVA_MEMCACHE1%{‘md5v':md5v}
key2=KEY_CDNJAVA_MEMCACHE2%{‘md5v':md5v}
for mcs in setting.mcserverlist:
hostport=mcs.split(‘:’,1)
if len(hostport)==1:
host=hostport[0]
port=11211
else:
host,port=hostport
port=int(port)
try:
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.settimeout(1)
s.connect((host,port))
cmd=’delete %s\r\n’%key1
s.send(cmd)
s.recv(1024)
cmd=’delete %s\r\n’%key2
s.send(cmd)
s.recv(1024)
s.close()
except socket.error,ex:
print ‘[EX][clear_cache] %s’%str(ex)
return

twisted线程池的一种实现方式

Monday, July 28th, 2008

一个具有并发控制的计数器,控制当前线程数量。线程数不足时就用reactor.callInThread()启动线程。并任线程自然结束。当然,需要在让主控函数形成循环来不停的生成新的线程。这种循环比较适合用reactor.callLater()来实现,而不是用while True的循环。毕竟twisted是事件驱动的,如果一个函数死循环了,那么其他函数就没有执行的机会了。

在对twisted中使用线程,多次尝试之后,我就是使用了上面的方法。感觉比以前靠谱了很多。