Vadim Babaev
Vadim Babaev

Reputation: 490

concurrency writings into memcache

Could you help me with my issue. I have some slow mysql queries, so I'm caching its results into memcache.

I do something like this:

$data = get_from_cache();
if (! $data) {
   $data = get_from_mysql();
   set_cache($data);
}

Problem. Sometimes I have about 10 requests per second. So, when my cache is expiring, I have 5-10 get-requests which are initiating this slow mysql query at the same time.

Could you recommend a pattern for me to make a mutex in php, or something like this, to do only one slow request to mysql.

Upvotes: 3

Views: 1215

Answers (1)

Barmar
Barmar

Reputation: 781716

This is known as the dog pile problem. Strategy: Break Up The Memcache Dog Pile describes two approaches:

Solution 1:

  • Set the cache item expire time way out in the future.
  • Embed the "real" timeout serialized with the value. For example, set the item to timeout in 24 hours, but the embedded timeout might be five minutes in the future.
  • On a get from the cache determine if the stale timeout expired and on expiry immediately set a time in the future and re-store the data as is. This closes down the window of risk.
  • Fetch data from the DB and update the cache with the latest value.

Solution 2:

  • Create two keys in memcached: MAIN key with expiration time a bit higher than normal + a STALE key which expires earlier.
  • On a get read STALE key too. If the stale has expired, re-calculate and set the stale key again.

Upvotes: 4

Related Questions