Reputation: 8060
This is my code for memcache getting & setting (everything points to _mc_get)
def _mc_get(key, retrieve_func):
value = memcache.get(key)
if value is not None:
logging.debug("Memcache: hit %s", key)
return value
logging.debug("Memcache: missing + adding %s", key)
value = retrieve_func()
if not memcache.add(key, value, 10):
logging.error('Memcache set failed.')
return value
def mc_get_all_orders():
return _mc_get('Order:all', Order.query().fetch)
def mc_get_tasks_by_order(order_key):
return _mc_get('Order:all', Task.query(Task.order == order_key).order(Task.action).fetch)
def mc_get_tasks_by_orders(order_keys):
return _mc_get('Order:order_id:%s' % sorted([k.id() for k in order_keys]),
Task.query(Task.order.IN(order_keys)).order(Task.action).fetch)
def mc_get_all_producetypes():
return _mc_get('ProduceType:all', ProduceType.query().fetch)
This function is taking >40 seconds on appengine.
@app.route('/orders/schedule/all/', methods=['GET', 'POST'])
@login_required
def generate_schedule_for_all_orders():
"""Merge all the orders together in one big schedule
TODO: put range by default.
TODO: think of default empty scenario
"""
orders = key_dict(mc_get_all_orders())
# TODO: somehow there's a lot of orphaned tasks in development. For now,
# we will just query for non orphaned tasks to prevent errors piling up
tasks = mc_get_tasks_by_orders(orders.keys())
ds = sorted([t.date for t in tasks])
start, end = ds[0], ds[-1]
dates = range_for_dates(start, end)
return render_template('backward_schedule.html',
tasks=tasks,
orders=orders,
producetypes=key_dict(mc_get_all_producetypes()),
dates=dates,
display_order_info=True)
I was wondering why this took so long, so I inserted logging.debug statements on my _mc_get to see if I was hitting or missing memcache. To my surprise, I am missing 100% on memcache if I wait longer than 3 seconds: (This applies to both my dev and production server)
Log for first access to the page: NOTE THE TIME
DEBUG 2014-06-11 23:16:11,765 mc.py:27] Memcache: missing + adding Order:all
DEBUG 2014-06-11 23:16:11,808 mc.py:27] Memcache: missing + adding Order:order_id:[4578366418059264L, 4741094138970112L, 5260063627280384L, 5664683906301952L, 5673479999324160L, 5761440929546240L]
DEBUG 2014-06-11 23:16:12,255 mc.py:27] Memcache: missing + adding ProduceType:all
INFO 2014-06-11 23:16:13,517 recording.py:665] Saved; key: __appstats__:071700, part: 105 bytes, full: 64362 bytes, overhead: 0.002 + 0.010; link: http://localhost:8080/_ah/stats/details?time=1402528571756
Second access to the page (reloading as soon as the first access finished loading)
INFO 2014-06-11 23:16:13,534 module.py:639] default: "GET /orders/schedule/all/ HTTP/1.1" 200 1236559
DEBUG 2014-06-11 23:16:15,638 mc.py:24] Memcache: hit Order:all
DEBUG 2014-06-11 23:16:15,699 mc.py:24] Memcache: hit Order:order_id:[4578366418059264L, 4741094138970112L, 5260063627280384L, 5664683906301952L, 5673479999324160L, 5761440929546240L]
DEBUG 2014-06-11 23:16:15,706 mc.py:24] Memcache: hit ProduceType:all
INFO 2014-06-11 23:16:16,937 recording.py:665] Saved; key: __appstats__:075600, part: 56 bytes, full: 15643 bytes, overhead: 0.000 + 0.004; link: http://localhost:8080/_ah/stats/details?time=1402528575619
Third access to the same page (just hitting refresh): (This is literally 4 seconds after the second access to the same page)
INFO 2014-06-11 23:16:17,112 module.py:639] default: "GET /orders/schedule/all/ HTTP/1.1" 200 1236559
DEBUG 2014-06-11 23:16:23,362 mc.py:27] Memcache: missing + adding Order:all
DEBUG 2014-06-11 23:16:23,415 mc.py:27] Memcache: missing + adding Order:order_id:[4578366418059264L, 4741094138970112L, 5260063627280384L, 5664683906301952L, 5673479999324160L, 5761440929546240L]
DEBUG 2014-06-11 23:16:23,888 mc.py:27] Memcache: missing + adding ProduceType:all
INFO 2014-06-11 23:16:25,153 recording.py:665] Saved; key: __appstats__:083300, part: 105 bytes, full: 64339 bytes, overhead: 0.002 + 0.011; link: http://localhost:8080/_ah/stats/details?time=1402528583353
INFO 2014-06-11 23:16:25,169 module.py:639] default: "GET /orders/schedule/all/ HTTP/1.1" 200 1236559
Why is my memcache expiring so quickly?
Upvotes: 0
Views: 220
Reputation: 2618
There is no guarantee on memcache entry, in theory it can be evicted anytime because memory pressure.
You use memcache.add which only set the value if it is not there. Your timeout is 10 seconds, the memcache was added at 23:16:13 and it is lost when you access it at 23:16:23. That is expected since it's around over 10 seconds. It never prints the memcache add failed because if you find the value, the function return right away.
It's kinda weird that both mc_get_all_orders and mc_get_tasks_by_order using the same key, but different query
Upvotes: 4