.NET Core et ASP.NET Core gagnent en popularité en raison de leur simplicité de conception, de leur légèreté, de leur open source et de leur capacité à fonctionner à la fois sous Windows et Linux. En conséquence, de nombreuses applications existantes migrent également vers .NET Core du .NET Framework. Presque toutes les nouvelles applications sont développées dans .NET Core.
Beaucoup d'entre eux .NET Core les applications génèrent un trafic élevé, desservant des millions d'utilisateurs et de transactions. Par conséquent, ces applications ont un impact énorme sur votre entreprise et sont donc très importantes.
La .NET Core les applications qui ont généralement besoin d'évolutivité sont les applications serveur qui doivent traiter très rapidement un grand nombre de transactions avec des temps de réponse très rapides. Bon nombre de ces applications sont orientées client, ce qui signifie qu'elles traitent les demandes des clients. S'ils ne répondent pas rapidement aux demandes des clients, le coût pour l'entreprise est élevé en termes de perte de revenus et de perte de clients satisfaits.
Following .NET Core les applications nécessitent une évolutivité :
Fait intéressant, toutes les applications mentionnées ci-dessus ont des architectures de niveau application très évolutives. Chacun d'eux vous permet d'évoluer de manière linéaire à mesure que votre charge de transaction augmente en ajoutant plus de serveurs, de machines virtuelles ou d'instances de conteneurs avec un équilibreur de charge.
Mais, malgré une architecture très évolutive au niveau applicatif, .NET Core les applications serveur sont aujourd'hui confrontées à d'importants goulots d'étranglement en matière d'évolutivité. Ces goulots d'étranglement se produisent dans différents domaines tels que :
Le plus gros goulot d'étranglement pour tout trafic élevé .NET Core applications est leur base de données d'applications. La plupart des applications utilisent encore aujourd'hui une base de données relationnelle comme SQL Server ou Oracle. Ces bases de données deviennent rapidement des goulots d'étranglement d'évolutivité à mesure que vous augmentez les charges de transaction sur ces applications. Cela est vrai que vous utilisiez SQL Server sur une machine virtuelle ou Azure SQL Database.
Cela se produit parce qu'une base de données relationnelle ne peut pas être partitionnée logiquement comme une NoSQL database et reste à la place dans un seul endroit physique ; même certains partitionnements au niveau des colonnes n'ont rien à voir avec un vrai NoSQL partition de style. Par conséquent, vous ne pouvez pas augmenter la capacité de transaction du niveau base de données en ajoutant davantage de serveurs de base de données comme vous le pouvez avec un NoSQL database.
Par exemple, alors que votre niveau d'application peut facilement avoir 10, 20, 30 serveurs d'applications ou plus à mesure que votre charge de transaction augmente, votre niveau de base de données ne peut pas du tout croître de la même manière.
À cause de tout cela, votre base de données relationnelle devient un goulot d'étranglement pour toutes les données que vous y stockez (données d'application ou autres données).
SQL Server a introduit des optimisations en mémoire pour augmenter le nombre de transactions par seconde. Oracle a également fourni sa propre version des tables en mémoire.
Bien que les optimisations en mémoire améliorent les performances, elles ne résolvent pas le problème central de l'évolutivité linéaire. Les tables en mémoire sont généralement utilisées pour les données en lecture seule et afin de mettre à l'échelle une capacité de transaction en lecture seule, vous devez ajouter plus d'instances de SQL Server sur des machines haut de gamme.
Les tables en mémoire ont également des limitations sur la taille des données ; vous ne pouvez pas mettre de grandes tables en mémoire puisque toute la table doit être mise en mémoire. Et leur réplication vers d'autres instances de SQL Server ne peut être effectuée que vers d'autres tables en mémoire et non vers une base de données appropriée.
En résumé, ces optimisations en mémoire dans les bases de données SQL Server et Oracle ne sont pas en mesure de répondre pleinement à votre .NET Core besoins d'évolutivité de l'application.
Une des raisons NoSQL databases sont devenus populaires parce qu'ils fournissent un partitionnement approprié des données basé sur des algorithmes basés sur le hachage et d'autres algorithmes. Cela résout de nombreux problèmes d'évolutivité de la capacité de transaction auxquels sont confrontées les bases de données relationnelles telles que SQL Server et Oracle.
Mais il y a des raisons NoSQL databases ne sont pas la solution idéale pour ces goulots d'étranglement de base de données.
La solution à tous les problèmes mentionnés ci-dessus est d'utiliser un cache distribué en mémoire comme NCache dans votre .NET Core déploiement d'applications. NCache est un cache distribué Open Source pour .NET et .NET Core qui est extrêmement rapide et linéairement évolutif. Considérez-le comme un magasin de données en mémoire qui est également distribué. Le fait d'être en mémoire le rend extrêmement rapide et sa distribution le rend linéairement évolutif.
NCache est linéairement évolutif car il crée un cluster TCP de serveurs de cache à faible coût (même configuration que vos serveurs d'applications Web mais avec plus de mémoire) et regroupe la mémoire et les ressources CPU de tous ces serveurs en une seule capacité logique. NCache vous permet ensuite d'ajouter des serveurs de cache à ce cluster lors de l'exécution à mesure que votre charge de transaction augmente. Et depuis NCache est tout en mémoire, il est ultra-rapide et vous donne des temps de réponse inférieurs à la milliseconde que vous ne pouvez pas attendre de vos bases de données relationnelles ou même NoSQL databases.
En plus de fournir une évolutivité linéaire, un cache distribué comme NCache réplique les données intelligemment afin que vos performances ne soient pas compromises tout en garantissant la fiabilité des données en cas de panne d'un serveur de cache.
NCache vous permet de mettre à l'échelle votre .NET Core candidatures via les éléments suivants :
Le goulot d'étranglement le plus important auquel sont confrontés .NET Core applications est la "Base de données d'applications". La bonne chose à propos NCache est-ce différent NoSQL databases, NCache ne vous demande pas d'arrêter d'utiliser votre base de données relationnelle existante. Vous pouvez continuer à utiliser SQL Server, Azure SQL Database, Oracle, etc. comme base de données tout en obtenant une évolutivité linéaire en utilisant NCache au-dessus de votre base de données relationnelle. Ceci est dû au fait NCache supprime tous les goulots d'étranglement de l'évolutivité de la base de données relationnelle, car contrairement à votre base de données, NCache est en fait linéairement évolutif.
La mise en cache des données d'application vous permet de supprimer les goulots d'étranglement de votre base de données. NCache vous permet de mettre en cache les données d'application et de réduire ces déplacements coûteux de la base de données. Vous pouvez vous attendre à détourner 80 à 90 % du trafic de la base de données vers NCache. Cela réduit la pression sur votre base de données et lui permet de fonctionner plus rapidement et de gérer des charges de transactions plus importantes sans ralentir.
La mise en cache des données d'application signifie que vous mettez en cache toutes les données d'application que vous obtenez de votre base de données relationnelle. Cela se présente généralement sous la forme d'objets de domaine (également appelés entités). Voici un exemple d'utilisation d'un cache distribué comme NCache pour la mise en cache des données d'application.
Customer Load(string custId)
{
ICache cache = CacheManager.GetCache("myCache");
string key = "Customer:CustomerID:" + custId;
Customer cust = cache.Get<Customer>(key);
if (cust == null) {
// Item not in cache so load from db
LoadCustomerFromDb(cust);
// Add item to cache for future reference
cache.Add(key, cust);
}
return cust;
}
Figure 3 : Utilisation du cache distribué en mémoire pour la mise en cache des données d'application
Un autre goulot d'étranglement possible est si vous stockez votre ASP.NET Core Sessions dans SQL Server ou MemoryCache autonome. Les deux options ont de grandes limites en termes de performances et d'évolutivité. Le stockage SQL Server n'est pas bon pour ASP.NET Core sessions et devient rapidement un goulot d'étranglement, tout comme pour les données d'application.
NCache est un endroit idéal pour stocker votre ASP.NET Core Sessions car il est beaucoup plus rapide et plus évolutif que les autres options de stockage. NCache est plus rapide car il est en mémoire et fournit une interface clé-valeur avec la valeur étant un "objet" qu'un ASP.NET Core La séance est. Et, il est évolutif car il s'agit d'un cache distribué.
Et, NCache réplique également intelligemment ASP.NET Core sessions grâce à ses riches topologies de mise en cache, de sorte que même si un serveur de cache tombe en panne, il n'y a aucune perte de données de session. Cette réplication est nécessaire car NCache fournit un magasin en mémoire et la mémoire viole le stockage.
NCache accélère également votre sérialisation de l'ASP.NET Core Session requise avant de pouvoir être stockée hors processus. NCache le fait en utilisant sa fonctionnalité de sérialisation compacte dynamique qui est 10 fois plus rapide que le .NET standard et .NET Core sérialisation. Vous pouvez utiliser cette fonctionnalité sans apporter de modifications au code.
Vous pouvez utiliser NCache en tant que votre ASP.NET Core Stockage de session de deux manières.
Voici un exemple de la façon dont vous pouvez configurer votre ASP.NET Core application à utiliser NCache Fournisseur de sessions :
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
// Specify NCache as the session provider
services.AddNCacheSession(Configuration.GetSection("NCacheSettings"));
...
}
public void Configure(IApplicationBuilder app, ...)
{
// select NCache session provider for ASP.NET Core
app.UseNCacheSession();
...
}
}
Figure 4 : Plug-in NCache en tant qu'ASP.NET Core Sessions
ASP.NET Core les applications, qui ont par ailleurs un contenu assez dynamique, sont confrontées à des situations où, pour certaines de leurs pages, le contenu ou la réponse ne change pas à travers plusieurs requêtes. Mais ces pages doivent toujours être exécutées à chaque fois que la demande arrive. Et cela impose une charge inutile aux ressources du serveur Web ainsi qu'à tous les niveaux de cette application. Par conséquent, cela ajoute également aux goulots d'étranglement des performances et limite l'évolutivité de l'application.
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
// Turn on ASP.NET Core Response Cache with IDistributedCache
services.AddResponseCaching();
// Select NCache as IDistributedCache provider
services.AddNCacheDistributedCache(Configuration.GetSection("NCacheSettings"));
...
}
}
Figure 5 : Plug-in NCache en tant qu'ASP.NET Core Intergiciel de cache de réponse
Pour traiter la surcharge de l'exécution de pages répétitives où la réponse de la page ne change pas, ASP.NET Core a fourni un mécanisme de mise en cache de réponse de page appelé ASP.NET Response Cache Middleware. Et, NCache a implémenté l'interface IDistributedCache dans ASP.NET Core grâce à quoi vous pouvez brancher de manière transparente NCache en tant que votre ASP.NET Core Intergiciel de cache de réponse.
Vous pouvez donc utiliser NCache mettre en cache ASP.NET Core réponses de la page pendant une certaine période de temps afin que la prochaine fois que la même page soit appelée avec les mêmes paramètres, cette réponse mise en cache peut être réajustée au lieu d'exécuter à nouveau la page entière. Ci-dessous l'exemple de code sur la façon de configurer NCache en tant que votre ASP.NET Core Intergiciel de cache de réponse.
Si votre ASP.NET Core l'application est une application Web en temps réel, elle utilise très probablement ASP.NET Core SignalR pour fournir ce comportement en temps réel. Les applications Web en temps réel fournissent des mises à jour à haute fréquence du serveur au client. Les exemples de telles applications incluent les jeux, les enchères, le vote, les réseaux sociaux, etc.
Si votre ASP.NET Core l'application s'exécute dans un environnement multiserveur à charge équilibrée, elle doit utiliser un ASP.NET Core SignalR Backplane fournisseur afin de partager des événements sur plusieurs serveurs Web. Et, ce fond de panier doit être évolutif. Sinon, votre ASP.NET Core L'application SignalR commence à faire face à des goulots d'étranglement de performances.
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
// Specify NCache as the ASP.NET Core SignalR Backplane
services.AddSignalR().AddNCache(ncacheOptions =>
{ ncacheOptions.CacheName = "myPartitionedCache"; });
...
}
public void Configure(IApplicationBuilder app, ...)
{
// Use SignalR in ASP.NET Core
app.UseSignalR(config => { config.MapHub<MessageHub>("/messages"); });
...
}
}
Figure 6 : Plug-in NCache en tant qu'ASP.NET Core SignalR Backplane Provider
NCache a mis en place un ASP.NET Core SignalR Backplane fournisseur. NCachede l'ASP.NET Core SignalR Backplane fournisseur utilise les fonctionnalités de messagerie Pub/Sub de NCache qui sont ultra-rapides car totalement en mémoire. Cela permet à votre ASP.NET Core Application SignalR pour accélérer la propagation des événements SignalR parmi tous les serveurs Web et, par conséquent, vers les clients.
Et cela rend votre application Web en temps réel plus réactive pour fournir ces mises à jour fréquentes aux clients. Et, vous pouvez continuer à augmenter le nombre de clients et également ajouter plus de serveurs Web sans craindre de goulots d'étranglement de performances.
Si votre .NET Core l'application doit utiliser la messagerie Pub/Sub ou les événements, il est fort probable qu'elle utilise une plate-forme de messagerie Pub/Sub qui n'est pas entièrement en mémoire et stocke à la place tous les messages sur le disque. Par conséquent, cela peut facilement devenir un goulot d'étranglement des performances si votre application est très transactionnelle.
NCache fournit également une messagerie Pub/Sub ultra-rapide car entièrement en mémoire. Et, il réplique tous les messages à un autre NCache serveur pour s'assurer qu'il n'y a pas de perte de données en cas de panne d'un serveur.
Par conséquent, si votre .NET Core l'application utilise NCache en tant que plate-forme de messagerie Pub/Sub, elle bénéficiera de performances ultra-rapides et d'une évolutivité linéaire car NCache elle-même est linéairement évolutive.
Vous trouverez ci-dessous un exemple d'utilisation de la messagerie Pub/Sub fournie par NCache dans votre .NET Core .
private void PublishMessage (string topicName)
{
ITopic topic = _cache.MessagingService.GetTopic(topicName);
Order order = Order.GenerateOrder<Order>();
// Publish message containing "order" with expiry
Message message = new Message(order, new TimeSpan(0, 0, 15));
topic.Publish(message, DeliveryOption.All, true);
}
private ITopicSubscription SubscribeMessage (string topicName)
{
ITopic topic = _cache.MessagingService.GetTopic(topicName);
// Subscribes to the topic. Message delivered to MessageReceivedCallback
return topic.CreateSubscription(MessageReceivedCallback);
}
static void MessageReceivedCallback(object sender, MessageEventArgs args) { ... }
Figure 7 : Utilisation de la messagerie Pub/Sub dans .NET Core Applications
Le plus grand goulot d'étranglement d'évolutivité que votre .NET Core l'application doit supprimer est de la base de données de l'application. Dans ce domaine, vos applications peuvent atteindre des performances élevées et une évolutivité linéaire grâce à la mise en cache des données d'application. La raison en est simple. Plus .NET Core les applications traitent un grand nombre de données dans les deux sens à partir de la base de données.
En ce qui concerne la mise en cache des données d'application, la plus grande crainte des utilisateurs est que le cache devienne obsolète, ce qui signifie qu'il contient une ancienne version des données qui a déjà été modifiée dans la base de données par un autre utilisateur ou une autre application.
Cette crainte qu'un cache devienne obsolète est si forte que la majorité des gens ne cachent que des données en lecture seule ou statiques (données de référence). Mais ces données en lecture seule ne représentent que 20 % du total des données sous la forme de tables de recherche et d'autres données de référence. La majeure partie des données de la base de données est transactionnelle, y compris les clients, les comptes, les activités, etc. Et, si vous ne mettez pas en cache ces données transactionnelles, vous ne bénéficiez pas pleinement de la mise en cache.
Ainsi, le véritable avantage de la mise en cache vient si vous pouvez mettre en cache tous les types de données sans craindre que la mise en cache ne devienne obsolète. NCache fournit une multitude de fonctionnalités pour résoudre ce problème.
Le moyen le plus efficace de garder votre cache à jour est de toujours le synchroniser avec votre base de données. NCache vous permet de faire cela pour une variété de bases de données comme suit :
Lorsque vous synchronisez votre cache avec SQL Server, vous demandez NCache pour s'enregistrer en tant que client de SQL Server, puis émettre un appel SqlDependency avec un ensemble de données basé sur une requête SQL. Ensuite, lorsque SQL Server voit des modifications dans cet ensemble de données, il notifie NCache à propos de ça
private static void CreateSqlDependency (Product product)
{
string connectionString = "Data Source=localhost;Database=northwind;...";
// SQL stmt on which the SQL Dependency is created in SQL Server
string sqlStmt = "SELECT ProductID, ProductName, QuantityPerUnit, UnitPrice " +
"FROM dbo.PRODUCTS WHERE ProductID = " + product.Id;
CacheDependency sqlDependency = new SqlCacheDependency(connectionString, sqlStmt);
CacheItem cacheItem = new CacheItem(product) { Dependency = sqlDependency };
string key = "Product:ProductId:" + product.Id; ;
cache.Add(key, cacheItem);
}
Figure 8 : Utilisation de SqlDependency pour synchroniser le cache avec SQL Server
Puis, NCache supprime cet élément du cache de sorte que la prochaine fois que l'application en aura besoin, elle devra récupérer la dernière copie de la base de données. Si vous utilisez le gestionnaire de lecture (voir ci-dessous), alors NCache peut également recharger automatiquement la dernière copie de la base de données pour vous. Vous trouverez ci-dessous un exemple d'utilisation de SqlDependency pour synchroniser votre cache avec SQL Server.
Le cache de lecture est un cache capable de lire les données de votre base de données en appelant un gestionnaire de lecture que vous avez développé et fourni au cache. De même, un cache d'écriture immédiate est capable d'écrire des modifications de données dans votre base de données en appelant un gestionnaire d'écriture immédiate que vous avez développé et fourni au cache. Write-behind Cache est identique à Write-through sauf que les mises à jour de la base de données sont effectuées de manière asynchrone.
La lecture continue, l'écriture immédiate et l'écriture différée offrent de nombreux avantages à votre .NET Core candidatures comprenant :
Vous trouverez ci-dessous un exemple de la façon dont vous pouvez utiliser Read-through avec NCache.
// Read through handler for SQL Server
public class SqlReadThruProvider : Runtime.DatasourceProviders.IReadThruProvider
{
public void Init(IDictionary parameters, string cacheId) {}
public void Dispose() {}
// Get object from the database/data-source based on the key
public ProviderCacheItem LoadFromSource(string key) {}
// Bulk-Get objects from the database/data-source based on the keys
public IDictionary<string, ProviderCacheItem> LoadFromSource(ICollection<string> keys)
{}
}
Figure 9 : Utilisation du gestionnaire de lecture avec NCache
Une fois que vous êtes à l'aise avec la mise en cache de toutes les données, vous pouvez commencer à mettre beaucoup de données dans un cache distribué. Ici, vous pouvez commencer à faire face à un autre problème particulier, à savoir comment trouver rapidement et facilement vos données. Étant donné que la plupart des caches distribués sont des magasins clé-valeur, il devient très difficile de suivre toutes vos données uniquement via des clés.
C'est ici que NCache vous offre une variété de façons de trouver rapidement des données à partir de votre cache. Les exemples comprennent:
Vous trouverez ci-dessous un exemple de la façon dont vous pouvez utiliser des requêtes basées sur LINQ avec NCache.
// Search the cache based on object attributes by using LINQ
IQueryable>Product< products = new NCacheQuery<Product>(_cache);
var result = from product in products
where product.Id > 10
select product;
if (result != null)
{
foreach (Product p in result1)
{
// Process each “product” fetched from the database
Console.WriteLine("ProductID : " + p.Id);
}
}
Figure 10 : Utilisation des requêtes LINQ avec NCache
Fort trafic .NET Core les applications ne peuvent pas se permettre de baisser, surtout pendant les heures de pointe. Pour ces types d'applications, il existe trois objectifs architecturaux vraiment importants qu'un bon cache distribué InMemory comme NCache remplit.
Laissez-moi vous expliquer chacun ci-dessous.
NCache fournit un cache client qui est un cache local très proche de votre application. Il peut s'agir d'InProc (c'est-à-dire qu'il réside dans votre processus de candidature) ou d'OutProc local. Dans tous les cas, il fournit un accès très rapide à un sous-ensemble des données mises en cache dont votre application sur ce serveur d'applications a besoin à ce moment. Le cache client reste en même temps synchronisé avec le niveau de mise en cache afin que toutes les données modifiées par d'autres utilisateurs ou applications dans le niveau de mise en cache soient immédiatement propagées au cache client. Le client vous permet d'avoir une vitesse InProc tout en faisant partie d'un niveau de mise en cache très évolutif.
L'un des objectifs architecturaux les plus importants de NCache est d'atteindre une évolutivité linéaire avec la fiabilité des données grâce à ses topologies de mise en cache. Voilà quelque NCache Topologies de mise en cache qui aident à atteindre ces deux objectifs.
L'un des objectifs architecturaux les plus importants de NCache est d'obtenir une haute disponibilité et une élasticité du cache. Pour ce faire, il utilise les fonctionnalités architecturales suivantes :