Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Redis: Race Condition and Single threaded

Tags:

redis

I'm new to Redis and going through Redis in Action book, which elaborate on Race Conditions and different Locking mechanism to avoid it.(There is one dedicated chapter on it). But in some of the StackOverflow Posts it is discussed that Redis is Single Threaded. The link is as follows : Are redis operations on data structures thread safe

In the above Link(in one of the answer) it is explicitly written that When command is executing no other command will run.

Now my question is : If Redis is Single Threaded, then why need Locking mechanism at all.

Please clarify on it and let me know if I'm wrong anywhere in my understanding.

Also it follows optimistic Locking mechanism, where multiple threads may try to update the data and if data is modified it will get notified to other threads trying to update at same time(as their update is failed, they can again retry the same operation).

like image 515
bharatj Avatar asked May 02 '15 15:05

bharatj


1 Answers

If Redis is Single Threaded, then why need Locking mechanism at all.

Redis is indeed (mostly) single-threaded but locking is required when multiple clients try to do different thing at adjacent temporal proximity. The locking discussed in RiA is about exactly that - ensuring that only one client/thread does a specific task, or making sure that updates don't go awry.

Here's an example why you would need locking despite Redis' single-threadedness: assume you have a value in Redis, a number for example stored under a key named foo. Your app's code reads that number (GET foo), does something it (i.e.g. adds 1) and writes it back (SET). When you run your code in a single thread, this is how it would look:

App               Redis
 |---- GET foo ---->|
 |<------ 1 --------|
 |                  |
 | thinking...      |
 |                  |
 |--- SET foo 2 --->|
 |<----- OK --------|

Now lets see what happens when two app clients try doing this:

App 1             Redis              App 2
 |---- GET foo ---->|                  |
 |<------ 1 --------|<--- GET foo -----|
 |                  |------- 1 ------->|
 | thinking...      |                  |
 |                  |       thinking...|
 |--- SET foo 2 --->|                  |
 |<----- OK --------|<--- SET foo 2 ---|
 |                  |------ OK ------->|

Here you can immediately see what happened without locking, despite the server being (mostly) single threaded - instead of 3, foo's value is 2. As you add more threads/clients/apps, things can go merrily and terribly wrong when multiple writers attempt modifying the data without coordination (i.e.g. locking).

Optimistic locking is just one of the ways to do that, which Redis offers built-in via the WATCH mechanism. Sometimes, however, optimism - despite its easy going and happy nature - isn't the right solution so you'll need to implement better/advanced/different mechanisms to prevent race conditions. Such locks could, arguably, be implemented even outside Redis, but if you're already using it then it makes sense to manage your locks in it as well.

like image 77
Itamar Haber Avatar answered Dec 30 '22 17:12

Itamar Haber