Reputation: 5717
Imagine following scenario:
Everything works fine. Let's add another client between 4 and 5:
Database returns object A
Now object A is up to date in database, but outdated in Redis. Are there any patterns to prevent such behaviour? Obviously locking the database while waiting for Redis to store its copy isn't a solution.
I should also note I'm using NodeJS which maintains a fixed size connection pool to Redis and requests are processed asynchronously, so we can't assume that the order of queries from different clients won't be mixed in a single connection.
Upvotes: 1
Views: 1166
Reputation: 183
If your data are not changed often (non-volatile), as in Historical data from yesterday or a month ago, you can safely ignore the race condition, because no matter who got the last commit, data is still the same across clients.
For time sensitive data, especially transaction data, you can separate the cache based on user id by using user id (Client#1, Client#2) as the additional Key. This will eliminate race condition between clients without resorting to locking and transaction synchronization with drawback of higher memory usage.
This method can be combined with the first method e.g. if the data is about user specific data, you can use user id key, and on the other hand if the data contains shared/grouping information like menu access based on role, you can use the group id instead.
Upvotes: 1
Reputation: 158
If there is not an update operation on object (5th step), you should use SETNX to store it. So you don't store outdated object.
Upvotes: 0
Reputation: 17505
You're looking for Redis transactions. The key is the WATCH
command. You call WATCH
on object A before the initial read, and set the object inside a MULTI
. Now your two scenarios look like:
and
Database returns object A
After failure, Client #1 could retry, but it's probably better to just ignore the failure, since it appears that you're just using it as a cache.
Client #2, of course, should have also done the WATCH/MULTI/EXEC pattern.
Upvotes: 0