Aujourd'hui, les entreprises développent des applications Web ASP.NET à fort trafic qui desservent des dizaines de milliers d'utilisateurs simultanés. Plusieurs clients ont accès aux données du cache dans un environnement en cluster où les serveurs d'applications se déploient dans un environnement à charge équilibrée. Dans de telles conditions parallèles, plusieurs utilisateurs essaient souvent d'accéder et de modifier les mêmes données et déclenchent une condition de concurrence.
Une condition de concurrence se produit lorsque deux utilisateurs ou plus essaient d'accéder et de modifier simultanément les mêmes données partagées, mais finissent par le faire dans le mauvais ordre. Cette situation entraîne un risque élevé de perte d'intégrité et de cohérence des données. Avec l'avènement des solutions de mise en cache évolutives en mémoire telles que NCache en fournissant des mécanismes de verrouillage distribués, les entreprises peuvent améliorer considérablement la cohérence des données.
NCache Détails Documents de verrouillage et de contrôle NCache Docs
Verrouillage distribué pour la cohérence des données
NCache fournit un mécanisme de distribution verrouillage dans .NET qui vous permet de verrouiller des éléments de cache spécifiques lors de mises à jour simultanées. Pour maintenir la cohérence des données dans de tels cas, NCache agit comme un gestionnaire de verrouillage distribué et vous propose deux types de verrouillage :
- Verrouillage optimiste (versions d'éléments de cache)
- Verrouillage pessimiste (verrouillage exclusif)
Nous en parlerons en détail plus tard dans le blog. Pour l'instant, considérez le scénario suivant pour comprendre comment, sans service de verrouillage distribué, il y a une violation de l'intégrité des données.
Deux utilisateurs accèdent simultanément au même compte bancaire avec un solde de 30,000 15,000. Un utilisateur retire 5,000 20,000, tandis que l'autre dépose 15,000 35,000. Si cela est fait correctement, le solde final devrait être de XNUMX XNUMX. Au contraire, si une condition de concurrence émerge et n'est pas prise en charge, le solde bancaire serait de XNUMX XNUMX ou XNUMX XNUMX, comme vous pouvez le voir ci-dessus.
Voici comment cette condition de concurrence se produit :
- Temps t1 : L'utilisateur 1 récupère un compte bancaire avec un solde = 30,000 XNUMX
- Temps t2 : L'utilisateur 2 récupère un compte bancaire avec un solde = 30,000 XNUMX
- Temps t3 : L'utilisateur 1 retire 15,000 15,000 et met à jour le solde du compte bancaire = XNUMX XNUMX
- Temps t4 : L'utilisateur 2 dépose 5,000 35,000 et met à jour le solde du compte bancaire = XNUMX XNUMX
Dans les deux cas, un bloc de code ne répondant pas à la gestion des threads pourrait être désastreux pour la banque. Ainsi, dans les sections suivantes, voyons comment NCache fournit des mécanismes de verrouillage pour garantir que la logique de votre application est thread-safe.
NCache Détails Verrouillage pessimiste Verrouillage optimiste
Verrouillage optimiste (versions d'éléments)
In verrouillage optimiste, NCache Usages gestion des versions des éléments du cache. Côté serveur, chaque objet mis en cache est associé à un numéro de version qui est incrémenté à chaque mise à jour d'élément de cache. NCache vérifie ensuite si vous travaillez sur la dernière version. Sinon, il rejette la mise à jour de votre cache. De cette façon, un seul utilisateur peut effectuer la mise à jour et les autres mises à jour échouent.
Vous pouvez ajouter un élément dans le cache en utilisant à la fois Ajouter or insérer méthodes.
- La méthode Add ajoute un nouvel élément dans le cache et enregistre la version de l'élément pour la première fois.
- La méthode d'insertion remplace la valeur d'un élément existant et met à jour sa version d'élément.
Jetez un oeil à l'exemple de code suivant.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
// Pre-condition: Cache is already connected // An item is added in the cache with itemVersion // Specify the key of the cacheItem string key = "Product:1001"; // Initialize the cacheItemVersion CacheItemVersion version = null; // Get the cacheItem previously added in the cache with the version CacheItem cacheItem = cache.GetCacheItem(key, ref version); // If result is not null if (cacheitem != null) { // CacheItem is retrieved successfully with the version // If result is Product type var prod = new Product(); prod = cacheItem.GetValue(); prod.UnitsInStock++; // Create a new cacheItem with updated value var updateItem = new CacheItem(prod); CacheItemVersion version = cache.Insert(key, updateItem); // If it matches, the insert will be successful, otherwise it will fail } else { // Item could not be retrieved due to outdated CacheItemVersion } |
Dans l'exemple ci-dessus, deux applications différentes utilisent un seul cache contenant les données des produits. CacheItem est ajouté au cache. Les deux applications récupèrent l'élément avec la version actuelle, disons version. Application1 modifie le nom du produit puis réinsère l'élément dans le cache qui met à jour sa version d'élément à nouvelle version. Application2 a toujours l'élément avec version. Si application2 met à jour les unités de l'article en stock et réinsère l'article dans le cache, l'insertion de l'article échouera. Application2 devra donc récupérer la version mise à jour pour fonctionner sur ce cacheItem.
NCache Détails Verrouillage optimiste Gestion des versions des éléments du cache
Toutefois, si vous souhaitez récupérer un élément existant dont une version plus récente est peut-être disponible dans le cache, NCache fournit une Obtenir si plus récent méthode. Si vous spécifiez la version actuelle comme argument de l'appel de méthode, le cache renvoie un résultat approprié. Si la version spécifique est inférieure à celle du cache, la méthode renvoie un nouvel élément, sinon elle renverra null.
Jetons un coup d'œil au code ci-dessous.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
// Get object from cache var result = cache.GetIfNewer(key, ref version); // Check if updated item is available if (result != null) { // An item with newer version is available if (result is Product) { // Perform operations according to business logic } } else { // No new itemVersion is available } |
L'exemple ci-dessus ajoute un élément dans le cache avec la clé Product:1001 et la version de l'élément. Si une version plus récente de l'élément est disponible, Obtenir si plus récent La méthode récupère l'élément à l'aide de la version de l'élément de cache.
Avec verrouillage optimiste, NCache garantit que chaque écriture dans le cache distribué est cohérente avec la version détenue par chaque application. Veuillez vous référer à notre officiel NCache Documentation pour un exemple de code complet.
NCache Détails Obtenir si plus récent CacheItemVersioning
Verrouillage pessimiste (verrouillage exclusif)
L'autre façon d'assurer la cohérence des données consiste à acquérir un verrou exclusif sur les données mises en cache. Ce mécanisme est appelé Verrouillage pessimiste . Il verrouille l'élément à l'aide de la poignée de verrouillage, empêchant tous les autres utilisateurs d'effectuer toute opération d'écriture sur cet élément de cache. UN Poignée de verrouillage est un handle associé à chaque élément verrouillé dans le cache renvoyé par l'API de verrouillage.
L'exemple suivant crée un LockHandle, puis verrouille un élément avec la clé Product:1001 pendant une durée de 10 secondes afin que l'élément soit automatiquement déverrouillé après 10 secondes.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
// Pre-Requisite: Cache is already connected // Item is already added in the cache // Specify the key of the item string key = $"Product:1001"; //Create a new LockHandle LockHandle lockHandle = null; // Specify time span of 10 seconds for which the item remains locked TimeSpan lockSpan = TimeSpan.FromSeconds(10); // Lock the item for a time span of 10 seconds bool lockAcquired = cache.Lock(key, lockSpan, out lockHandle); // Verify if the item is locked successfully if (lockAcquired == true) { // Item has been successfully locked } else { // Key does not exist // Item is already locked with a different LockHandle } |
Après avoir acquis avec succès le verrou lors de la récupération de l'élément, l'application peut désormais effectuer des opérations en toute sécurité, sachant qu'aucune autre application ne peut obtenir ou mettre à jour cet élément tant que vous avez ce verrou. Nous appellerons l'API d'insertion avec le même handle de verrou pour mettre à jour les données et libérer le verrou. Cela insérera les données dans le cache et libérera le verrou, le tout en un seul appel, permettant aux données mises en cache d'être disponibles pour toutes les autres applications.
N'oubliez pas que vous devez acquérir tous les verrous avec un délai d'attente. Par défaut, si le délai d'attente n'est pas spécifié, NCache verrouillera l'objet pour une durée indéterminée, durée.zéro. Il peut y avoir un cas où l'élément peut rester verrouillé pour toujours si l'application se bloque sans libérer le verrou. Pour une solution de contournement, vous pouvez relâcher avec force mais cette pratique est peu judicieuse. Par conséquent, verrouillez un élément pendant le TimeSpan minimum pour éviter un blocage ou une privation de thread.
NCache Détails Verrouillage pessimiste Utilisation du verrouillage avec les données mises en cache Blog
Prise en charge du basculement dans le verrouillage distribué
Depuis que NCache est en mémoire, cache distribué, il fournit également une prise en charge complète du basculement afin qu'il n'y ait aucune perte de données et qu'il soit hautement disponible. En cas de panne du serveur, vos applications clientes continuent de fonctionner de manière transparente. De même, vos verrous dans le système distribué sont également répliqués et maintenus par les nœuds de réplication. Si un nœud tombe en panne alors qu'une de vos applications acquiert un verrou, il sera automatiquement propagé à un nouveau nœud avec ses propriétés spécifiées, par exemple, Verrouiller l'expiration.
Conclusion
Alors, quel mécanisme de verrouillage vous convient le mieux, optimiste ou pessimiste ? Eh bien, cela dépend de votre cas d'utilisation et de ce que vous voulez réaliser. Le verrouillage optimiste offre des performances améliorées par rapport au verrouillage pessimiste, en particulier lorsque vos applications sont intensives en lecture. Alors que le verrouillage pessimiste est plus sûr du point de vue de la cohérence des données. Par conséquent, choisissez votre mécanisme de verrouillage avec soin. Pour plus de détails, rendez-vous sur site . En cas de questions, CONTACTEZ-NOUS et laissez nos experts vous aider !