6
votes

Verrouillage distribué en .NET

Je recherche des recommandations pour un mécanisme de verrouillage qui fonctionnera sur plusieurs machines. Dans mon cas, je veux fondamentalement simplement pouvoir démarrer un service sur 2 machines et avoir un bloc jusqu'à ce que l'autre se termine comme un moyen simple d'assurer la redondance au cas où une machine de service diminue.

En quelque sorte le long des mêmes lignes que Service de verrouillage distribué mais à la recherche de projets que les gens ont avec succès intégré à .NET.


2 commentaires

Quelqu'un a-t-il trouvé l'un d'eux encore? Je cherche aussi un. Les Paxos et peut-être des algues comme l'algorithme d'intimidation pourraient fonctionner, je suppose? Aimerait voir une implémentation .NET de quelque chose comme ça.


Jetez un coup d'œil à blog.kristandyson.com/2011/01/Distributed-lock. HTML


3 Réponses :


3
votes

Si vous utilisez Appfabric pour Windows Server, vous pouvez utiliser cette extension de datacache . Vous pouvez également utiliser Redis Locks avec Client Redis de ServiceStack .

Les deux sont des implémentations .NET mais nécessitent un composant de serveur. J'ai bricé avec une mise en œuvre de peercanNelEn d'un verrou distribué qui utilise la communication par les pairs et ne nécessite aucune infrastructure de serveur. Faites-moi savoir si c'est quelque chose que vous seriez intéressé.


1 commentaires

Composant de serveur? Comment installer REDIS dans Server Windows Server 2016/2019?



13
votes

Nous utilisons SQLServer's Verrouillage de l'application fonctionnalité pour le verrouillage distribué. Ceci est particulièrement pratique si SQLServer fait déjà partie de votre pile.

Pour que cela facilite le fonctionnement de .NET, j'ai créé un Paquet Nuget qui facilite l'utilisation de cette fonctionnalité. La bibliothèque prend également en charge d'autres backends tels que Postgres, Storage Azure Blob et Redis.

Avec cette bibliothèque, le code ressemble à: xxx

parce que le La fonctionnalité SQLServer sous-jacente est très flexible, il existe également des surcharges supportant la sémantique de TryCrire, les délais d'attente et le verrouillage Async.


12 commentaires

@Peterknaggs Je ne connais pas cette configuration. Si les serveurs sont vraiment séparés et que vous frappez un au hasard, cela ne fonctionnera pas. S'il s'agit de certaines fonctionnalités SQLServer intégrées pouvant synchroniser des choses telles que le verrou de maintien entre les serveurs, cela pourrait fonctionner? Puisque agissant en tant que fournisseur de verrouillage distribué ne prend pas de nombreuses ressources, vous pouvez toujours créer une base de données distincte qui n'est pas chargée équilibrée pour servir de base de données de verrouillage.


Pour les coups de pied pourriez-vous ajouter le code principal ici pour ... quant à la façon dont vous le feriez avec le package Nuget.


Est-ce que l'idée que la ressource que votre verrouillage est le nom lui-même, donc 2 serveurs ... Running emplois ... Assurez-vous que seulement ... Utilisez le même nom de ressource aléatoire. Même Tho "Lockname" n'existe pas réellement comme une chose sur SQL. Je pensais que cela fonctionnerait sur une ressource de table ou des ressources d'objet, mais avoir l'impression que son nom lui-même est-il correct?


@Seabizkit qui est correct. La fonctionnalité de verrouillage de l'application SQL Server vous permet de fonctionner sur des verrous nommés arbitraires (qui sont créés sur la demande dans les coulisses). Cela peut souvent être plus propre que de verrouiller les tables / rangées.


Un réel échantillon utilisant 2 programmes? PROGRAMME A EXECUTE UTILISATION (@ LOCK.ACQUIRE ()) ET PROGRAMME B EXECUTE Utilisation (@ LOCK.ACQUIRE ()) En même temps, les deux.


AVERTISSEMENT: cette approche échappe au pool de connexion


@ALEX Il est vrai que SP_GetApplock contient une connexion ouverte lorsqu'elle s'exécute. Vous pouvez réduire l'impact de cela en utilisant ThacQuire au lieu d'acquérir (si possible). En outre, des versions plus récentes de la bibliothèque multiplex SQLConnections sous la hotte afin que, souvent, plusieurs serrures finissent par être maintenues par une connexion. Enfin, une autre approche consiste à calmer une serrure en mémoire sur le dessus de la distribution si vous avez plusieurs acquéreurs concurrents sur la même machine.


@ChasemeDallion J'ai utilisé ce distributeur de distribution que vous avez créé pour exécuter une tâche par un seul nœud dans un pool de nœuds et fonctionne bien. Mais je suis proposé une situation qui, après avoir acquis la serrure par un nœud si la connexion SQL est tombée (pour ce nœud uniquement) pendant quelques secondes, un autre nœud pourrait aller et acquérir la serrure (car les autres nœuds attendent également d'acquérir la serrure. ). Est-ce que cela peut être manipulé? Quelle est la meilleure pratique consistant à utiliser cela dans un type d'élection de leader d'un mécanisme pour sélectionner un leader à partir d'un pool de nœuds?


@Nlr avec SQL Server Il n'y a pas de bonne façon de le faire parfaitement. Vous pouvez observer la perte de connectivité avec la poignée de la poignée de verrouillage et récupérer, mais il y aura toujours une blip. Si vous souhaitez gérer la perte de connexion, je vous recommanderais d'utiliser la bibliothèque DistribuesLock avec un fournisseur sous-jacent différent (e. G. Redis ou ZookePer) à la place de SQLServer. Certaines d'entre elles utilisent un mécanisme de «bail» qui empêche d'autres threads de ramasser une serrure abandonnée jusqu'à ce qu'un délai d'attente (configurable) puisse être utile dans votre cas.


@Chasemedallion merci beaucoup pour l'information. Malheureusement, nous avons des difficultés (avec notre client) en utilisant d'autres fournisseurs. Donc, vous préférez aller avec SQL Server. Comme vous l'avez dit, ne pouvons-nous pas louer la serrure pour une quantité de temps configurable dans la version SQL Server? afin que nous puissions donner suffisamment de temps pour restaurer les connexions ou nous pouvons être certains que le service ne fonctionne pas


@NLR L'API SQL sous-jacente ne vous donne pas cette flexibilité. Si vous êtes coincé avec SQL, je vous suggérerais d'abord de rechercher des options de configuration pour la rapidité avec laquelle SQL lui-même abandonne les liaisons lorsque les choses vont mal. Une autre option est de construire un mécanisme de location sur le dessus; e. g. Une fois que vous avez réclamé un verrou de verrou, vérifiez une autre table pour voir si une personne a un bail actif (la table pourrait être touchée sur le nom de verrouillage et avoir une autre colonne pour la date d'expiration; lors de la prise de verrouillage, vous vous inséreriez dans la table avec une expiration avec une expiration et lors de la libération de la serrure (enfin bloquer!) Vous enlevez la rangée.


@Chasemedallion merci. J'ai également essayé la table avec l'option de colonne d'expiration et cela semble bien pour le moment.



0
votes

Vous pouvez utiliser un verrouillage pessimiste pour ce cas d'utilisation spécifique à l'aide de NCache. Le verrouillage optimiste est bénéfique pour les scénarios lorsque vous traitez avec des applications intensives de lecture

NCache vous aide à y parvenir. http://blogs.alachisoft.com/ncache/distributed-locking/ xxx


1 commentaires

Ncache pas gratuitement?