2016-01-26 1 views
4

Les mémoires cache en mémoire nécessitent une sérialisation/désérialisation lors du stockage d'objets complexes, tels qu'un objet C# POCO.Est-il possible de conserver des objets en mémoire pour une mémoire cache encore plus rapide que Redis ou Memcached?

Est-ce qu'il n'est pas possible de conserver simplement les données à mettre en mémoire cache en tant que graphique d'objet et d'éliminer ce goulot d'étranglement? Après tout, les données mises en cache et sérialisé est encore en mémoire alors pourquoi ne pas garder les objets originaux dans la mémoire pour le cache le plus rapide possible (et peut-être utiliser des canaux nommés pour mettre en œuvre un cache distribué?)

Merci

+0

Vous pouvez regarder ProtoBuf –

+0

https://msdn.microsoft.com/en-us/library/system.runtime.caching.memorycache(v=vs.110).aspx – willaien

+1

protobuf est juste une autre forme de sérialisation/désérialisation comme json. C'est plus rapide mais la question est pourquoi sérialiser quand tout peut être gardé en mémoire –

Répondre

1

Waescher a raison de dire que s'il y a une seule machine et un seul processus, vous pouvez stocker le graphe d'objets dans la mémoire locale. S'il y a plusieurs processus, alors cela doit être dans la mémoire partagée et cela ouvre toute une boîte de vers qui peut ou ne peut pas être adressée par des produits de tiers tels que Redis/memcached. Par exemple, la simultanéité doit être gérée (c'est-à-dire s'assurer qu'un processus n'essaie pas de lire le graphique en même temps qu'un autre modifie le graphique, ou un algorithme sans verrou plus ambitieux). En fait, cela doit également être traité dans un processus multithread unique.

Les références d'objet, dans le cas de mémoire partagée, si elles sont des pointeurs de mémoire, peuvent toujours être utilisables tant que le segment de mémoire partagée est mappé à la même adresse dans chaque processus. En fonction de la taille du segment de mémoire partagée et de la taille des processus et de la carte mémoire de chaque processus, cela peut être possible ou non. L'utilisation d'un identificateur/référence d'objet généré par le système (par exemple un entier de 4 ou 8 octets augmentant séquentiellement) éviterait ce problème. À la fin de la journée, si vous stockez le graphe d'objets dans un référentiel, il doit être sérialisé/désérialisé dans/hors du stockage de ce référentiel.

2

Le Les caches que vous avez mentionnés sont conçus pour être utilisés comme caches distribués avec beaucoup de fonctionnalités et d'options. Tenir un objet ou en particulier un arbre d'objets dans une variable (globale) pour l'utiliser dans un seul processus est toujours plus rapide que de le charger depuis un autre ordinateur en le désérialisant, etc.

Mais ce n'est pas le cas Redis & Co. Dès que vous essayez d'implémenter votre propre cache distribué avec des canaux nommés (ou toute autre technologie), vous découvrirez que Redis a le droit d'exister. En d'autres termes: Dès que vous déplacez des objets sur les limites de la machine, vous devrez les sérialiser et les désérialiser. Vous pourriez ne pas le savoir si le protocole de transport sous-jacent le fait pour vous.

+0

Merci. En fait, je voulais dire qu'un cache distribué utilisant des tubes nommés était optionnel. Si le cache se trouvait sur une seule machine (sans équilibrage de charge), alors vous voulez dire que garder tout simplement comme un graphique d'objet en mémoire serait plus rapide et plus simple que d'utiliser Redis/memcache? –

+1

Une seule machine en un seul processus - oui. Si vous avez plusieurs processus, vous devez également partager vos objets en cache et vous ne pourrez pas utiliser les mêmes références d'objet à moins que vous n'utilisiez des pipes ou un .NET remoting ou peut-être d'autres technologies. Cela peut être plus rapide dans certains cas, mais vous êtes très limité par rapport à Redis - et vous savez que votre patron est déjà en route pour vous dire que les spécifications ont changé ... – Waescher

2

Garder les objets tels quels In-Memory a quelques avantages et inconvénients. Jetons un coup d'oeil à eux

Plus:

  • Il n'y aura pas sérialisation et les coûts désérialisation.
  • L'analyse (économie des coûts de sérialisation) sera plus facile.
    • Lorsque vous effectuez des fonctions MapReduce dans un Distributed Cache, les objets ne sont pas stockés sous forme binaire pour faciliter les coûts d'analyse.

Contre

  • sérialisation diminue effectivement la taille des données en supprimant les frais généraux de méta-données .NET (RAM est précieux)
  • taille de votre cache peut être prédite
  • effectuer le chiffrement ou compression si nécessaire.
  • les transférer sur le réseau
  • Mettre en oeuvre serializers personnalisés pour choisir ce qu'il faut stocker
  • Les données binaires n'a pas barrière de la langue (si vous avez vos propres serializers)

Ce ne sont que quelques-uns des pros et contre que je pense sont vraies. Je suis sûr qu'il y aura plus

Comprendre ces avantages et inconvénients, la plupart ou tous les caches distribués opter pour la sérialisation, même lorsque les caches sont en cours de traitement. Les coûts de sérialisation ne sont pas aussi élevés lorsque l'on considère la plupart des cas d'utilisation.

En outre, le point @Waescher est également vrai, quand le réseau est impliqué, tous les types de données doivent être convertis en octets pour le transfert.