{"id":24675,"date":"2022-12-01T00:00:00","date_gmt":"2022-12-01T00:00:00","guid":{"rendered":"https:\/\/www.mailgun.com\/blog\/golangs-superior-cache-solution-memcached-redis-2\/"},"modified":"2026-09-16T16:56:38","modified_gmt":"2026-09-16T16:56:38","slug":"golangs-superior-cache-solution-memcached-redis","status":"publish","type":"blog","link":"https:\/\/www.mailgun.com\/fr\/blog\/it-and-engineering\/golangs-superior-cache-solution-memcached-redis\/","title":{"rendered":"GroupCache\u00a0: la solution de cache sup\u00e9rieure pour Golang"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Le cache Golang rend la mise en cache distribu\u00e9e et la synchronisation simples et faciles \u00e0 d\u00e9ployer avec GroupCache. Mais pourquoi est-ce le meilleur outil\u00a0? Et quels probl\u00e8mes r\u00e9sout-il\u00a0? Chez Mailgun, nous avons utilis\u00e9 GroupCache pour r\u00e9duire la latence de notre service de limitation de d\u00e9bit et avons profit\u00e9 des avantages de la synchronisation, tout en \u00e9vitant les probl\u00e8mes d&rsquo;interblocage lors de la cr\u00e9ation et de la gestion de ressources uniques. Si vous n&rsquo;\u00eates pas convaincu, ce n&rsquo;est pas grave, nous sommes convaincus que vous le serez \u00e0 la fin de cet article.<\/p>\n\n\n\r\n    <nav data-content-type=\"longform\" class=\"toc-block longform-spacings px-5 py-6 px-md-6 px-lg-7 py-md-7 bg-light fs-sm rounded-lg\" aria-labelledby=\"toc-title-4751\"><p class=\"h5 m-0\" id=\"toc-title-4751\">Table des mati\u00e8res<\/p><div class=\"d-flex mt-3\"><div class=\"w-auto fw-bold text-accent d-flex me-2\">01<\/div><div class=\"d-flex flex-column\"><a class=\"fw-bold scrollme link-body-color text-accent\" href=\"#quest-ce-quun-cache-distribue\">Qu&rsquo;est-ce qu&rsquo;un cache distribu\u00e9\u00a0?<\/a><\/div><\/div><div class=\"d-flex mt-3\"><div class=\"w-auto fw-bold text-accent d-flex me-2\">02<\/div><div class=\"d-flex flex-column\"><a class=\"fw-bold scrollme link-body-color text-accent\" href=\"#comment-fonctionne-la-mise-en-cache-distribuee\">Comment fonctionne la mise en cache distribu\u00e9e\u00a0?<\/a><\/div><\/div><div class=\"d-flex mt-3\"><div class=\"w-auto fw-bold text-accent d-flex me-2\">03<\/div><div class=\"d-flex flex-column\"><a class=\"fw-bold scrollme link-body-color text-accent\" href=\"#resoudre-le-probleme-du-thundering-herd-tempetes-de-cache-et-haute-simultaneite\">R\u00e9soudre le probl\u00e8me du thundering herd\u00a0: temp\u00eates de cache et haute simultan\u00e9it\u00e9<\/a><\/div><\/div><div class=\"d-flex mt-3\"><div class=\"w-auto fw-bold text-accent d-flex me-2\">04<\/div><div class=\"d-flex flex-column\"><a class=\"fw-bold scrollme link-body-color text-accent\" href=\"#quest-ce-que-groupcache-et-comment-se-compare-t-il-aux-autres-solutions-de-cache\">Qu&rsquo;est-ce que GroupCache et comment se compare-t-il aux autres solutions de cache\u00a0?<\/a><\/div><\/div><div class=\"d-flex mt-3\"><div class=\"w-auto fw-bold text-accent d-flex me-2\">05<\/div><div class=\"d-flex flex-column\"><a class=\"fw-bold scrollme link-body-color text-accent\" href=\"#groupcache-comme-outil-de-synchronisation\">GroupCache comme outil de synchronisation<\/a><\/div><\/div><div class=\"d-flex mt-3\"><div class=\"w-auto fw-bold text-accent d-flex me-2\">06<\/div><div class=\"d-flex flex-column\"><a class=\"fw-bold scrollme link-body-color text-accent\" href=\"#utilisation-de-groupcache\">Utilisation de GroupCache<\/a><\/div><\/div><div class=\"d-flex mt-3\"><div class=\"w-auto fw-bold text-accent d-flex me-2\">07<\/div><div class=\"d-flex flex-column\"><a class=\"fw-bold scrollme link-body-color text-accent\" href=\"#comment-limplementer-avec-http-2-et-tls\">Comment l&rsquo;impl\u00e9menter avec HTTP\/2 et TLS<\/a><\/div><\/div><div class=\"d-flex mt-3\"><div class=\"w-auto fw-bold text-accent d-flex me-2\">08<\/div><div class=\"d-flex flex-column\"><a class=\"fw-bold scrollme link-body-color text-accent\" href=\"#mise-a-jour-de-mailgun-concernant-la-suppression-de-cles\">Mise \u00e0 jour de Mailgun concernant la suppression de cl\u00e9s<\/a><\/div><\/div><div class=\"d-flex mt-3\"><div class=\"w-auto fw-bold text-accent d-flex me-2\">09<\/div><div class=\"d-flex flex-column\"><a class=\"fw-bold scrollme link-body-color text-accent\" href=\"#ameliorations-des-performances-de-mailgun-grace-a-groupcache\">Am\u00e9liorations des performances de Mailgun gr\u00e2ce \u00e0 GroupCache<\/a><\/div><\/div><div class=\"d-flex mt-3\"><div class=\"w-auto fw-bold text-accent d-flex me-2\">10<\/div><div class=\"d-flex flex-column\"><a class=\"fw-bold scrollme link-body-color text-accent\" href=\"#conclusion-la-mise-en-cache-distribuee-simplifiee\">Conclusion\u00a0: la mise en cache distribu\u00e9e simplifi\u00e9e<\/a><\/div><\/div><\/nav>\n\n\n<h2 class=\"wp-block-heading\">Qu&rsquo;est-ce qu&rsquo;un cache distribu\u00e9\u00a0?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Un cache est une solution de stockage en m\u00e9moire \u00e0 haut d\u00e9bit qui conserve les donn\u00e9es tr\u00e8s demand\u00e9es pour acc\u00e9l\u00e9rer leur r\u00e9cup\u00e9ration. <b>Un cache distribu\u00e9 divise le cache en segments et les distribue<\/b> de sorte que chaque n\u0153ud d&rsquo;un cluster de serveurs ne contienne qu&rsquo;un seul segment du cache entier. De cette fa\u00e7on, le cache peut continuer \u00e0 \u00e9voluer en ajoutant simplement de nouveaux n\u0153uds au cluster.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">C&rsquo;est important pour plusieurs raisons.<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><b>Les caches distribu\u00e9s permettent au cache de cro\u00eetre en m\u00eame temps que les donn\u00e9es.<\/b> Ils sont avantageux dans les environnements avec un volume de donn\u00e9es et une charge \u00e9lev\u00e9s.<\/li>\n\n\n\n<li><b>Un cache distribu\u00e9 peut s&rsquo;\u00e9tendre sur plusieurs serveurs<\/b>, ce qui lui conf\u00e8re une capacit\u00e9 de transaction beaucoup plus \u00e9lev\u00e9e.<\/li>\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\">Comment fonctionne la mise en cache distribu\u00e9e\u00a0?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Les syst\u00e8mes de cache distribu\u00e9 comme Redis et les clients Memcached fonctionnent g\u00e9n\u00e9ralement de la mani\u00e8re suivante\u00a0:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>L&rsquo;<b>App<\/b> demande les donn\u00e9es en cache au <b>Client<\/b> via une cl\u00e9.<\/li>\n\n\n\n<li>Ensuite, le <b>Client<\/b> effectue un hachage coh\u00e9rent sur la cl\u00e9 pour d\u00e9terminer quel <b>Node<\/b> poss\u00e8de les donn\u00e9es.<\/li>\n\n\n\n<li>Une fois que le <b>Client<\/b> a localis\u00e9 les donn\u00e9es, il effectue une requ\u00eate r\u00e9seau vers le <b>Node<\/b>.<\/li>\n\n\n\n<li>Le <b>Node<\/b> renvoie les donn\u00e9es s&rsquo;il les trouve.<\/li>\n\n\n\n<li>L&rsquo;<b>App<\/b> v\u00e9rifie si des donn\u00e9es sont renvoy\u00e9es, sinon elle g\u00e9n\u00e8re ou r\u00e9cup\u00e8re les donn\u00e9es de la base de donn\u00e9es. <\/li>\n\n\n\n<li>L&rsquo;<b>App<\/b> indique au <b>Client<\/b> de stocker les donn\u00e9es pour cette cl\u00e9.<\/li>\n\n\n\n<li>Le <b>Client<\/b> effectue un hachage coh\u00e9rent sur la cl\u00e9 pour d\u00e9terminer quel <b>Node<\/b> doit poss\u00e9der les donn\u00e9es.<\/li>\n\n\n\n<li>Enfin, le <b>Client<\/b> stocke les donn\u00e9es sur le <b>Node<\/b>.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">En examinant ce flux, deux grandes implications se d\u00e9gagent\u00a0: <\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Chaque requ\u00eate de cache entra\u00eene un aller-retour vers un <b>Node<\/b>, qu&rsquo;il y ait un succ\u00e8s (hit) ou un \u00e9chec (miss) de cache.<\/li>\n\n\n\n<li>Vous ne pouvez pas \u00e9viter l&rsquo;aller-retour vers un <b>Node<\/b> en mettant la valeur en cache localement, car le <b>Node<\/b> distant pourrait invalider les donn\u00e9es \u00e0 tout moment sans que l&rsquo;<b>App<\/b> ne le sache.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">Bien qu&rsquo;aucune de ces implications ne soit particuli\u00e8rement g\u00eanante pour la plupart des applications, les allers-retours suppl\u00e9mentaires vers la base de donn\u00e9es peuvent avoir un impact sur les applications \u00e0 haute performance et \u00e0 faible latence. Cependant, il y a une autre implication qui n&rsquo;est peut-\u00eatre pas imm\u00e9diatement \u00e9vidente\u00a0: le probl\u00e8me du thundering herd\u00a0!<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">R\u00e9soudre le probl\u00e8me du thundering herd\u00a0: temp\u00eates de cache et haute simultan\u00e9it\u00e9<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"><b>Le probl\u00e8me du thundering herd est une avalanche de requ\u00eates qui sature le syst\u00e8me.<\/b> Parfois appel\u00e9 temp\u00eate de cache (cache stampede), dogpiling ou effet Slashdot, ce probl\u00e8me survient lorsque des instances simultan\u00e9es d&rsquo;une application tentent toutes d&rsquo;acc\u00e9der \u00e0 des donn\u00e9es en m\u00eame temps.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Dans le cadre de cet article, notre thundering herd fait suite \u00e0 un \u00e9chec de cache, ce qui signifie que les donn\u00e9es ont \u00e9t\u00e9 soit supprim\u00e9es, soit jamais plac\u00e9es dans le cache. Par exemple, en fonctionnement normal, <b>une application reste responsive sous une forte charge tant que les donn\u00e9es restent en cache<\/b>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Lorsque le cache ne contient pas les donn\u00e9es, ce thundering herd de requ\u00eates simultan\u00e9es pourrait saturer le syst\u00e8me et entra\u00eener une congestion, voire un effondrement du syst\u00e8me.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Pour lutter contre ce travail simultan\u00e9, vous avez besoin d&rsquo;un syst\u00e8me pour synchroniser la r\u00e9cup\u00e9ration ou la g\u00e9n\u00e9ration des donn\u00e9es. Heureusement,\u202f<b>il existe une biblioth\u00e8que Golang appel\u00e9e <\/b><a href=\"https:\/\/github.com\/mailgun\/groupcache\" target=\"_tabs\" rel=\"noopener noreferrer\"><b>GroupCache<\/b><\/a><b> qui peut \u00eatre utilis\u00e9e pour r\u00e9soudre le probl\u00e8me du thundering herd<\/b>\u202fet am\u00e9liorer les implications du cache distant que nous avons mentionn\u00e9es.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Qu&rsquo;est-ce que GroupCache et comment se compare-t-il aux autres solutions de cache\u00a0?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Il existe de nombreuses solutions de cache sur le march\u00e9. GroupCache de Golang est une solution open source qui diff\u00e8re des outils populaires comme BigCache, Redis et Memcache, car elle <b>s&rsquo;int\u00e8gre directement \u00e0 votre code en tant que cache distribu\u00e9 dans le code (ICDC)<\/b>. Cela signifie que chaque instance de l&rsquo;<b>App<\/b> <i>est<\/i> un <b>Node<\/b> dans le cache distribu\u00e9. L&rsquo;avantage\u00a0? En tant que membre \u00e0 part enti\u00e8re du cache distribu\u00e9, chaque instance d&rsquo;application conna\u00eet les structures de donn\u00e9es, non seulement pour savoir comment stocker les donn\u00e9es du n\u0153ud, mais aussi comment r\u00e9cup\u00e9rer ou g\u00e9n\u00e9rer les donn\u00e9es si elles sont manquantes.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Pour comprendre pourquoi cela est sup\u00e9rieur \u00e0 Redis ou Memcached, examinons le flux de mise en cache distribu\u00e9e lors de l&rsquo;utilisation de GroupCache. En lisant le flux, gardez \u00e0 l&rsquo;esprit <b>que GroupCache est une biblioth\u00e8que utilis\u00e9e par l&rsquo;application qui \u00e9coute \u00e9galement les requ\u00eates entrantes provenant d&rsquo;autres instances de l&rsquo;application<\/b> qui utilisent GroupCache.<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>L&rsquo;<b>App<\/b> demande les donn\u00e9es \u00e0 <b>GroupCache<\/b> via une cl\u00e9.<\/li>\n\n\n\n<li>Ensuite, <b>GroupCache<\/b> v\u00e9rifie le cache chaud en m\u00e9moire pour les donn\u00e9es, s&rsquo;il n&rsquo;y a pas de donn\u00e9es, il continue.<\/li>\n\n\n\n<li><b>GroupCache<\/b> effectue un hachage coh\u00e9rent sur la cl\u00e9 pour d\u00e9terminer quelle instance <b>GroupCache<\/b> poss\u00e8de les donn\u00e9es.<\/li>\n\n\n\n<li>Puis, <b>GroupCache<\/b> effectue une requ\u00eate r\u00e9seau vers l&rsquo;<b>instance GroupCache<\/b> qui poss\u00e8de les donn\u00e9es.<\/li>\n\n\n\n<li><b>GroupCache<\/b> renvoie les donn\u00e9es si elles existent en m\u00e9moire, sinon il demande \u00e0 l&rsquo;<b>App<\/b> de g\u00e9n\u00e9rer ou de r\u00e9cup\u00e9rer les donn\u00e9es.<\/li>\n\n\n\n<li>Enfin, <b>GroupCache<\/b> renvoie les donn\u00e9es \u00e0 l&rsquo;<b>instance GroupCache<\/b> qui a initi\u00e9 la requ\u00eate. <\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">L&rsquo;<b>\u00e9tape 5<\/b> est importante dans le contexte d&rsquo;un \u00e9v\u00e9nement de type thundering herd, car <b>seule l&rsquo;une des instances GroupCache<\/b> effectuera la g\u00e9n\u00e9ration ou la r\u00e9cup\u00e9ration des donn\u00e9es demand\u00e9es. Toutes les autres instances de l&rsquo;application \u2013 qui demandent \u00e9galement les donn\u00e9es \u00e0 l&rsquo;instance GroupCache \u2013 seront bloqu\u00e9es jusqu&rsquo;\u00e0 ce que l&rsquo;instance propri\u00e9taire de l&rsquo;application g\u00e9n\u00e8re ou r\u00e9cup\u00e8re les donn\u00e9es avec succ\u00e8s. <b>Cela cr\u00e9e un point de synchronisation naturel pour l&rsquo;acc\u00e8s aux donn\u00e9es dans le syst\u00e8me distribu\u00e9<\/b> et annule le probl\u00e8me du thundering herd. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">L&rsquo;<b>\u00e9tape 2<\/b> est \u00e9galement importante car la capacit\u00e9 de mettre en cache les donn\u00e9es localement en m\u00e9moire \u00e9vite le co\u00fbt d&rsquo;un aller-retour r\u00e9seau, offrant un \u00e9norme avantage en termes de performances et r\u00e9duisant la pression sur le r\u00e9seau. Puisque <b>GroupCache<\/b> fait partie de l&rsquo;application, nous \u00e9vitons la possibilit\u00e9 que <b>GroupCache<\/b> supprime les donn\u00e9es \u00e0 l&rsquo;insu de l&rsquo;application, car tout \u00e9v\u00e9nement de suppression de ce type est partag\u00e9 par toutes les instances de l&rsquo;application utilisant <b>GroupCache<\/b>. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Un avantage certes mineur \u2013 mais que ceux d&rsquo;entre nous qui aiment la simplicit\u00e9 peuvent appr\u00e9cier \u2013 est celui du d\u00e9ploiement. Bien qu&rsquo;il ne soit pas tr\u00e8s difficile de d\u00e9ployer et de s\u00e9curiser Redis et Memcached en tant qu&rsquo;entit\u00e9s distinctes de l&rsquo;application, le fait d&rsquo;avoir une seule application \u00e0 d\u00e9ployer signifie une chose de moins \u00e0 g\u00e9rer, \u00e0 maintenir \u00e0 jour et \u00e0 s\u00e9curiser pour l&rsquo;\u00e9quipe op\u00e9rationnelle. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Il vaut la peine de le mentionner \u00e0 nouveau car c&rsquo;est facile \u00e0 n\u00e9gliger. La capacit\u00e9 de l&rsquo;impl\u00e9mentation du cache \u00e0 g\u00e9n\u00e9rer ou \u00e0 r\u00e9cup\u00e9rer les donn\u00e9es d&rsquo;une base de donn\u00e9es lors d&rsquo;un \u00e9chec de cache, et la capacit\u00e9 \u00e0 s&rsquo;appuyer sur un cache chaud local en m\u00e9moire, font de GroupCache un choix sup\u00e9rieur parmi les caches distribu\u00e9s. Aucun cache distribu\u00e9 externe \u00e0 votre application ne peut offrir ces avantages.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">GroupCache comme outil de synchronisation<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u00c9tant donn\u00e9 que GroupCache fournit une excellente s\u00e9mantique de synchronisation, nous avons trouv\u00e9 que GroupCache est <b>une alternative sup\u00e9rieure aux verrous distribu\u00e9s ou au niveau de la base de donn\u00e9es<\/b> lors de la cr\u00e9ation et de la gestion de ressources uniques.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u00c0 titre d&rsquo;exemple, notre moteur de statistiques interne lit des milliers d&rsquo;\u00e9v\u00e9nements et ajoute dynamiquement des balises avec des statistiques attribu\u00e9es. Comme nous avons de nombreuses instances du moteur en cours d&rsquo;ex\u00e9cution, chaque nouvelle balise rencontr\u00e9e doit \u00eatre trait\u00e9e comme une nouvelle balise possible. Normalement, cela g\u00e9n\u00e9rerait un flux constant de requ\u00eates upsert vers notre base de donn\u00e9es. En utilisant GroupCache, chaque instance peut interroger le cache avec la cl\u00e9 <code>account:tag<\/code>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Si la balise existe d\u00e9j\u00e0, elle est renvoy\u00e9e avec les derni\u00e8res donn\u00e9es sur la balise. Cependant, si la balise n&rsquo;existe pas, GroupCache relaie la requ\u00eate \u00e0 l&rsquo;instance propri\u00e9taire et cr\u00e9e la balise. De cette mani\u00e8re, un seul upsert est envoy\u00e9 \u00e0 la base de donn\u00e9es lorsque le syst\u00e8me rencontre une nouvelle balise.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">De la m\u00eame mani\u00e8re, nous utilisons GroupCache pour compter les compteurs uniques lorsque le syst\u00e8me ne doit enregistrer qu&rsquo;une seule instance d&rsquo;un compteur. Puisque nous utilisons <b>GroupCache, nous \u00e9vitons compl\u00e8tement d&rsquo;utiliser un verrou distribu\u00e9 et les probl\u00e8mes d&rsquo;interblocage<\/b>. Cela est particuli\u00e8rement utile lorsque vous utilisez une base de donn\u00e9es NoSQL avec peu ou pas de s\u00e9mantique de verrouillage ou de synchronisation propre.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Utilisation de GroupCache<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Mailgun utilise une version modifi\u00e9e de l&rsquo;\u0153uvre de <i>Brad Fitzpatrick (<\/i><a href=\"https:\/\/github.com\/patrickmn\/go-cache\" target=\"_tabs\" rel=\"noopener noreferrer\"><i>patrickmn<\/i><\/a><i>)<\/i>, la  <a href=\"https:\/\/github.com\/mailgun\/groupcache\" target=\"_tabs\" rel=\"noopener noreferrer\">biblioth\u00e8que GroupCache originale sur github.com<\/a>.<\/p>\n\n\n    <div data-content-type=\"longform\"  class=\"callout text-body-color px-5 py-6 px-md-6 px-lg-7 py-md-7 longform-spacings rounded-lg bg-light\" data-theme=\"light\">\r\n\r\n        <div class=\"content-body\"> Pour consulter la documentation de l&rsquo;API et des exemples, rendez-vous sur <a href='http:\/\/godoc.org\/github.com\/mailgun\/groupcache'>http:\/\/godoc.org\/github.com\/mailgun\/groupcache<\/a><\/div>\r\n    <\/div>\r\n\n\n\n<p class=\"wp-block-paragraph\">Les modifications notables apport\u00e9es \u00e0 la biblioth\u00e8que sont les suivantes\u00a0:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Support de la suppression explicite de cl\u00e9s d&rsquo;un groupe. <code>Remove()<\/code><\/li>\n\n\n\n<li>Support des valeurs expir\u00e9es. <code>SetBytes()<\/code>, <code>SetProto()<\/code> et <code>SetString()<\/code> acceptent d\u00e9sormais un param\u00e8tre optionnel <code>time.Time{}<\/code> qui repr\u00e9sente une heure dans le futur \u00e0 laquelle la valeur expirera.<\/li>\n\n\n\n<li>Support du standard Golang <code>context.Context<\/code><\/li>\n\n\n\n<li>Remplit toujours le hotcache<\/li>\n\n\n\n<li>Pour utiliser GroupCache, vous cr\u00e9ez un pool d&rsquo;instances avec lequel chaque instance GroupCache communiquera, puis vous cr\u00e9ez plusieurs groupes de cache ind\u00e9pendants qui utilisent le m\u00eame pool d&rsquo;instances.<\/li>\n\n\n\n<li>Gardez une trace des pairs dans notre cluster et ajoutez notre instance au pool `<code>http:\/\/localhost:8080` pool := groupcache.NewHTTPPoolOpts(\"http:\/\/localhost:8080\", &amp;groupcache.HTTPPoolOptions{}<\/code>)<\/li>\n\n\n\n<li>Ajoutez d&rsquo;autres pairs <code>pool.Set(\"http:\/\/peer1:8080\", \"http:\/\/peer2:8080\")<\/code><\/li>\n\n\n\n<li>Cr\u00e9ez un nouveau cache de groupe avec une taille de cache maximale de 3\u00a0Mo group: = <code>groupcache.NewGroup(\"users\", 3000000, groupcache.GetterFunc( func(ctx context.Context, id string, dest groupcache.Sink) error { \/\/ Returns a protobuf struct `User` if user, err := fetchUserFromMongo(ctx, id); err != nil { return err }<\/code><\/li>\n\n\n\n<li>Configurez l&rsquo;utilisateur dans groupcache pour qu&rsquo;il expire apr\u00e8s 5 minutes <code>if err := dest.SetProto(&amp;user, time.Now().Add(time.Minute*5)); err != nil { return err } return nil }, ))<\/code> <\/li>\n\n\n\n<li>var user User<\/li>\n\n\n\n<li>R\u00e9cup\u00e9rez la d\u00e9finition dans le cache de groupe ctx, <code>cancel := context.WithTimeout(context.Background(), time.Second*10) if err := group.Get(ctx, \u201ckey\u201d, groupcache.ProtoSink(&amp;user)); err != nil { return nil, err } cancel()<\/code> <\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Comment l&rsquo;impl\u00e9menter avec HTTP\/2 et TLS<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">GroupCache utilise HTTP pour communiquer entre les instances du cluster. Si votre application utilise \u00e9galement HTTP, GroupCache peut utiliser le m\u00eame port HTTP que votre application. Ajoutez simplement le pool en tant que gestionnaire avec son propre chemin.<\/p>\n\n\n    <div data-content-type=\"longform\" class=\"code-snippet longform-spacings rounded-lg overflow-hidden shadow \" data-count=\"1\">\r\n        <ul class=\"nav nav-buttons code-snippet__tabs longform-except position-relative d-flex gap-2 flex-wrap p-3\" role=\"tablist\">\r\n\r\n                            \r\n                    \r\n                        <li class=\"nav-item\" role=\"presentation\">\r\n                            <button class=\"nav-link active\" data-bs-toggle=\"tab\" data-bs-target=\"#code_0\" type=\"button\" role=\"tab\" aria-controls=\"code_0\" aria-selected=\"true\">\r\n                                PHP                            <\/button>\r\n                        <\/li>\r\n\r\n                    \r\n                            \r\n        <\/ul>\r\n        <div class=\"code-snippet__tab-content tab-content\">\r\n\r\n                            \r\n                    <div class=\"tab-pane show active\" id=\"code_0\" role=\"tabpanel\" aria-labelledby=\"code_0\">\r\n                        <div class=\"code-snippet__code-wrapper\">\r\n                            <div class=\"nav nav-buttons code-snippet__copy-wrapper\">\r\n                                <button type=\"button\" class=\"nav-link code-snippet__copy\" data-clipboard-target=\"#code_0_content\" data-clipboard-label=\"Copier dans le presse-papiers\" data-clipboard-success-label=\"Copi\u00e9\u00a0!\" data-clipboard-error-label=\"Impossible de copier\" data-tooltip=\"Copier dans le presse-papiers\" data-tooltip-placement=\"left\" role=\"tooltip\" aria-label=\"Copier dans le presse-papiers\">\r\n                                    <svg class=\"code-snippet__copy-icon code-snippet__copy-icon--default\" width=\"24\" height=\"24\" aria-hidden=\"true\" data-url=\"https:\/\/www.mailgun.com\/wp-content\/plugins\/sinch-core\/assets\/icons\/sinch\/file-stack.svg\"><\/svg>\r\n                                    <svg class=\"code-snippet__copy-icon code-snippet__copy-icon--success\" width=\"24\" height=\"24\" aria-hidden=\"true\" data-url=\"https:\/\/www.mailgun.com\/wp-content\/plugins\/sinch-core\/assets\/icons\/sinch\/badge-check.svg\"><\/svg>\r\n                                <\/button>\r\n                            <\/div>\r\n                            <pre class=\"w-100 h-100 m-0 line-numbers language-PHP\">\r\n                                <code id=\"code_0_content\" class=\"language-PHP\">\r\n\r\n                                    1\/\/ Our application2http.HandleFunc(&quot;\/&quot;, func(w http.ResponseWriter, r *http.Request) {3 fmt.Fprint(w, &quot;Hi there&quot;)4})5\/\/ Handle GroupCache requests6http.Handle(&quot;\/_groupcache\/&quot;, pool)7log.Fatal(http.ListenAndServe(&quot;:8080&quot;, nil))8\r\n                                <\/code>\r\n                            <\/pre>\r\n                        <\/div>\r\n                    <\/div>\r\n                                    <\/div>\r\n    <\/div>\r\n\n\n\n<p class=\"wp-block-paragraph\">Si votre application a configur\u00e9 TLS, GroupCache b\u00e9n\u00e9ficiera de la m\u00eame configuration TLS que celle utilis\u00e9e par votre application, avec en plus la possibilit\u00e9 d&rsquo;activer HTTP\/2, ce qui am\u00e9liore encore les performances des requ\u00eates GroupCache.\u202f<a href=\"https:\/\/www.mailgun.com\/blog\/dev-life\/exemple-client-http-2-clair-h2c-go\/\" target=\"_tabs\" rel=\"noopener noreferrer\">Vous pouvez \u00e9galement utiliser HTTP\/2 sans TLS via H2C<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Mise \u00e0 jour de Mailgun concernant la suppression de cl\u00e9s<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"><b>Une diff\u00e9rence notable de la version Mailgun de GroupCache est la possibilit\u00e9 de supprimer explicitement des cl\u00e9s du cache.<\/b> Lorsqu&rsquo;une instance souhaite supprimer une cl\u00e9, elle supprime d&rsquo;abord la cl\u00e9 de l&rsquo;instance propri\u00e9taire, puis envoie les requ\u00eates de suppression \u00e0 toutes les autres instances du pool. Cela garantit que toutes les requ\u00eates futures provenant d&rsquo;instances non propri\u00e9taires du pool vers le propri\u00e9taire entra\u00eeneront une nouvelle r\u00e9cup\u00e9ration ou g\u00e9n\u00e9ration des donn\u00e9es (ou une erreur si les donn\u00e9es ne sont plus disponibles).<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Comme pour tout syst\u00e8me distribu\u00e9, il est possible qu&rsquo;une instance ne soit pas disponible, ou que la connectivit\u00e9 ait \u00e9t\u00e9 perdue au moment o\u00f9 la demande de suppression a \u00e9t\u00e9 effectu\u00e9e. Dans ce sc\u00e9nario, <code>group.Remove()<\/code> renverra une erreur indiquant que certaines instances n&rsquo;ont pas \u00e9t\u00e9 contact\u00e9es et pr\u00e9cisant la nature de l&rsquo;erreur. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Selon le cas d&rsquo;utilisation, l&rsquo;utilisateur a alors la possibilit\u00e9 de r\u00e9essayer l&rsquo;appel \u00e0 <code>group.Remove()<\/code> ou d&rsquo;ignorer l&rsquo;erreur. Pour certains syst\u00e8mes, il peut \u00eatre acceptable d&rsquo;ignorer l&rsquo;erreur, en particulier si vous utilisez la fonctionnalit\u00e9 de valeurs expir\u00e9es. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">La fonctionnalit\u00e9 de valeurs expir\u00e9es vous permet de fournir un d\u00e9lai d&rsquo;expiration optionnel <code>time.Time<\/code> qui sp\u00e9cifie une heure future \u00e0 laquelle les donn\u00e9es doivent expirer.<\/p>\n\n\n    <div data-content-type=\"longform\" class=\"code-snippet longform-spacings rounded-lg overflow-hidden shadow \" data-count=\"1\">\r\n        <ul class=\"nav nav-buttons code-snippet__tabs longform-except position-relative d-flex gap-2 flex-wrap p-3\" role=\"tablist\">\r\n\r\n                            \r\n                    \r\n                        <li class=\"nav-item\" role=\"presentation\">\r\n                            <button class=\"nav-link active\" data-bs-toggle=\"tab\" data-bs-target=\"#code_0\" type=\"button\" role=\"tab\" aria-controls=\"code_0\" aria-selected=\"true\">\r\n                                PHP                            <\/button>\r\n                        <\/li>\r\n\r\n                    \r\n                            \r\n        <\/ul>\r\n        <div class=\"code-snippet__tab-content tab-content\">\r\n\r\n                            \r\n                    <div class=\"tab-pane show active\" id=\"code_0\" role=\"tabpanel\" aria-labelledby=\"code_0\">\r\n                        <div class=\"code-snippet__code-wrapper\">\r\n                            <div class=\"nav nav-buttons code-snippet__copy-wrapper\">\r\n                                <button type=\"button\" class=\"nav-link code-snippet__copy\" data-clipboard-target=\"#code_0_content\" data-clipboard-label=\"Copier dans le presse-papiers\" data-clipboard-success-label=\"Copi\u00e9\u00a0!\" data-clipboard-error-label=\"Impossible de copier\" data-tooltip=\"Copier dans le presse-papiers\" data-tooltip-placement=\"left\" role=\"tooltip\" aria-label=\"Copier dans le presse-papiers\">\r\n                                    <svg class=\"code-snippet__copy-icon code-snippet__copy-icon--default\" width=\"24\" height=\"24\" aria-hidden=\"true\" data-url=\"https:\/\/www.mailgun.com\/wp-content\/plugins\/sinch-core\/assets\/icons\/sinch\/file-stack.svg\"><\/svg>\r\n                                    <svg class=\"code-snippet__copy-icon code-snippet__copy-icon--success\" width=\"24\" height=\"24\" aria-hidden=\"true\" data-url=\"https:\/\/www.mailgun.com\/wp-content\/plugins\/sinch-core\/assets\/icons\/sinch\/badge-check.svg\"><\/svg>\r\n                                <\/button>\r\n                            <\/div>\r\n                            <pre class=\"w-100 h-100 m-0 line-numbers language-PHP\">\r\n                                <code id=\"code_0_content\" class=\"language-PHP\">\r\n\r\n                                    1\/\/ Our application2http.HandleFunc(&quot;\/&quot;, func(w http.ResponseWriter, r *http.Request) {3 fmt.Fprint(w, &quot;Hi there&quot;)4})5\/\/ Handle GroupCache requests6http.Handle(&quot;\/_groupcache\/&quot;, pool)7log.Fatal(http.ListenAndServe(&quot;:8080&quot;, nil))8\r\n                                <\/code>\r\n                            <\/pre>\r\n                        <\/div>\r\n                    <\/div>\r\n                                    <\/div>\r\n    <\/div>\r\n\n\n\n<p class=\"wp-block-paragraph\">Dans le sc\u00e9nario ci-dessus o\u00f9 nous perdons temporairement la connectivit\u00e9 avec une instance, nous disons que le pool d&rsquo;instances est dans un \u00e9tat incoh\u00e9rent. Cependant, lorsqu&rsquo;elle est utilis\u00e9e conjointement avec la fonction d&rsquo;expiration des donn\u00e9es, nous savons que le syst\u00e8me redeviendra finalement coh\u00e9rent lorsque les donn\u00e9es sur les instances d\u00e9connect\u00e9es expireront. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Il existe d&rsquo;autres solutions beaucoup plus complexes pour r\u00e9soudre ce probl\u00e8me, mais nous avons constat\u00e9 dans la pratique que les solutions \u00e0 coh\u00e9rence \u00e0 terme (eventually consistent) sont <b>le moyen le plus simple et le moins sujet aux erreurs<\/b> de faire face aux perturbations du r\u00e9seau.<\/p>\n\n\n    <div data-content-type=\"longform\"  class=\"callout text-body-color px-5 py-6 px-md-6 px-lg-7 py-md-7 longform-spacings rounded-lg bg-light\" data-theme=\"light\">\r\n\r\n        <div class=\"content-body\"> Une petite remarque sur la d\u00e9couverte\u00a0: bien que GroupCache ne fournisse pas de m\u00e9thode pour d\u00e9couvrir les instances, il existe plusieurs syst\u00e8mes largement disponibles pour simplifier la d\u00e9couverte. Voici quelques options pour vous lancer\u00a0:<\/div><ul class=\"mb-0 mt-3\"><li><a href='https:\/\/github.com\/etcd-io\/etcd'>Etcd<\/a><\/li><li><a href='https:\/\/github.com\/kubernetes\/kubernetes'>Kubernetes<\/a><\/li><li><a href='https:\/\/github.com\/hashicorp\/consul'>Consul<\/a><\/li><li><a href='https:\/\/github.com\/hashicorp\/memberlist'>MemberList<\/a><\/li><\/ul>\r\n    <\/div>\r\n\n\n\n<h2 class=\"wp-block-heading\">Am\u00e9liorations des performances de Mailgun gr\u00e2ce \u00e0 GroupCache<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Chez Mailgun, notre premi\u00e8re utilisation en production de GroupCache s&rsquo;est faite dans notre service de limitation de d\u00e9bit (ratelimit). \u00c9tant donn\u00e9 que ce service doit fonctionner \u00e0 un niveau de tr\u00e8s haute performance et de faible latence, les syst\u00e8mes de cache traditionnels posaient probl\u00e8me\u00a0: plus nous introduisions d&rsquo;allers-retours dans le pipeline de requ\u00eates, plus nous avions d&rsquo;occasions d&rsquo;introduire une latence suppl\u00e9mentaire.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Les graphiques suivants <b>montrent le nombre total de succ\u00e8s de cache (hits) et parmi ces succ\u00e8s, le nombre total de succ\u00e8s qui ont entra\u00een\u00e9 un aller-retour vers une autre instance GroupCache<\/b>. Cela d\u00e9montre exactement \u00e0 quel point nous b\u00e9n\u00e9ficions du cache chaud local en m\u00e9moire, par opposition \u00e0 un appel aller-retour \u00e0 chaque requ\u00eate.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" class=\"wp-image-4841\" width=\"961\" height=\"469\" src=\"https:\/\/www.mailgun.com\/wp-content\/uploads\/2025\/07\/Screen_Shot_2022-11-22_at_4.18.53_PM__1_.png\" alt=\"Graph showing GroupCache hits and misses per second\" srcset=\"https:\/\/www.mailgun.com\/wp-content\/uploads\/2025\/07\/Screen_Shot_2022-11-22_at_4.18.53_PM__1_.png 961w, https:\/\/www.mailgun.com\/wp-content\/uploads\/2025\/07\/Screen_Shot_2022-11-22_at_4.18.53_PM__1_-300x146.png 300w, https:\/\/www.mailgun.com\/wp-content\/uploads\/2025\/07\/Screen_Shot_2022-11-22_at_4.18.53_PM__1_-768x375.png 768w\" sizes=\"(max-width: 961px) 100vw, 961px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Vous pouvez voir dans le graphique suivant \u00e0 quel point MongoDB et notre application b\u00e9n\u00e9ficient de l&rsquo;\u00e9vitement du thundering herd lorsque de nouvelles cl\u00e9s sont r\u00e9cup\u00e9r\u00e9es du syst\u00e8me.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" class=\"wp-image-4842\" width=\"696\" height=\"693\" src=\"https:\/\/www.mailgun.com\/wp-content\/uploads\/2025\/07\/Screen_Shot_2022-11-23_at_12.44.44_PM__2_.png\" alt=\"GroupCache peer request graph\" srcset=\"https:\/\/www.mailgun.com\/wp-content\/uploads\/2025\/07\/Screen_Shot_2022-11-23_at_12.44.44_PM__2_.png 696w, https:\/\/www.mailgun.com\/wp-content\/uploads\/2025\/07\/Screen_Shot_2022-11-23_at_12.44.44_PM__2_-150x150.png 150w, https:\/\/www.mailgun.com\/wp-content\/uploads\/2025\/07\/Screen_Shot_2022-11-23_at_12.44.44_PM__2_-300x300.png 300w\" sizes=\"(max-width: 696px) 100vw, 696px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Les appels r\u00e9els \u00e0 MongoDB repr\u00e9sentent une petite fraction du total des requ\u00eates r\u00e9ellement adress\u00e9es au service. C&rsquo;est ce qui, ajout\u00e9 \u00e0 la vitesse de gubernator, permet \u00e0 notre service de limitation de d\u00e9bit de fonctionner avec une faible latence, m\u00eame en cas de forte charge.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Vous pouvez voir ici les statistiques de temps de r\u00e9ponse du service de limitation de d\u00e9bit. Gardez \u00e0 l&rsquo;esprit que pour chaque requ\u00eate, nous effectuons un appel gubernator et une requ\u00eate GroupCache qui peuvent ou non entra\u00eener une requ\u00eate HTTP GroupCache ou une requ\u00eate MongoDB.\u202f<i>(Ce graphique montre les r\u00e9ponses les plus lentes, pas la moyenne)<\/i>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Conclusion\u00a0: la mise en cache distribu\u00e9e simplifi\u00e9e<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">GroupCache a am\u00e9lior\u00e9 les performances de nos services chez Mailgun. Il rend <b>la mise en cache distribu\u00e9e et la synchronisation simples et faciles<\/b> \u00e0 d\u00e9ployer. J&rsquo;esp\u00e8re que d&rsquo;autres d\u00e9couvriront les m\u00eames avantages dont nous profitons et que cela inspirera d&rsquo;autres impl\u00e9mentations d&rsquo;ICDC dans d&rsquo;autres langages.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Cet article vous a-t-il \u00e9t\u00e9 utile\u00a0? Chez Mailgun, nous \u00e9valuons et impl\u00e9mentons constamment de nouvelles fa\u00e7ons d&rsquo;aider \u00e0 faire \u00e9voluer nos services et d&rsquo;am\u00e9liorer nos performances. Ce n&rsquo;est pas toujours facile. Nous aimerions que vous appreniez de nos exp\u00e9riences. Inscrivez-vous \u00e0 notre newsletter pour plus de contenu de ce type.<\/p>\n\n\n    <div data-content-type=\"longform\" class=\"longform-spacings\">\r\n        <div class=\"cta bg-primary rounded-lg px-5 py-6 p-md-7 px-md-6\">\r\n                    <div class=\"form-subscription\">\r\n                            <div class=\"h4 mb-3\">\r\n                    Tenez-moi au courant ! Recevez d&rsquo;excellentes ressources dans votre bo\u00eete de r\u00e9ception chaque semaine.                <\/div>\r\n                                    <form accept-charset=\"UTF-8\" action=\"\" enctype=\"multipart\/form-data\" data-form-subscription method=\"POST\" style=\"max-width: 400px;\">\r\n                <div class=\"row justify-content-between align-items-top g-2\">\r\n                    <div class=\"col-10\">\r\n                        <input type=\"email\" name=\"email\" class=\"form-control\" placeholder=\"Email\" autocomplete=\"email\" required>\r\n                        <div data-fs=\"error\" role=\"alert\" class=\"invalid-feedback\">\r\n                            Please complete this required field.                        <\/div>\r\n                    <\/div>\r\n                                            <div class=\"col-12 order-last mt-3 fs-xxs\" data-fs=\"acceptance\" style=\"display:none;\">\r\n                            \r\n                                <div class=\"form-check\">\r\n                                    <input id=\"formSubscriptionAcceptance-terms-8352\" class=\"form-check-input\"\r\n                                        type=\"checkbox\" name=\"terms\">\r\n                                    <label for=\"formSubscriptionAcceptance-terms-8352\" class=\"form-check-label text-body-color\">\r\n                                        J&rsquo;ai lu et j&rsquo;accepte les conditions d&rsquo;utilisation.                                        <span class=\"hs-form-required\">*<\/span>\r\n                                    <\/label>\r\n                                <\/div>\r\n\r\n                            \r\n                                <div class=\"form-check\">\r\n                                    <input id=\"formSubscriptionAcceptance-privacy-4283\" class=\"form-check-input\"\r\n                                        type=\"checkbox\" name=\"privacy\">\r\n                                    <label for=\"formSubscriptionAcceptance-privacy-4283\" class=\"form-check-label text-body-color\">\r\n                                        J&rsquo;ai lu et j&rsquo;accepte la politique de confidentialit\u00e9.                                        <span class=\"hs-form-required\">*<\/span>\r\n                                    <\/label>\r\n                                <\/div>\r\n\r\n                                                    <\/div>\r\n                    \r\n                                            <div class=\"col-12 order-last fs-xxs mb-0 mt-2 text-body-color\">\r\n                            Envoyez-moi la newsletter Mailjet. J&rsquo;accepte express\u00e9ment de recevoir la newsletter et je sais que je peux facilement me d\u00e9sabonner \u00e0 tout moment.                        <\/div>\r\n                    \r\n                    <div class=\"col-2\">\r\n                        <button type=\"submit\" value=\"Submit\" aria-label=\"Submit\" class=\"btn btn-secondary btn-icon\">\r\n                            <svg aria-hidden=\"true\" data-url=\"https:\/\/www.mailgun.com\/wp-content\/plugins\/sinch-core\/assets\/icons\/layout\/chevron-right.svg\"><\/svg>\r\n                        <\/button>\r\n                    <\/div>\r\n                <\/div>\r\n\r\n                <input type=\"hidden\" name=\"formSubscriptionRecaptchaToken\" data-fs=\"recaptcha-token\">\r\n                <input type=\"hidden\" name=\"customListID\" value=\"\">\r\n\r\n            <\/form>\r\n            <div data-fs=\"message-success\" style=\"display: none;\">\r\n                <p class=\"mb-0 mt-2 text-body-color\">\r\n                    D\u00e9couvrez la newsletter de Mailjet chaque mois dans votre bo\u00eete de r\u00e9ception.                <\/p>\r\n            <\/div>\r\n        <\/div>\r\n        <\/div>\r\n    <\/div>\r\n","protected":false},"excerpt":{"rendered":"<p>Le cache Golang, \u00e9galement connu sous le nom de GroupCache, a \u00e9t\u00e9 un ajout fantastique \u00e0 notre ensemble d&rsquo;outils de services distribu\u00e9s chez Mailgun. Voici comment vous pouvez l&rsquo;impl\u00e9menter dans le v\u00f4tre.<\/p>\n","protected":false},"author":35,"featured_media":4843,"menu_order":0,"template":"","meta":{"_acf_changed":true,"footnotes":""},"blog_category":[23],"class_list":["post-24675","blog","type-blog","status-publish","has-post-thumbnail","hentry","blog_category-it-and-engineering"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.4 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>La solution de cache de Golang sup\u00e9rieure \u00e0 Memcached et Redis - Transactional Email API Service For Developers | Mailgun<\/title>\n<meta name=\"description\" content=\"GroupCache a \u00e9t\u00e9 un ajout fantastique \u00e0 notre ensemble d&#039;outils de services distribu\u00e9s chez Mailgun. Voici comment vous pouvez l&#039;impl\u00e9menter dans le v\u00f4tre.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.mailgun.com\/fr\/blog\/it-and-engineering\/golangs-superior-cache-solution-memcached-redis\/\" \/>\n<meta property=\"og:locale\" content=\"fr_FR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"La solution de cache de Golang sup\u00e9rieure \u00e0 Memcached et Redis - Transactional Email API Service For Developers | Mailgun\" \/>\n<meta property=\"og:description\" content=\"GroupCache a \u00e9t\u00e9 un ajout fantastique \u00e0 notre ensemble d&#039;outils de services distribu\u00e9s chez Mailgun. Voici comment vous pouvez l&#039;impl\u00e9menter dans le v\u00f4tre.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.mailgun.com\/fr\/blog\/it-and-engineering\/golangs-superior-cache-solution-memcached-redis\/\" \/>\n<meta property=\"og:site_name\" content=\"Transactional Email API Service For Developers | Mailgun\" \/>\n<meta property=\"article:modified_time\" content=\"2026-09-16T16:56:38+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.mailgun.com\/wp-content\/uploads\/2025\/07\/MG-Blog-IT-Engineering.png\" \/>\n\t<meta property=\"og:image:width\" content=\"720\" \/>\n\t<meta property=\"og:image:height\" content=\"448\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data1\" content=\"10 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.mailgun.com\\\/fr\\\/blog\\\/it-and-engineering\\\/golangs-superior-cache-solution-memcached-redis\\\/\",\"url\":\"https:\\\/\\\/www.mailgun.com\\\/fr\\\/blog\\\/it-and-engineering\\\/golangs-superior-cache-solution-memcached-redis\\\/\",\"name\":\"La solution de cache de Golang sup\u00e9rieure \u00e0 Memcached et Redis - Transactional Email API Service For Developers | Mailgun\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.mailgun.com\\\/fr\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.mailgun.com\\\/fr\\\/blog\\\/it-and-engineering\\\/golangs-superior-cache-solution-memcached-redis\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.mailgun.com\\\/fr\\\/blog\\\/it-and-engineering\\\/golangs-superior-cache-solution-memcached-redis\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.mailgun.com\\\/wp-content\\\/uploads\\\/2025\\\/07\\\/MG-Blog-IT-Engineering.png\",\"datePublished\":\"2022-12-01T00:00:00+00:00\",\"dateModified\":\"2026-09-16T16:56:38+00:00\",\"description\":\"GroupCache a \u00e9t\u00e9 un ajout fantastique \u00e0 notre ensemble d'outils de services distribu\u00e9s chez Mailgun. Voici comment vous pouvez l'impl\u00e9menter dans le v\u00f4tre.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.mailgun.com\\\/fr\\\/blog\\\/it-and-engineering\\\/golangs-superior-cache-solution-memcached-redis\\\/#breadcrumb\"},\"inLanguage\":\"fr-FR\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.mailgun.com\\\/fr\\\/blog\\\/it-and-engineering\\\/golangs-superior-cache-solution-memcached-redis\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"fr-FR\",\"@id\":\"https:\\\/\\\/www.mailgun.com\\\/fr\\\/blog\\\/it-and-engineering\\\/golangs-superior-cache-solution-memcached-redis\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.mailgun.com\\\/wp-content\\\/uploads\\\/2025\\\/07\\\/MG-Blog-IT-Engineering.png\",\"contentUrl\":\"https:\\\/\\\/www.mailgun.com\\\/wp-content\\\/uploads\\\/2025\\\/07\\\/MG-Blog-IT-Engineering.png\",\"width\":720,\"height\":448},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.mailgun.com\\\/fr\\\/blog\\\/it-and-engineering\\\/golangs-superior-cache-solution-memcached-redis\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.mailgun.com\\\/fr\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Blog\",\"item\":\"https:\\\/\\\/www.mailgun.com\\\/fr\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"GroupCache\u00a0: la solution de cache sup\u00e9rieure pour Golang\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.mailgun.com\\\/fr\\\/#website\",\"url\":\"https:\\\/\\\/www.mailgun.com\\\/fr\\\/\",\"name\":\"Transactional Email API Service For Developers | Mailgun\",\"description\":\"Des API d\u2019emails transactionnels puissantes qui vous permettent d'envoyer, de recevoir et de suivre des emails, con\u00e7ues pour les d\u00e9veloppeurs. En savoir plus d\u00e8s aujourd'hui !\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.mailgun.com\\\/fr\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.mailgun.com\\\/fr\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"fr-FR\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.mailgun.com\\\/fr\\\/#organization\",\"name\":\"Transactional Email API Service For Developers | Mailgun\",\"url\":\"https:\\\/\\\/www.mailgun.com\\\/fr\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"fr-FR\",\"@id\":\"https:\\\/\\\/www.mailgun.com\\\/fr\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.mailgun.com\\\/wp-content\\\/uploads\\\/2025\\\/06\\\/cropped-android-chrome-512x512-1.png\",\"contentUrl\":\"https:\\\/\\\/www.mailgun.com\\\/wp-content\\\/uploads\\\/2025\\\/06\\\/cropped-android-chrome-512x512-1.png\",\"width\":512,\"height\":512,\"caption\":\"Transactional Email API Service For Developers | Mailgun\"},\"image\":{\"@id\":\"https:\\\/\\\/www.mailgun.com\\\/fr\\\/#\\\/schema\\\/logo\\\/image\\\/\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"La solution de cache de Golang sup\u00e9rieure \u00e0 Memcached et Redis - Transactional Email API Service For Developers | Mailgun","description":"GroupCache a \u00e9t\u00e9 un ajout fantastique \u00e0 notre ensemble d'outils de services distribu\u00e9s chez Mailgun. Voici comment vous pouvez l'impl\u00e9menter dans le v\u00f4tre.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.mailgun.com\/fr\/blog\/it-and-engineering\/golangs-superior-cache-solution-memcached-redis\/","og_locale":"fr_FR","og_type":"article","og_title":"La solution de cache de Golang sup\u00e9rieure \u00e0 Memcached et Redis - Transactional Email API Service For Developers | Mailgun","og_description":"GroupCache a \u00e9t\u00e9 un ajout fantastique \u00e0 notre ensemble d'outils de services distribu\u00e9s chez Mailgun. Voici comment vous pouvez l'impl\u00e9menter dans le v\u00f4tre.","og_url":"https:\/\/www.mailgun.com\/fr\/blog\/it-and-engineering\/golangs-superior-cache-solution-memcached-redis\/","og_site_name":"Transactional Email API Service For Developers | Mailgun","article_modified_time":"2026-09-16T16:56:38+00:00","og_image":[{"width":720,"height":448,"url":"https:\/\/www.mailgun.com\/wp-content\/uploads\/2025\/07\/MG-Blog-IT-Engineering.png","type":"image\/png"}],"twitter_card":"summary_large_image","twitter_misc":{"Est. reading time":"10 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/www.mailgun.com\/fr\/blog\/it-and-engineering\/golangs-superior-cache-solution-memcached-redis\/","url":"https:\/\/www.mailgun.com\/fr\/blog\/it-and-engineering\/golangs-superior-cache-solution-memcached-redis\/","name":"La solution de cache de Golang sup\u00e9rieure \u00e0 Memcached et Redis - Transactional Email API Service For Developers | Mailgun","isPartOf":{"@id":"https:\/\/www.mailgun.com\/fr\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.mailgun.com\/fr\/blog\/it-and-engineering\/golangs-superior-cache-solution-memcached-redis\/#primaryimage"},"image":{"@id":"https:\/\/www.mailgun.com\/fr\/blog\/it-and-engineering\/golangs-superior-cache-solution-memcached-redis\/#primaryimage"},"thumbnailUrl":"https:\/\/www.mailgun.com\/wp-content\/uploads\/2025\/07\/MG-Blog-IT-Engineering.png","datePublished":"2022-12-01T00:00:00+00:00","dateModified":"2026-09-16T16:56:38+00:00","description":"GroupCache a \u00e9t\u00e9 un ajout fantastique \u00e0 notre ensemble d'outils de services distribu\u00e9s chez Mailgun. Voici comment vous pouvez l'impl\u00e9menter dans le v\u00f4tre.","breadcrumb":{"@id":"https:\/\/www.mailgun.com\/fr\/blog\/it-and-engineering\/golangs-superior-cache-solution-memcached-redis\/#breadcrumb"},"inLanguage":"fr-FR","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.mailgun.com\/fr\/blog\/it-and-engineering\/golangs-superior-cache-solution-memcached-redis\/"]}]},{"@type":"ImageObject","inLanguage":"fr-FR","@id":"https:\/\/www.mailgun.com\/fr\/blog\/it-and-engineering\/golangs-superior-cache-solution-memcached-redis\/#primaryimage","url":"https:\/\/www.mailgun.com\/wp-content\/uploads\/2025\/07\/MG-Blog-IT-Engineering.png","contentUrl":"https:\/\/www.mailgun.com\/wp-content\/uploads\/2025\/07\/MG-Blog-IT-Engineering.png","width":720,"height":448},{"@type":"BreadcrumbList","@id":"https:\/\/www.mailgun.com\/fr\/blog\/it-and-engineering\/golangs-superior-cache-solution-memcached-redis\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.mailgun.com\/fr\/"},{"@type":"ListItem","position":2,"name":"Blog","item":"https:\/\/www.mailgun.com\/fr\/blog\/"},{"@type":"ListItem","position":3,"name":"GroupCache\u00a0: la solution de cache sup\u00e9rieure pour Golang"}]},{"@type":"WebSite","@id":"https:\/\/www.mailgun.com\/fr\/#website","url":"https:\/\/www.mailgun.com\/fr\/","name":"Transactional Email API Service For Developers | Mailgun","description":"Des API d\u2019emails transactionnels puissantes qui vous permettent d'envoyer, de recevoir et de suivre des emails, con\u00e7ues pour les d\u00e9veloppeurs. En savoir plus d\u00e8s aujourd'hui !","publisher":{"@id":"https:\/\/www.mailgun.com\/fr\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.mailgun.com\/fr\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"fr-FR"},{"@type":"Organization","@id":"https:\/\/www.mailgun.com\/fr\/#organization","name":"Transactional Email API Service For Developers | Mailgun","url":"https:\/\/www.mailgun.com\/fr\/","logo":{"@type":"ImageObject","inLanguage":"fr-FR","@id":"https:\/\/www.mailgun.com\/fr\/#\/schema\/logo\/image\/","url":"https:\/\/www.mailgun.com\/wp-content\/uploads\/2025\/06\/cropped-android-chrome-512x512-1.png","contentUrl":"https:\/\/www.mailgun.com\/wp-content\/uploads\/2025\/06\/cropped-android-chrome-512x512-1.png","width":512,"height":512,"caption":"Transactional Email API Service For Developers | Mailgun"},"image":{"@id":"https:\/\/www.mailgun.com\/fr\/#\/schema\/logo\/image\/"}}]}},"_links":{"self":[{"href":"https:\/\/www.mailgun.com\/fr\/wp-json\/wp\/v2\/blog\/24675","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.mailgun.com\/fr\/wp-json\/wp\/v2\/blog"}],"about":[{"href":"https:\/\/www.mailgun.com\/fr\/wp-json\/wp\/v2\/types\/blog"}],"author":[{"embeddable":true,"href":"https:\/\/www.mailgun.com\/fr\/wp-json\/wp\/v2\/users\/35"}],"version-history":[{"count":1,"href":"https:\/\/www.mailgun.com\/fr\/wp-json\/wp\/v2\/blog\/24675\/revisions"}],"predecessor-version":[{"id":24676,"href":"https:\/\/www.mailgun.com\/fr\/wp-json\/wp\/v2\/blog\/24675\/revisions\/24676"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.mailgun.com\/fr\/wp-json\/wp\/v2\/media\/4843"}],"wp:attachment":[{"href":"https:\/\/www.mailgun.com\/fr\/wp-json\/wp\/v2\/media?parent=24675"}],"wp:term":[{"taxonomy":"blog_category","embeddable":true,"href":"https:\/\/www.mailgun.com\/fr\/wp-json\/wp\/v2\/blog_category?post=24675"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}