6

我有一个使用pylibmc 模块连接到 memcached 服务器的 python web 应用程序。如果我每秒使用请求一次或更慢的速度测试我的应用程序,则一切正常。但是,如果我每秒发送一个以上的请求,我的应用程序就会崩溃,并且我会在日志中看到以下内容:

函数“memcached_get_by_key”的断言“ptr->query_id == query_id +1”失败,可能是“程序员错误,query_id 未增加。”,位于 libmemcached/get.cc:107

函数“memcached_get_by_key”的断言“ptr->query_id == query_id +1”失败,可能是“程序员错误,query_id 未增加。”,位于 libmemcached/get.cc:89

知道出了什么问题或如何解决吗?

我的代码如下所示:

self.mc = pylibmc.Client(
    servers=[os.environ.get(MEMCACHE_SERVER_VAR)],
    username=os.environ.get(MEMCACHE_USER_VAR),
    password=os.environ.get(MEMCACHE_PASS_VAR),
    binary=True
    )

#...

if (self.mc != None):
    self.mc.set(key, stored_data)

#...

page = self.mc.get(key)
4

2 回答 2

4

这是一个线程问题。pylibmc 客户端不是线程安全的。您应该将代码转换为使用ThreadMappedPool 对象,以确保为每个线程保持单独的连接。像这样的东西:

mc = pylibmc.Client(
    servers=[os.environ.get(MEMCACHE_SERVER_VAR)],
    username=os.environ.get(MEMCACHE_USER_VAR),
    password=os.environ.get(MEMCACHE_PASS_VAR),
    binary=True
    )
self.pool = pylibmc.ThreadMappedPool(mc)

#...

if (self.pool != None):
    with self.pool.reserve() as mc:
        mc.set(key, stored_data)

#...

if (self.pool != None):
    with self.pool.reserve() as mc:
        page = mc.get(key)

确保self.pool.relinquish()在线程完成时调用,可能在析构函数中!

(在我的例子中,这是因为我使用cherrypy作为我的网络服务器,并且cherrypy默认生成10个单独的线程来服务请求。)

于 2012-09-14T07:32:08.687 回答
1

我在 Apache 上运行 Django 时遇到了同样的问题。切换pylibmcpython-memcached为我消除了这个问题。

于 2015-02-23T22:30:21.507 回答