3

I'm looking to create a distributed Lock within Redis on Azure for our multi-instance Worker Role. I need a way of creating "critical sections" for which only a single thread can have access at a time across multiple-instances of the Worker Role.

I am using the StackExchange.Redis client to do this and, helpfully, it has an implementation of transactional TakeLock\ReleaseLock already, and this answer on SO gives me a good idea of the pattern to use and details about how to create a lock.

Reading further around the subject, I also read this Redis article regarding distlock which describes the weaknesses of failover-based Redis nodes when trying to implement a distributed lock mechanism.

The Azure Redis cache implements master/slave failover (apart from the Basic tier) so does this mean that I will need to implement the redlock pattern in order to guarantee that only one thing will ever have the lock?

Additionally, I am wondering:

  • Why do Azure Redis example connection strings not seem to list the master and slave in them? Have Azure implemented the master/slave failover in a different way?
  • Why has one .NET implementation of redlock chosen not to support using master/slaves in its usage? (See Usage section, first para) Is this just by choice or is it because master/slave is not a valid usage of redlock (that would not seem to be the case in the redis article)
Community
  • 1
  • 1
oatsoda
  • 2,088
  • 2
  • 26
  • 49

1 Answers1

3

I'm the author of the RedLock.net library that you linked in your question. The reason the documentation specifies connecting to independent redis instances is based on the reasoning in the Redis Distlock documentation. By forcing writes only to master nodes, we hopefully avoid the situation where a user might misconfigure Redlock to connect to multiple replicated hosts.

According to Azure Redis Cache 103 - Failover and Monitoring there is a load balancer in front of an Azure Redis Cache (at the standard tier and above) that ensures that you are always connected to the master.

Connecting to multiple redis instances (either replicated or not) should give a fairly good guarantee that no two processes end up running at the same time (moreso than a single replicated instance).

In order for another process to 'steal' the lock before the first had finished, more than half of the independent redis instances would need to lose their lock keys (e.g. by restarting without persistence), then have process two gain the lock before the timer in process one reacquired it during its extend timer.

Sam
  • 341
  • 1
  • 4
  • I read the redlock article and also watched the video. Can I assume that if I use one azure instance, we would have this scenario: "There is an obvious race condition with this model: Client A acquires the lock in the master. The master crashes before the write to the key is transmitted to the slave. The slave gets promoted to master. Client B acquires the lock to the same resource A already holds a lock for. SAFETY VIOLATION! " – Alex Maie Apr 13 '16 at 08:36
  • 1
    @AlexMaie: yes, I believe so. If you want stronger safety against multiple clients entering a critical section, then using the distlock algorithm with multiple independent masters (or multiple independent master/slave replicated sets) should be safer. – Sam Apr 14 '16 at 16:16