1

在检查了一大堆东西之后,我发现对于某些键,python-memcached 只是无法获取或在我的机器上设置它们(Mac OSX 10.9,自制 memcache 1.4.15,pip installed python-memcached 1.53) . 我的第一个问题是在黑暗中拍摄,不清楚发生了什么,但经过更多挖掘后,我现在确定了。

这一切都取决于 def _get_server(self, key):

如果我们添加两个调试打印输出行,

def _get_server(self, key):
    if isinstance(key, tuple):
        serverhash, key = key
    else:
        serverhash = serverHashFunction(key)

    for i in range(Client._SERVER_RETRIES):
        server = self.buckets[serverhash % len(self.buckets)]
        if server.connect():
            #print "(using server %s)" % server,
            print 'got server {} for {}'.format(serverhash % len(self.buckets),
                                                key)
            return server, key
        print 'server {} failed for {}'.format(serverhash % len(self.buckets),
                                            key)
        serverhash = serverHashFunction(str(serverhash) + str(i))
    return None, None

试图获取或设置密钥'NFL::CAR_TB',

import memcache
mc_cl = memcache.Client('127.0.0.1')
mc_cl.set('JAC_SF', 1)
mc_cl.get('JAC_SF')
mc_cl.set('UAC_SF', 1)
mc_cl.get('UAC_SF')

结果,在我的机器上,

server 3 (inet:.:11211 (dead until 1384821475)) failed for JAC_SF
server 7 (inet:.:11211 (dead until 1384821475)) failed for JAC_SF
server 3 (inet:.:11211 (dead until 1384821475)) failed for JAC_SF
server 2 (inet:7:11211 (dead until 1384821475)) failed for JAC_SF
server 5 (inet:.:11211 (dead until 1384821475)) failed for JAC_SF
server 7 (inet:.:11211 (dead until 1384821475)) failed for JAC_SF
server 3 (inet:.:11211 (dead until 1384821475)) failed for JAC_SF
server 7 (inet:.:11211 (dead until 1384821475)) failed for JAC_SF
server 7 (inet:.:11211 (dead until 1384821475)) failed for JAC_SF
server 2 (inet:7:11211 (dead until 1384821475)) failed for JAC_SF
server 3 (inet:.:11211 (dead until 1384821475)) failed for JAC_SF
server 7 (inet:.:11211 (dead until 1384821475)) failed for JAC_SF
server 3 (inet:.:11211 (dead until 1384821475)) failed for JAC_SF
server 2 (inet:7:11211 (dead until 1384821475)) failed for JAC_SF
server 5 (inet:.:11211 (dead until 1384821475)) failed for JAC_SF
server 7 (inet:.:11211 (dead until 1384821475)) failed for JAC_SF
server 3 (inet:.:11211 (dead until 1384821475)) failed for JAC_SF
server 7 (inet:.:11211 (dead until 1384821475)) failed for JAC_SF
server 7 (inet:.:11211 (dead until 1384821475)) failed for JAC_SF
server 2 (inet:7:11211 (dead until 1384821475)) failed for JAC_SF
server 7 (inet:.:11211 (dead until 1384821475)) failed for UAC_SF
got server 6 for UAC_SF
server 7 (inet:.:11211 (dead until 1384821475)) failed for UAC_SF
got server 6 for UAC_SF

如果我将 _get_server 更改为

def _get_server(self, key):
    choices = range(len(self.buckets) - 1)
    random.shuffle(choices)

    if isinstance(key, tuple):
        choice, key = key
    else:
        choice = choices.pop()

    for _ in range(Client._SERVER_RETRIES):
        server = self.buckets[choice]
        if server.connect():
            #print "(using server %s)" % server,
            print 'got server {} for {}'.format(choice,
                                                key)
            return server, key
        print 'server {} ({}) failed for {}'.format(choice, server, key)
        choice = choices.pop()
    return None, None

然后一切都会好很多,

got server 4 for JAC_SF
server 0 (inet:1:11211 (dead until 1384821552)) failed for JAC_SF
server 3 (inet:.:11211 (dead until 1384821552)) failed for JAC_SF
got server 4 for JAC_SF
server 7 (inet:.:11211 (dead until 1384821552)) failed for UAC_SF
server 0 (inet:1:11211 (dead until 1384821552)) failed for UAC_SF
got server 6 for UAC_SF
server 7 (inet:.:11211 (dead until 1384821552)) failed for UAC_SF
server 2 (inet:7:11211 (dead until 1384821552)) failed for UAC_SF
server 5 (inet:.:11211 (dead until 1384821552)) failed for UAC_SF
server 1 (inet:2:11211 (dead until 1384821552)) failed for UAC_SF
got server 6 for UAC_SF
尝试在我的 python 程序中设置多个键时,我得到了非常不一致的结果, import memcache TWO_HOURS = 2 * 60 * 60 mc_cl = memcache.Client('127.0.0.1') mapping = {...} mc_cl.flush_all() ret = mc_cl.set_multi(mapping=mapping, time=TWO_HOURS) getret = mc_cl.get_multi(mapping.keys()) if len(mapping) != len(getret): print 'not set\n\t{}'。 format('\n\t'.join([str((k, mapping[k])) for k in [a for a in mapping.keys() if a not in getret.keys()]])) 和在分析原始 memcache 输出之后,似乎并不是所有的键都被设置了,之后也不是所有的键都被请求了。在 Mac OSX 10.9 上的 homebrew 和 pip 上完成的所有事情都是最新的。下面的 Memcache 输出和读取表明只有 101 个键被尝试写入和读取,而有 228 个项目。import re gamesSet = [] gamesGet = [] with open('memout.log') as f: for line in f.read().split('\n'): match = re.match('^21 OK 22好的 21 已存储
4

1 回答 1

0

这是一个奇怪的问题,我目前正在与 python-memcached 库的编写者/维护者辩论,https://github.com/linsomniac/python-memcached/issues/21

随机地,这里出了问题的是第一行,

mc_cl = memcache.Client('127.0.0.1')

客户端期望一个可迭代的,但不确保检查它是否没有得到一个字符串,所以以一种非常pythonic的方式,它将这个字符串视为一个可迭代的并遍历它,设置'1','2'中的每一个, '7' '。'0' 是 memcached 服务器的 IP 地址,但真正令人困惑的是,'0' 实际上是一个有效的 IP 地址,计算结果为 0.0.0.0 并由您的本地 memcached 服务器提供服务,如果是这样的话你已经设置好了(这就是我的开发环境的设置方式)。

如果您只是将其更改为,

mc_cl = memcache.Client(('127.0.0.1',))

一切都按预期工作,但是如果您传入 '127.0.0.1' 字符串,您不会收到任何错误消息,也不会收到任何关于未设置键的报告,也无法“获取”,只是非常不稳定和像上面那样不可解释的行为。

于 2013-12-05T17:54:24.653 回答