6

pylibmc モジュールを使用して memcached サーバーに接続するPython Web アプリがあります。1 秒に 1 回以下のリクエストでアプリをテストすると、すべて正常に動作します。ただし、1 秒間に複数のリクエストを送信すると、アプリがクラッシュし、ログに次のように表示されます。

アサーション "ptr->query_id == query_id +1" が関数 "memcached_get_by_key" で失敗しました。これは、libmemcached/get.cc:107 で、"Programmer error, the query_id was not incremented." の可能性があります。

アサーション "ptr->query_id == query_id +1" が関数 "memcached_get_by_key" で失敗しました。これは、libmemcached/get.cc:89 で、"Programmer error, the query_id was not incremented." の可能性があります。

何がうまくいかないのか、それを修正する方法はありますか?

私のコードは次のようになります。

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を Web サーバーとして使用していたために発生しました。cherrypy は、デフォルトでリクエストを処理するために 10 個の個別のスレッドを生成します。)

于 2012-09-14T07:32:08.687 に答える