svenxie / redis

Automatically exported from code.google.com/p/redis
BSD 3-Clause "New" or "Revised" License
1 stars 0 forks source link

Conditional-store with version number should be supported for all operations #530

Closed GoogleCodeExporter closed 8 years ago

GoogleCodeExporter commented 8 years ago
I'm using 2.0.4 on Ubuntu x86 10.10.

I'm not able to prevent race conditions in read-modify-write operations.

1. read some data
2. modify the data
3. write the data back
4. do the same from another process or another host at the same time

The traditional way of doing this is to provide a "version number" per piece of 
data being stored. Any get/read operation will return the version number to the 
reader. Any store operation will take this version number as an argument, and 
if the version number of what's being updated is no longer the same, fail the 
store with a "stale data' error. The user-level operation can then choose to 
re-try, or return an error. This allows cross-system transactional semantics to 
be implemented, which is super important in large, distributed systems with 
many different storage engines.

Original issue reported on code.google.com by jwa...@gmail.com on 19 Apr 2011 at 8:56

GoogleCodeExporter commented 8 years ago
Have you looked at WATCH in the transaction docs?

http://redis.io/topics/transactions

Original comment by jzaw...@gmail.com on 19 Apr 2011 at 9:01

GoogleCodeExporter commented 8 years ago
Thanks for the suggestion. However, that is somewhat different. I don't want to 
use Redis transaction support. Version numbers could conceivably come from some 
external system (so the new version number might actually be provided by the 
conditional-set operation).
Also, the WATCH GET MULTI SET EXEC sequence ends up doing 5 operations for 
something that could be done in 2 with version numbers as GETV CSETV.

Original comment by jwa...@gmail.com on 20 Apr 2011 at 3:28

GoogleCodeExporter commented 8 years ago
If you want something like versioning, why not implement it with INCR for 
versions? You read the current version of a string, INCR its version key and 
write to a new key. That way, you can always test the key holding the version 
to see if the update you did was in fact the latest. A native solution for 
versioning will likely never be added, so we can try and see if we can 
implement something similar using the existing primitives. Can you check if the 
INCR+SET+DEL loop would be applicable in your case?

Original comment by pcnoordh...@gmail.com on 20 Apr 2011 at 8:04

GoogleCodeExporter commented 8 years ago
Why would a native conditional store never be implemented?

Original comment by jwa...@gmail.com on 21 Apr 2011 at 5:41

GoogleCodeExporter commented 8 years ago
Implementing versioned string values is pretty straightforward, but for lists, 
sets, etc, this is a big pain (unless you copy the structure prior to modifying 
it, which can become very expensive for large lists, sets, etc.). Versioning 
where you only keep the latest version, as Redis currently implicitly does, is 
more feasible, and only requires to add an additional key storing the version 
number and a WATCH on that version.

Original comment by pcnoordh...@gmail.com on 21 Apr 2011 at 6:00