4 points par GN⁺ 2024-03-20 | 1 commentaires | Partager sur WhatsApp
  • Garnet est un cache distant créé par Microsoft Research, basé sur le protocole filaire RESP, ce qui permet d’utiliser les clients Redis existants sans modification
  • Il offre une meilleure capacité de traitement et une meilleure scalabilité que des caches open source comparables lorsqu’il y a de nombreuses connexions clientes et de petits lots, et sur des VM Azure avec Accelerated Networking activé, la latence au 99,9e percentile est souvent inférieure à 300 microsecondes
  • Basé sur les technologies .NET récentes, il fonctionne sous Linux et Windows, permet de créer des opérations personnalisées, des procédures stockées et des modules en C#, et prend aussi en charge les scripts Lua
  • Sa couche de stockage, Tsavorite, prend en charge la hiérarchisation entre mémoire, SSD et stockage cloud, les checkpoints non bloquants, la reprise, un journal d’opérations pour la durabilité, les transactions multi-clés, ainsi que le sharding, la réplication et la migration dynamique de clés en mode cluster
  • Parmi les nouvelles fonctions, Vector Sets Preview et Range Index Preview ont été ajoutés, et un article sur Garnet devrait paraître à la VLDB 2026

Un cache distant proposé par Garnet

  • Garnet est le nouveau cache distant de Microsoft Research
  • Il adopte comme base le protocole filaire RESP, ce qui permet d’utiliser sans modification les clients Redis existants dans plusieurs langages de programmation
  • Il fournit une meilleure capacité de traitement et une meilleure scalabilité que des caches open source comparables dans les scénarios avec beaucoup de connexions clientes et de petits lots, ce qui peut réduire les coûts des applications et services à grande échelle
  • Sur des VM Azure classiques avec Accelerated Networking activé, la latence client au 99,9e percentile est souvent inférieure à 300 microsecondes
  • Il repose sur des technologies .NET modernes et vise une architecture multiplateforme, extensible et contemporaine
    • Il a été conçu pour faciliter le développement et l’évolution sans sacrifier les performances dans les cas d’usage courants
    • Il s’appuie sur l’écosystème de bibliothèques .NET pour élargir la surface API tout en laissant de la place à l’optimisation
    • Il atteint un niveau de performance élevé à la fois sous Linux et sous Windows
  • Pour celles et ceux qui ont besoin d’un service entièrement managé, Azure Cosmos DB Garnet Cache propose Garnet comme solution de cache d’entreprise avec haute disponibilité, garanties de performance et sans gestion d’infrastructure

Fonctions récentes et article

  • Vector Sets Preview fournit une recherche approchée de plus proches voisins
    • Elle repose sur l’algorithme DiskANN et le moteur de stockage Tsavorite de Garnet
    • Dans les premiers résultats, Garnet montre de meilleures performances en QPS, latence p99 et recall
  • Range Index Preview fournit des index secondaires de plage et d’égalité sur les clés Garnet
  • Un article sur Garnet devrait paraître à VLDB 2026
    • Son titre est Garnet: A Next-Generation Cache-Store for Accelerating Applications and Services
    • Un PDF est disponible

API et modèle d’extension

  • Garnet implémente plusieurs API
    • chaînes brutes : get, set, expiration de clé
    • opérations analytiques : HyperLogLog, Bitmap
    • opérations sur objets : sorted set, list, etc.
  • Il prend en charge les transactions multi-clés
    • transactions RESP côté client
    • procédures stockées et modules côté serveur en C#
  • Les utilisateurs peuvent créer des opérations personnalisées à la fois pour les chaînes brutes et les types d’objets personnalisés
    • En s’appuyant sur la simplicité et la sûreté de C#, il abaisse la barrière à l’entrée pour le développement d’extensions sur mesure
  • Les scripts Lua sont également pris en charge

Réseau, sécurité et couche de stockage

  • Garnet utilise une couche réseau rapide et enfichable
    • Cela ouvre la voie à de futures extensions, comme l’utilisation de piles kernel bypass
  • Pour les communications sécurisées, il prend en charge TLS via la bibliothèque .NET SslStream
  • Il fournit un contrôle d’accès de base
  • La couche de stockage Tsavorite est conçue pour de hautes performances et inclut plusieurs fonctions de base de données
    • scalabilité des threads
    • stockage hiérarchisé incluant mémoire, SSD et stockage cloud
    • checkpoints rapides et non bloquants
    • reprise
    • journal d’opérations pour la durabilité
    • transactions multi-clés
    • meilleure gestion et réutilisation de la mémoire

