简体   繁体   中英

flask app under uwsgi - can't see memcached entries from other workers

So I launched 20 uswgi processes, and I'm using Nginx to load balance them like detailed here

What I'm noticing is that when one worker is hit it will load up memcached after not seeing the results it needs in memcached. Thereafter that workder will find them in memcached. But other workers still won't see the memcached results until they load them up themselves.

Any idea what could be going on? Here's the relevant code:

import memcache
import msgpack
from flask import Flask

app = Flask(__name__, static_url_path = "")
app.config['PROPAGATE_EXCEPTIONS'] = True

class MemCachedWrapper(object):
    """Simple wrapper around memcached to handle translating keys"""
    def make_key(self, key):
        #is this crazy??  memcached only wants strings and won't accept spaces
        return str(key).replace(' ','')
    def __init__(self, servers, debug=0, server_max_value_length=1024*1024*3,
        flush_on_start=False):
        #Set up memcached
        #see README.md for instructions on setting server_max_value_length on memcached (-I option)
        self.cache = memcache.Client(servers, debug=debug,
            server_max_value_length=server_max_value_length)
        if flush_on_start:
            self.cache.flush_all()
    def get(self, key):
        return self.cache.get(self.make_key(key))
    def get_multi(self, keys):
        m = self.make_key
        return self.cache.get_multi([m(k) for k in keys])
    def set(self, key, value):
        return self.cache.set(self.make_key(key), value)
    def delete(self, key):
        return self.cache.delete(self.make_key(key))

cache =MemCachedWrapper([MEMCACHE_URL], debug=0,
        server_max_value_length=MEMCACHE_MAX_VALUE_LENGTH)

def _get_range(key_beg, key_end):
    keys = get_keys(key_beg, key_end)
    def stream_results():
        mc_results = None        
        for scality_key in keys:
            if not mc_results:
                mc_results = cache.get_multi([k[0].encode('utf-8') for k in keys])
            scality_key = scality_key.encode('utf-8')
            obj = mc_results.get(scality_key)
            if obj:
                yield dvid_key, obj
            else:
                print "key miss"
                response = session.get(SCALITY_URL % scality_key)
                cache.set(scality_key, response.content)
                yield dvid_key, response.content
    return stream_results()

@app.route('/api/keyvalue_range/<key_beg>/<key_end>/', methods=['GET'])
def get_range(key_beg, key_end):
    results = _get_range(key_beg, key_end)
    packed = msgpack.packb(list(results), use_bin_type=True)
    return Response(packed, mimetype='application/x-msgpack')


if __name__ == '__main__':
    app.run(host=host, port=PORT, debug=True)

This isn't a great answer, but I ended up using pylibmc as my memcached client library instead and it seems to have fixed the issue. No idea what was going on.

As for changes to the above code, basically just these lines:

import pylibmc as memcache
...
self.cache = memcache.Client(servers, binary=True,
   behaviors={"tcp_nodelay": True, "ketama": True, "no_block": True})

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM