Inconsistent data with node failover cache

I ran into a problem when the data in my database reverts to the old state. I think I narrowed the problem down to this situation.

Imagine a sequence of two purchases, as follows:

  • All cache nodes work
  • The user is registered (data is extracted from the database and stored in memcached)
  • Node cache not working
  • The user continues to browse (and since their data cannot be found in the cache, it is extracted from the database and stored in memcached)
  • The user performs some action that converts their record [for example, alignment up] (their record is updated in the cache and database)
  • Node cache returns
  • We again retrieve user data from the cache and proceed from the original node cache, which was previously
  • Now we have a problem: node in the cache is out of date!
  • The user does another action that transforms his record.
  • This is stored in the cache and database, but since it was based on an obsolete record, it stomps in the previous change and effectively returns it

Now we have lost data because the database record was overwritten with partially outdated information.

How can I prevent this with PHP5 and libmemcached with persistent connections? I think I want the node cache to not turn on at all; it should just not read and write to node, but not remove it from the pool so that I don't get duplicate entries.

This will increase the load on my database by 1 / n (where n is the total number of cache nodes) when the node is omitted, but this is better than ending with inconsistent data.

Unfortunately, it’s hard for me to figure out which settings I need to change in order to get this behavior.

+7
php caching memcached libmemcached
source share
2 answers

I like version control and the optimistic locking approach implemented in Doctrine ORM. You can do the same. It will not increase the load on your database, but it will require some refactoring.

Basically, you add a version number to all cached tables, change your update requests to increase version = version + 1 and add a condition where version=$version (note that $version comes from your php / memcache). You will need to check the number of rows affected and throw an exception if it is 0.

It is up to you how to deal with such an exception. You can simply invalidate the cache for this entry and ask the user to resubmit the form or try to merge the changes. At this stage, you have obsolete data from the cache, updating from user input and fresh data from the database, so the only incorrigible case is when you have 3 different values ​​for the same column.

+2
source share

you make the problem more complicated, a simple approach is to simply mark the cache dirty and rebuild it, and not just return it to the service with inconsistent data on it.

+1
source share

All Articles