Architecture

  • La conception de Garnet repense l’ensemble de la pile du cache, depuis la réception des paquets réseau jusqu’au parsing et au traitement des opérations de base de données, ainsi qu’aux interactions avec le stockage
  • La couche réseau repose sur une architecture à mémoire partagée
    • Le traitement TLS et les interactions avec le stockage sont effectués dans les threads d’achèvement des E/S réseau
    • Cela évite, dans les cas courants, le surcoût des changements de contexte entre threads
    • Au lieu de déplacer les données vers le shard approprié du serveur comme dans les architectures réseau traditionnelles fondées sur le shuffle, la cohérence du cache CPU fait remonter les données vers la logique de traitement
  • L’architecture de stockage se compose de deux magasins clé-valeur Tsavorite liés par un journal d’opérations unifié
    • Le main store est optimisé pour les opérations sur chaînes brutes et gère soigneusement la mémoire afin d’éviter le garbage collection
    • Le object store optionnel est optimisé pour les objets complexes et les types de données personnalisés
    • Le object store inclut des types comme Sorted Set, Set, Hash, List et Geo
    • Les types de données du object store exploitent actuellement l’écosystème de bibliothèques .NET
    • Les objets sont stockés dans le tas mémoire sous une forme efficace pour les mises à jour, et sur disque sous une forme sérialisée
  • À l’avenir, l’équipe prévoit d’étudier l’utilisation d’index et de journaux unifiés pour faciliter la maintenance
  • L’un des éléments différenciants de Garnet est l’API de stockage Tsavorite en forme de goulot étroit
    • C’est au-dessus de cette API qu’est implémentée une surface RESP large, riche et extensible
    • Elle se compose d’opérations de lecture, upsert, suppression et read-modify-write atomique
    • Des callbacks asynchrones permettent à la logique de Garnet d’intervenir à plusieurs étapes de chaque opération
    • Cela sépare les préoccupations de parsing et de traitement des requêtes des détails de stockage comme la concurrence, la hiérarchisation du stockage et les checkpoints
  • Les transactions multi-clés utilisent le verrouillage en deux phases

Mode cluster et contraintes opérationnelles

  • En plus de l’exécution sur un nœud unique, Garnet prend en charge le mode cluster
    • Il permet de créer et de gérer des déploiements avec sharding et réplication
    • Il prend en charge un mécanisme efficace et dynamique de migration de clés pour le rééquilibrage des shards
  • Les utilisateurs peuvent créer et gérer un cluster Garnet à l’aide des commandes standard de cluster Redis
  • Les nœuds échangent via gossip pour partager et faire évoluer l’état du cluster
  • La conception du mode cluster de Garnet est actuellement passive
    • Il n’implémente pas d’élection de leader
    • Il répond aux commandes de cluster émises par un control plane fourni par l’utilisateur
    • Plus d’informations dans la documentation du control plane

Documentation et licence

