一位同事提出了一個似乎對我們的用例足夠好的想法,所以在這裏分享。基本的想法是,你創建了你想要使用的memcache客戶端的數量,把它們放入一個隊列中,並且每當你需要一個memcache客戶端時,你就從隊列中取出一個客戶端。由於Queue.Queue get()方法具有可選的超時參數,因此您還可以處理無法及時獲取客戶端的情況。您還需要在memcache客戶端中處理threading.local的使用。
下面是它如何在代碼中工作(請注意,我沒有真正運行此確切版本,因此可能會出現一些問題,但是如果文本描述對您沒有意義,這應該會給您一個想法):
import Queue
import memcache
# See http://stackoverflow.com/questions/9539052/python-dynamically-changing-base-classes-at-runtime-how-to
# Don't inherit client from threading.local so that we can reuse clients in
# different threads
memcache.Client = type('Client', (object,), dict(memcache.Client.__dict__))
# Client.__init__ references local, so need to replace that, too
class Local(object): pass
memcache.local = Local
class PoolClient(object):
'''Pool of memcache clients that has the same API as memcache.Client'''
def __init__(self, pool_size, pool_timeout, *args, **kwargs):
self.pool_timeout = pool_timeout
self.queue = Queue.Queue()
for _i in range(pool_size):
self.queue.put(memcache.Client(*args, **kwargs))
def __getattr__(self, name):
return lambda *args, **kw: self._call_client_method(name, *args, **kw)
def _call_client_method(self, name, *args, **kwargs):
try:
client = self.queue.get(timeout=self.pool_timeout)
except Queue.Empty:
return
try:
return getattr(client, name)(*args, **kwargs)
finally:
self.queue.put(client)
這是一個非常不錯的解決方案,非常感謝! – Goin
我不是爲什麼,但我的表現在時間上是通過使用池,然後使用單個客戶端 – userRaj