Introduction
Microservice architecture is widely adopted these days. One of the benefits is that offers the possibility of horizontal scaling, which allows us to increase the performance of our application dramatically. However, there are situations when multiple instances of service face contention for some shared resource.
Consider a service that, apart from other functionalities, runs some mission-critical job once per day which should be executed in a single instance. At the same time, the deployment of a single instance is counterproductive, since a microservice bears other functionalities which would benefit from horizontal scaling. One may argue that we can split such microservice into even smaller microservices, but I'd be cautious against making microservices too granular.
Another reason might be the poor man's failover scenario, where one instance of a service executes work, while the other is idle and waits just in case the first instance fails for some reason.
As a solution, I offer to elect a single leader which would handle shared resource exclusively at a single point of time.
Such well-known leader election algorithms such as the Bully algorithm or Ring algorithm require a lot of ceremony and knowledge of the logical topology of your system in order to be implemented. That's the reason why we'll have a look at leader election using a distributed lock. You should use this pattern when the tasks in a distributed application need careful coordination and there's no natural leader.
As storage for a distributed lock, we'll use Redis. Redis is in-memory key-value storage so we'll take advantage of its speed. There is already a library that implements distributed lock over Redis. So we just have to make use of it.
The code
The sample code can be accessed on GitHub. Let's break down what actually happens here.
The idea behind leader election via distributed lock is whoever acquires lock over shared resource becomes a leader. So naturally, we have a lock key quite similar to the built-in C# `lock` construct.
- private const string _resource = "the-thing-we-are-locking-on";
Obviously, storage is a single point of failure so we have to make sure that it is reliable. RedLock.net which we use for our case allows us to use multiple instances of Redis instead of single in order to improve reliability.

Join the conversation! Your thoughts help the community grow.