1 commentaires

 
GN⁺ 2024-03-20
Commentaires Hacker News
  • En regardant le graphique de performances des benchmarks (https://microsoft.github.io/garnet/docs/benchmarking/results...), le débit de GET est plus de 10 fois supérieur à celui de Dragonfly
    La latence au 50e percentile est légèrement plus élevée que celle de Dragonfly, mais celle au 99e percentile est légèrement plus basse
    Garnet et Dragonfly offrent tous deux un débit et une latence bien meilleurs que Redis, ce qui donne l’impression que Redis aurait besoin d’une optimisation de performances assez importante

    • Redis est mono-thread, donc simple et efficace
      Je ne sais pas si une optimisation est absolument nécessaire, et il existe déjà 3 alternatives
      Cela dit, Garnet est impressionnant parce que c’est la première alternative qui surpasse Redis à la fois en faible et en forte concurrence, et j’ai hâte de l’essayer
    • Le plus surprenant, c’est que ce projet a été développé en C#
      Dragonfly est en C++, Redis en C
    • C’est surprenant que Garnet, écrit en langage à garbage collector comme C#, batte Redis/Dragonfly
  • La couche de stockage de Garnet, Tsavorite, est issue d’un fork du projet open source FASTER et inclut de solides fonctionnalités de base de données comme la scalabilité des threads, le stockage hiérarchisé (mémoire, SSD, stockage cloud), des checkpoints rapides non bloquants, la reprise, un journal d’opérations pour la durabilité, des transactions multi-clés, ainsi qu’une meilleure gestion et réutilisation de la mémoire
    https://www.microsoft.com/en-us/research/blog/introducing-ga...

    • J’avais déjà étudié l’implémentation de FASTER
      À l’époque, ça m’avait semblé assez prometteur comme bibliothèque de persistance pour un projet de preuve de concept avec de fortes exigences de performance sur lequel je travaillais
      Au passage, les deux projets semblent être dirigés par la même personne [1]
      [1]: https://github.com/badrishc
    • Encore un autre projet open source créé par Microsoft
  • Les projets où Microsoft et l’équipe .NET bricolent directement l’infrastructure sont assez impressionnants
    Yarp est un outil qui sert de reverse proxy / passerelle API / ou tout autre besoin du genre, et maintenant Garnet sert au cache mémoire
    Ils semblent avoir une demande interne énorme, et la volonté de la partager

  • Ce serait bien que ce genre de chose soit intégré à Azure App Service
    Histoire de ne pas être obligé d’utiliser un service distant juste pour le cache
    À une époque, il était courant sous IIS d’avoir un stockage d’état de session hors processus pour les applis ASP.NET
    Cela permettait d’éviter que les utilisateurs perdent leur session et doivent se reconnecter depuis zéro quand le processus de l’application web redémarrait
    Bien sûr, on peut aussi le mettre dans un stockage central comme SQL Server, mais alors chaque requête de page web doit attendre le chargement de l’état de session avant d’être traitée
    L’état de session est généralement verrouillé d’une manière ou d’une autre, donc cela pose aussi beaucoup de problèmes de performance
    La solution courante aujourd’hui est d’utiliser Redis pour le cache et l’état de session, et en général ça fonctionne à peu près correctement
    Le débit est élevé, mais Redis est une ressource séparée dans Azure et coûte absurdement cher
    Je n’ai pas envie de payer des tarifs de base de données Oracle pour quelque chose d’aussi simple, et la configuration de connexion est aussi assez pénible
    Cet article parle d’un temps de réponse de 300 microsecondes, mais dans une architecture redondante inter-zones cela n’a pas beaucoup de sens, car tous les load balancers Azure utilisent une sélection de zone aléatoire
    Un serveur web d’une zone aléatoire est sélectionné, puis il se connecte à nouveau à un serveur de cache d’une zone aléatoire
    Si ce serveur n’a pas la clé, il peut ensuite devoir aller chercher les données du cache dans une autre zone aléatoire
    Le trafic rebondit entre les datacenters, ce qui ajoute 1 à 3 ms de latence et rend le tout jusqu’à 10 fois plus lent que les chiffres mis en avant par Garnet
    Le scénario idéal serait quelque chose comme les reliable collections de Microsoft Service Fabric [1]
    Cela s’exécute localement sur chaque nœud hôte et se réplique sur deux autres nœuds
    L’application web peut toujours lire les valeurs du cache sur le même hôte physique
    Dans certains cas, la latence descend jusqu’à quelques microsecondes, et même le meilleur service externe ultra-optimisé reste des milliers de fois plus lent s’il s’appuie sur un simple équilibrage de charge
    Je ne veux pas quelque chose de 30 % plus rapide que Redis, je veux quelque chose de 3 000 fois plus rapide
    [1] https://learn.microsoft.com/en-us/azure/service-fabric/servi...

    • C’est pour ça que Kubernetes avec Cilium est bien
      On peut configurer les services pour qu’ils aillent toujours vers un service local, ou selon d’autres topologies de routage
      C’est excellent pour le DNS ou le cache applicatif
  • C’est un remplaçant de Redis avec des chiffres de benchmark de latence et de débit assez impressionnants
    Je me demande à quoi cela ressemble en production réelle sur une stack autre qu’Azure

    • Je ne suis pas sûr que ce soit vraiment un drop-in replacement
      Je ne vois aucune indication de support de xstream
  • Garnet being multi-threaded, MSET is not atomic. For an atomic version of MSET, you would need to express it as a transaction (stored procedure).
    Je ne comprends pas bien ce point
    Pourquoi ne pas simplement l’envelopper dans une transaction en interne pour rendre la commande atomique ?
    Et je me demande aussi quels autres pièges d’atomicité il peut y avoir

    • Si on faisait ça, cela imposerait aussi un coût en performances à tous ceux qui n’ont pas besoin de l’atomicité de MSET, et il n’y aurait aucun moyen de désactiver cette transaction
      En revanche, si l’objectif est d’être un remplaçant direct de Redis, c’est un problème puisque Redis garantit cette atomicité
      Au minimum, si la compatibilité totale fait partie des objectifs de conception, on pourrait imaginer une option de configuration permettant de choisir entre compatibilité et performances
  • C’est clairement impressionnant
    Microsoft Research sort parfois des projets remarquables, et être payé pour faire de la R&D a l’air amusant
    J’aimerais que les grandes entreprises fassent plus souvent des projets de R&D utiles à l’ensemble du secteur
    Si Hashicorp est à vendre, j’espère qu’une bonne entreprise le rachètera

  • C’est une très bonne nouvelle pour ceux qui doivent exécuter directement un serveur compatible Redis sur Microsoft Windows Server sans dépendre de WSL2
    Il existait autrefois un port de Redis [1], mais il est maintenant archivé, avait des problèmes d’utilisation mémoire (principalement à cause des fichiers mappés en mémoire, à ma connaissance) et n’est plus maintenu
    Le fait que ce soit écrit en C# est aussi personnellement assez intéressant
    Comme C# est mon langage principal, j’aimerais prendre le temps d’aller fouiller le code
    [1]: https://github.com/microsoftarchive/redis

  • J’aimerais voir où cela est utilisé dans de vrais environnements de production
    Il y a cette phrase : « après des milliers de tests unitaires et plusieurs années de déploiement opérationnel de Garnet avec les équipes first-party de Microsoft, nous avons estimé qu’il était temps de le rendre public »
    https://microsoft.github.io/garnet/blog

  • À voir les commentaires ici, on dirait que plus personne n’utilise memcached

    • La dernière fois que je l’ai utilisé, c’était vers 2016, il me semble, et la configuration n’était pas particulièrement simple
      Je voulais un cache LRU, mais il y avait plusieurs options et la documentation n’était pas très claire, donc je ne comprenais pas pourquoi il continuait à évincer des éléments
      En passant à Redis, la configuration était plus simple et cela fonctionnait comme je l’attendais