1

I am wondering whether having short timeouts (60 seconds) in memcached would have any negative effect on performance, VS longer timeouts, but ignoring the returned value (if it was stored more than 60 seconds ago).

Would having lots of cache misses (if the item has been removed) have an impact on the performance?

Quick note: I would not be re-setting the value if there is a cache miss, just checking for it's existence

Example Scenario:

Consider a case where on your website, you want do prevent double actions (an example would be clicking twice on a PAY button on your website, that registers two payments. We are not dealing with payment in our case).

A simple trick would be keeping user actions in Memcached for a short period -- there are far better ways of doing this of course -- and check for whether the same call has been made within the last few seconds.

Now, you could either set the cache for a short period, and check whether the same action for the user exists in the cache or not. Or, set the last_user_action cache for a long period, along with the time of the action, and the application can check the time against the intended period.

The caveat for short periods would be having lots of cache deletes (expired keys), and a lot of cache misses (since the item has been deleted). The longer period would only use more memory.

So, I'd like to know the overhead of having lots of deletes(expired elements) and cache misses.

Community
  • 1
  • 1
Sina
  • 607
  • 7
  • 22
  • Please explain what you want to do exactly? Proper scenario with example then it could be answered more precisely. – Vickrant Sep 29 '14 at 05:19
  • I've added an example scenario. Think about it as a way of preventing double-clicks/submissions on the server side. – Sina Sep 29 '14 at 14:35
  • I would setup an ab test where you measure the amount of requests that come through using a parameter to turn memcached on and off for lots of hits that incrementally insert memcached data for a very short period of time and then access that data again after expiration and then run that on say 10,000 queries to see what kind of load difference there is to it. Something like: yoursite.com/memcache_test?memcache=on and memcache=off, measure system performance and requests per second – Paul Carlton Sep 30 '14 at 19:28

1 Answers1

1

Don't lie to a Lazy Slab

Your timeouts should exactly match your app's timeouts wanting the entry back (as long as you are OK with a 1-2 second uncertainty.) You wont significantly rise the amount of cache misses memcache internally encounters or cause some form of blocking if many entries expire at the same time. But you will allow memcache to stop handling and returning an item that your app will just need to throw away.

You can find a description of memcached's behavior in Monitoring:Why Isn't curr_items Decreasing When Items Expire? In essence, it does nothing active about an expired entry, instead:

Expired Item Encountered by:

  • get

    don't return it and mark it free

  • store

    always runs get logic first, so now it can reuse the item's space

  • LRU eviction (triggered by store on a full cache)

    don't increment the eviction stats since this item is expired.

Motivated Slab Crawler seeks CPU and lock contention?

The FAQ answer does not mention that you can now optionally have a LRU crawler thread, but it is the nature of a slab allocator that this thread has a relatively small overhead "freeing" expired entries and that work is payed back by simplifying its subsequent traversals.

Don't forget memcache is a LRU Cache

  1. Always be wary of triggering unwanted LRU evictions:

    • If you are also sharing the cache with similar size but longer lived entries you may cause their eviction (which is what the optional crawler is intended to prevent.)

    • If you allow ops * seconds * slab_size(entry) to approach the cache size, entries will begin disappearing before their expiration date.

    But you can observe this in the eviction statistics and could test with artificial traffic and/or proportionally reduced cache space.

  2. If it is restarted, (or your configuration changes, or gets out of sync across app instances, or ...?) you might not find an entry which is not a problem in a cache use case, but in your case you would have to be careful to disallow operations for your delay period.

  3. Given (1) and (2), I probably wouldn't share a special use case where the item is not backed by a safely repeatable operation with your general purpose cache.

undone
  • 7,857
  • 4
  • 44
  • 69
lossleader
  • 13,182
  • 2
  • 31
  • 45
  • Great answer. Just two small sub-questions based on your answer (to complement the answer): 1- Since memcached is LRU based, does it discard the LRU item based on its age, or its LRU strictly? I don't want to have cache purges because of expired items. 2- I am not able to find anything on the optional LRU crawler thread you mentioned. Can you expand on that a little further (and maybe with links for further reading) ? – Sina Oct 03 '14 at 12:39
  • @Sina, a strict LRU would only compare the time of the most recent operation, but memcache favors objects with accesses as that implies utility. The LRU logic doesn't consider expiration just marks eviction if the LRU item wasn't expired. The "LRU crawler" (it crawls in LRU order but applies expiration logic) was introduced in https://code.google.com/p/memcached/wiki/ReleaseNotes1418 and described at: https://github.com/memcached/memcached/blob/master/doc/protocol.txt#L404 as long as you use a independent cache for your use case you don't need it and can avoid using it. – lossleader Oct 03 '14 at 13:25