Question

Supposons que nous construisons un site de commerce électronique qui permet aux consommateurs de rechercher des produits en tapant des mots-clés. Disons qu'il ya au plus 200.000 produits, et il y a des millions de consommateurs qui utilisent le système. Disons que le tableau des produits est mis à jour assez fréquemment. Étant donné que le nombre de produits n'est pas élevé et nous pouvons probablement stocker l'ensemble de la table produit dans la mémoire et de la recherche contre au lieu de frapper la base de données. Nous espérons créer des caches distribués qui stockent les mêmes données, mais résident dans différents serveurs (pour des raisons de haute disponibilité et de performance) et nous devons être en mesure de synchroniser les données entre ces caches et invalider les caches lorsque la table de produit est modifié.

Notre application est construit en utilisant ASP.NET MVC et NHibernate. Je suis en train de comprendre si la mise en cache de niveau 2 de NHibernate aiderait à ma situation. Je voudrais vraiment apprécier si vous les gars peuvent faire la lumière sur ce point.

Je comprends que le niveau 2 cache aidera résultat de la requête de cache donc si deux utilisateurs différents sont à la recherche en utilisant le même mot-clé, le cache L2 servira le résultat à partir du cache au lieu de partir de la base de données. Mais cela ne nous aide pas beaucoup depuis la table des produits est mis à jour fréquemment et le résultat en cache sera obsolète. Ma question est-ce que je comprends bien la mise en cache L2 et il existe quelque chose qui cache aider à gérer la façon dont je voudrais faire (plusieurs caches, les mêmes données, la synchronisation entre le cache et invalident le cache). Toute pensée est très apprécié.

Était-ce utile?

La solution

Ayant utilisé à la fois le cache de second niveau (à l'aide du fournisseur memcached) et le NHibernate.Search add-on, il me semble que vous pourriez bénéficier des deux.

Le composant NHibernate.Search dépend de Lucene.Net et recherche par mot clé est découplé de la base de données elle-même. Un fichier d'index différent est créé par classe mappée et optimisations peuvent être définis au niveau de la propriété en utilisant les attributs, vous donnant un niveau de granularité supplémentaire. De plus, vous pouvez mettre en œuvre meilleure correspondance et propositions (vérifier Lucene en action et / ou Hibernate Recherche en action). Comme une note, vous ne devez pas maintenir l'index (sauf si vous demandez explicitement une reconstruction d'index); la mise en œuvre gère tout dans les coulisses, bien que vous pouvez manipuler l'index si vous souhaitez le faire. Ainsi, l'ajout / suppression / mise à jour d'un produit mettra automatiquement à jour l'index suivant.

Pour le cache de second niveau vous obtenez gain de performance instantanée. Sur un environnement de test avec un ensemble de données d'environ 2 rangées de mil i eu plus de 20% d'amélioration, même sur un nombre de requêtes extrêmement faible. Le gain de performance est progressivement plus grande que les augmentations de comptage de demande - l'application frappe d'abord le cache de niveau 2 et si elle ne trouve pas frappe alors le DB pour aller chercher les lignes requises et les insère sur le cache pour les requêtes futures. Encore une fois, vous pouvez gérer des choses comme la durée du cache et d'autres paramètres de configuration, ainsi que le cache explicitement clair (tout cela, une partie de celui-ci, ou des entrées particulières) si vous souhaitez le faire. Notez que l'état du cache est géré par l'application lors de la sauvegarde / mise à jour / supprimer.

Pour scallability * 2ème cache de niveau dépend du fournisseur (c.-à-memcached est très performant et évolutif et prend en charge les instances distribuées). * Pour le Lucene.Net/NHibernate.Search, vous aurez besoin de mettre en place un lieu précis que les indices résideront et ce lieu doit être accessible en lecture / écriture par toutes les instances application web. Notez ici que le lien est sensible E / S et les conflits de fichiers, la mise en sorte une machine avec un plus rapide que le système de fichiers lumière empêche que cela se produise (je parle de votre scénario avec plusieurs milliers de demandes de recherche par seconde)

Comme une note de côté je recommande vivement NHibernate.Search car il est extrêmement plus rapide que requêtes LIKE et est plus facile à utiliser que la mise en œuvre de la recherche de texte intégral de SQL-serveur dans l'application (qui je l'ai fait).

Autres conseils

Si un cache de second niveau aidera dépend exactement à quelle fréquence votre table de produit est mis à jour par rapport aux coups de cache. Si vous ajoutez 100 nouveaux produits à l'heure, mais recevez 10.000 requêtes par heure, même un taux de succès de cache de 10% fera une grande différence. Si les taux sont inversés, un cache de second niveau sera de presque aucune valeur.

Je vous suggère de mettre en place un environnement de test de stress qui se rapproche de près votre environnement de production et d'effectuer des analyses comparatives sur les différents fournisseurs de deuxième cache de niveau.

Vérifiez aussi que votre DB est correctement configuré pour un scénario de mise à jour lourde.

Je recommande d'utiliser NHibernate.Search w / Lucene. Il travaille en collaboration avec le cache de niveau 2. Lucene peut faire une recherche sophistiquée de texte déchirant clés rapide et puis retourner l'entité à NHibernate qui tire l'entité complète de son cache de niveau 2. L'extension NHibernate.Search fait le travail de garder votre index Lucene en synchronisation.

TekPub a fait un épisode récent de votre scénario exact de la recherche des descriptions de produits. L'épisode compare les requêtes SQL NHibernate, l'indexation en texte intégral et Lucene w / NHibernate.Search.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top