Skip to content

Can't get, or set 'NFL::CAR_TB' #21

@seaders

Description

@seaders

After checking a whole loada things, I've found that for some keys, python-memcached just won't get, or set them on my machine (homebrew'd 1.4.15, pip installed python-memcached 1.53 on Mac OSX 10.9). My first issue was a shot in the dark, not having a clear idea as to what was going on, but after more digging I now definitely now.

It all hinges around
def _get_server(self, key):

If we add two debug printout lines,

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

Trying to get or set the key 'NFL::CAR_TB',

import memcache
mc_cl = memcache.Client('127.0.0.1')
mc_cl.set('NFL::CAR_TB', 1)
mc_cl.get('NFL::CAR_TB')
mc_cl.set('NFL::CAR_UB', 1)
mc_cl.get('NFL::CAR_UB')

results, on my machine with,

server 7 (inet:.:11211 (dead until 1384820703)) failed for NFL::CAR_TB
server 8 (inet:1:11211 (dead until 1384820703)) failed for NFL::CAR_TB
server 3 (inet:.:11211 (dead until 1384820703)) failed for NFL::CAR_TB
server 8 (inet:1:11211 (dead until 1384820703)) failed for NFL::CAR_TB
server 0 (inet:1:11211 (dead until 1384820703)) failed for NFL::CAR_TB
server 7 (inet:.:11211 (dead until 1384820703)) failed for NFL::CAR_TB
server 7 (inet:.:11211 (dead until 1384820703)) failed for NFL::CAR_TB
server 5 (inet:.:11211 (dead until 1384820703)) failed for NFL::CAR_TB
server 1 (inet:2:11211 (dead until 1384820703)) failed for NFL::CAR_TB
server 5 (inet:.:11211 (dead until 1384820703)) failed for NFL::CAR_TB
server 7 (inet:.:11211 (dead until 1384820703)) failed for NFL::CAR_TB
server 8 (inet:1:11211 (dead until 1384820703)) failed for NFL::CAR_TB
server 3 (inet:.:11211 (dead until 1384820703)) failed for NFL::CAR_TB
server 8 (inet:1:11211 (dead until 1384820703)) failed for NFL::CAR_TB
server 0 (inet:1:11211 (dead until 1384820703)) failed for NFL::CAR_TB
server 7 (inet:.:11211 (dead until 1384820703)) failed for NFL::CAR_TB
server 7 (inet:.:11211 (dead until 1384820703)) failed for NFL::CAR_TB
server 5 (inet:.:11211 (dead until 1384820703)) failed for NFL::CAR_TB
server 1 (inet:2:11211 (dead until 1384820703)) failed for NFL::CAR_TB
server 5 (inet:.:11211 (dead until 1384820703)) failed for NFL::CAR_TB
got server 6 for NFL::CAR_UB
got server 6 for NFL::CAR_UB

If I alter _get_server to

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

Then everything works much better,

got server 4 for NFL::CAR_TB
server 1 (inet:2:11211 (dead until 1384820883)) failed for NFL::CAR_TB
server 7 (inet:.:11211 (dead until 1384820883)) failed for NFL::CAR_TB
server 0 (inet:1:11211 (dead until 1384820883)) failed for NFL::CAR_TB
server 2 (inet:7:11211 (dead until 1384820883)) failed for NFL::CAR_TB
got server 4 for NFL::CAR_TB
server 1 (inet:2:11211 (dead until 1384820883)) failed for NFL::CAR_UB
server 3 (inet:.:11211 (dead until 1384820883)) failed for NFL::CAR_UB
got server 4 for NFL::CAR_UB
server 1 (inet:2:11211 (dead until 1384820883)) failed for NFL::CAR_UB
got server 6 for NFL::CAR_UB

~~
multi_get and multi_set not getting / setting all keys

I was getting very inconsistent results when trying to set multiple keys in my python program,

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()]]))

And after analysing the raw memcache output, it seems like not all the keys are being set, and not all the keys are being requested thereafter. All things done and up to date on homebrew and pip, on Mac OSX 10.9.

Memcache output below and reading it states that only 101 keys were attempted to be written and read, whereas there were 228 items.

import re

gamesSet = []
gamesGet = []
with open('memout.log') as f:
    for line in f.read().split('\n'):
        match = re.match('^<21 set ([^ ]+) .*$', line)
        if match is not None:
            gamesSet.append(match.group(1))
            continue
        match = re.match('^<21 get (.*)$', line)
        if match is not None:
            gamesGet += match.group(1).split(' ')
            continue
print len(mapping), mapping
print len(gamesSet), gamesSet
print len(gamesGet), gamesGet

That log is below.

<21 new auto-negotiating client connection
21: Client using the ascii protocol
<21 flush_all
>21 OK
<22 new auto-negotiating client connection
22: Client using the ascii protocol
<22 flush_all
>22 OK
<21 set NCAAF::BUFF_KENTST 1 7200 34
>21 STORED
<21 set NCAAF::ND_USC 1 7200 29
>21 STORED

~~

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions