Aller au contenu principal

Un article tagués avec « distributed-locks »

Voir tous les tags

Les verrous distribués expliqués

· 5 minutes de lecture
Clustron Team
Ingénierie des systèmes distribués

Un guide pratique pour les développeurs .NET

Introduction​

À mesure que les applications montent en charge sur plusieurs machines, la coordination devient l'un des aspects les plus délicats de la conception des systèmes.

Dans une application mono-machine, l'exclusion mutuelle est simple. Les développeurs peuvent s'appuyer sur des primitives du langage telles que lock en C#, Mutex ou Semaphore pour garantir qu'un seul thread accède à une ressource partagée à la fois.

Cependant, ces primitives ne fonctionnent qu'au sein d'un seul processus ou d'une seule machine.

Dès lors que les applications s'exécutent sur plusieurs services ou nœuds, les mécanismes de verrouillage traditionnels ne fonctionnent plus. Deux services s'exécutant sur des machines différentes ne peuvent pas s'appuyer sur une instruction lock locale pour coordonner l'accès à un état partagé.

C'est ici que les verrous distribués deviennent essentiels.

Les verrous distribués permettent aux services répartis sur un cluster de coordonner l'accès aux ressources partagées tout en garantissant qu'un seul participant détient le verrou à un instant donné.


Verrous locaux vs verrous distribués​

Un verrou local typique en C# ressemble à ceci :

private static readonly object _lock = new object();

public void ProcessOrder()
{
lock(_lock)
{
Console.WriteLine("Processing order safely.");
}
}

Cela fonctionne parfaitement à l'intérieur d'un seul processus.

Cependant, si votre application s'exécute sur plusieurs instances de service, chaque instance possède son propre objet _lock. Le verrou ne coordonne plus le travail à l'échelle du système.

Worker A → lock acquired Worker B → lock acquired Worker C → lock acquired

Tous les workers progressent simultanément, ce qui annule l'intérêt du verrouillage.

Les systèmes distribués nécessitent un mécanisme de coordination partagé.


Verrouillage distribué


L'idée derrière les verrous distribués​

Un verrou distribué utilise un système partagé pour représenter la possession du verrou.

Au lieu de verrouiller la mémoire, un nœud enregistre la possession du verrou dans un système de coordination distribué tel que :

  • un store clé-valeur distribué
  • un service de coordination
  • un cache distribué

Concept d'exemple :

Lock Key: order:123 Owner: worker‑1

Si un autre worker tente d'acquérir le même verrou, l'opération échoue jusqu'à ce que le verrou soit libéré ou expire.


Scénario concret : traitement distribué de factures​

Imaginez un cluster de workers traitant des factures.

Worker A Worker B Worker C

Tous les workers recherchent les factures en attente.

Sans verrouillage :

Worker A → processes invoice #101 Worker B → processes invoice #101 Worker C → processes invoice #101

La même facture pourrait être traitée plusieurs fois.

Un verrou distribué garantit qu'un seul worker traite la facture.


Les verrous distribués avec Clustron DKV​

Clustron DKV fournit des primitives intégrées pour la coordination distribuée.

Les verrous sont gérés via l'API Locks, et les opérations sur les clés verrouillées doivent inclure le bon handle de verrou.


Acquérir un verrou​

Un client acquiert d'abord un verrou pour une clé spécifique.

var locks = ((IDkv)client).Locks;

var key = "order:123";

var lockHandle = await locks.AcquireAsync(key, TimeSpan.FromSeconds(10));

if (lockHandle == null)
{
Console.WriteLine("Failed to acquire lock.");
return;
}

Console.WriteLine("Lock acquired.");

Le handle de verrou renvoyé représente la possession du verrou.


Effectuer des opérations sous le verrou​

Une fois un verrou acquis, les opérations doivent inclure le handle de verrou.

var result = await client.PutAsync(
key,
"processed",
Put.WithLock(lockHandle.Handle));

if (result.IsSuccess)
{
Console.WriteLine("Value updated safely.");
}

Seul le propriétaire du verrou peut modifier la valeur.


Lire avec le verrou​

Les lectures peuvent elles aussi respecter la possession du verrou.

var value = await client.GetAsync<string>(
key,
Get.WithLock(lockHandle.Handle));

if (value.IsSuccess)
{
Console.WriteLine($"Value: {value.Value}");
}

Opérations concurrentes sans le verrou​

Si un autre worker tente de modifier la clé sans le verrou, l'opération échoue.

var attempt = await client.PutAsync(key, "new-value");

if (!attempt.IsSuccess)
{
Console.WriteLine($"Operation rejected: {attempt.Status}");
}

Résultat :

KvStatus.Locked

Cela empêche la modification concurrente de la même ressource.


Libérer le verrou​

Une fois le travail terminé, le verrou peut être libéré.

await lockHandle.ReleaseAsync();

Console.WriteLine("Lock released.");

Après la libération du verrou, un autre worker peut l'acquérir.


Exemple de workflow de cluster​

Worker A → Acquire Lock → Success Worker B → Acquire Lock → Failed Worker C → Acquire Lock → Failed

Worker A → Update Key Worker A → Release Lock

Un seul worker effectue l'opération, garantissant la correction.


Gérer les défaillances​

Les verrous dans Clustron sont bornés dans le temps.

Lors de l'acquisition d'un verrou, une durée doit être spécifiée :

await locks.AcquireAsync(key, TimeSpan.FromSeconds(10));

Si le client détenant le verrou s'arrête brutalement ou se déconnecte, le verrou finit par expirer, ce qui permet à un autre worker de l'acquérir.

Cela évite que les verrous ne restent détenus indéfiniment.


Bonnes pratiques​

Lorsque vous implémentez des verrous distribués :

  • Gardez les sections critiques courtes
  • Évitez les verrous globaux lorsque c'est possible
  • Partitionnez les verrous par ressource
  • Concevez toujours en prévoyant les scénarios de défaillance

En conclusion​

Les verrous distribués sont l'une des primitives de coordination les plus fondamentales des systèmes distribués.

Ils permettent aux services s'exécutant sur plusieurs machines de coordonner en toute sécurité l'accès aux ressources partagées tout en préservant la correction du système.

Des plateformes comme Clustron DKV simplifient cela en fournissant des primitives de verrouillage intégrées, des opérations atomiques et de fortes garanties de cohérence.

Dans le prochain article, nous explorerons une autre primitive essentielle des systèmes distribués :

l'élection de leader.