{"id":24073,"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-16T10:55:33","modified_gmt":"2026-09-16T10:55:33","slug":"golangs-superior-cache-solution-memcached-redis","status":"publish","type":"blog","link":"https:\/\/www.mailgun.com\/pt\/blog\/it-and-engineering\/golangs-superior-cache-solution-memcached-redis\/","title":{"rendered":"GroupCache: o cache superior para Golang"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">O cache para Golang torna o cache distribu\u00eddo e a sincroniza\u00e7\u00e3o simples e f\u00e1ceis de implantar com o GroupCache. Mas por que essa \u00e9 a ferramenta superior? E quais problemas ela resolve? Na Mailgun, usamos o GroupCache para reduzir a lat\u00eancia em nosso servi\u00e7o de limita\u00e7\u00e3o de taxa e colhemos os benef\u00edcios da sincroniza\u00e7\u00e3o, evitando problemas de deadlock ao criar e gerenciar recursos exclusivos. Se voc\u00ea n\u00e3o est\u00e1 convencido, tudo bem. Temos certeza de que estar\u00e1 no final deste texto.<\/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-6864\"><p class=\"h5 m-0\" id=\"toc-title-6864\">\u00cdndice<\/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=\"#o-que-e-um-cache-distribuido\">O que \u00e9 um cache distribu\u00eddo?<\/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=\"#como-funciona-o-cache-distribuido\">Como funciona o cache distribu\u00eddo?<\/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=\"#resolvendo-o-problema-do-thundering-herd-estouros-de-cache-e-alta-concorrencia\">Resolvendo o problema do thundering herd: estouros de cache e alta concorr\u00eancia<\/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=\"#o-que-e-o-groupcache-e-como-ele-se-compara-a-outras-solucoes-de-cache\">O que \u00e9 o GroupCache e como ele se compara a outras solu\u00e7\u00f5es de cache?<\/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-como-uma-ferramenta-de-sincronizacao\">GroupCache como uma ferramenta de sincroniza\u00e7\u00e3o<\/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=\"#usando-o-groupcache\">Usando o 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=\"#como-implementar-com-http-2-e-tls\">Como implementar com HTTP\/2 e 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=\"#atualizacao-de-remocao-de-chaves-da-mailgun\">Atualiza\u00e7\u00e3o de remo\u00e7\u00e3o de chaves da Mailgun<\/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=\"#melhorias-de-desempenho-da-mailgun-com-o-groupcache\">Melhorias de desempenho da Mailgun com o 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=\"#conclusao-cache-distribuido-de-forma-facil\">Conclus\u00e3o: cache distribu\u00eddo de forma f\u00e1cil<\/a><\/div><\/div><\/nav>\n\n\n<h2 class=\"wp-block-heading\">O que \u00e9 um cache distribu\u00eddo?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Um cache \u00e9 uma solu\u00e7\u00e3o de armazenamento de mem\u00f3ria de alta velocidade que ret\u00e9m dados de alta demanda para acelerar a recupera\u00e7\u00e3o e o acesso aos dados. <b>Um cache distribu\u00eddo divide o cache em segmentos e os distribui<\/b> de forma que cada n\u00f3 em um cluster de servidores contenha apenas um segmento de todo o cache. Dessa forma, o cache pode continuar a escalar simplesmente adicionando novos n\u00f3s ao cluster.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Isso \u00e9 importante por alguns motivos.<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><b>Caches distribu\u00eddos permitem que o cache cres\u00e7a \u00e0 medida que os dados crescem.<\/b> Eles s\u00e3o vantajosos em ambientes com alto volume de dados e carga.<\/li>\n\n\n\n<li><b>Um cache distribu\u00eddo pode abranger v\u00e1rios servidores<\/b>, proporcionando uma capacidade de transa\u00e7\u00e3o muito maior.<\/li>\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\">Como funciona o cache distribu\u00eddo?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Sistemas de cache distribu\u00eddo, como clientes do Redis e Memcached, geralmente funcionam assim:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>O <b>App<\/b> solicita ao <b>Client<\/b> os dados em cache por meio de uma chave.<\/li>\n\n\n\n<li>Em seguida, o <b>Client<\/b> realiza um hash consistente na chave para determinar qual <b>Node<\/b> possui os dados.<\/li>\n\n\n\n<li>Assim que o <b>Client<\/b> localiza os dados, ele faz uma solicita\u00e7\u00e3o de rede para o <b>Node<\/b>.<\/li>\n\n\n\n<li>O <b>Node<\/b> retorna os dados, se forem encontrados.<\/li>\n\n\n\n<li>O <b>App<\/b> verifica se os dados foram retornados; caso contr\u00e1rio, ele renderiza ou busca os dados no banco de dados. <\/li>\n\n\n\n<li>O <b>App<\/b> informa ao <b>Client<\/b> para armazenar os dados dessa chave.<\/li>\n\n\n\n<li>O <b>Client<\/b> executa um hash consistente na chave para determinar qual <b>Node<\/b> deve ser o propriet\u00e1rio dos dados.<\/li>\n\n\n\n<li>Finalmente, o <b>Client<\/b> armazena os dados no <b>Node<\/b>.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Analisando esse fluxo, h\u00e1 duas grandes implica\u00e7\u00f5es que se destacam: <\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Toda solicita\u00e7\u00e3o de cache resulta em uma ida e volta a um <b>Node<\/b>, independentemente de um cache hit ou miss.<\/li>\n\n\n\n<li>Voc\u00ea n\u00e3o pode evitar a ida e volta a um <b>Node<\/b> armazenando o valor localmente, pois o <b>Node<\/b> remoto pode invalidar os dados a qualquer momento sem o conhecimento do <b>App<\/b>.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">Embora nenhuma dessas implica\u00e7\u00f5es seja particularmente problem\u00e1tica para a maioria dos aplicativos, as idas e voltas adicionais ao banco de dados podem afetar os aplicativos de alto desempenho e baixa lat\u00eancia. No entanto, h\u00e1 mais uma implica\u00e7\u00e3o que pode n\u00e3o ser imediatamente \u00f3bvia: o thundering herd!<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Resolvendo o problema do thundering herd: estouros de cache e alta concorr\u00eancia<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"><b>O problema do thundering herd \u00e9 um estouro de solicita\u00e7\u00f5es que sobrecarregam o sistema.<\/b> \u00c0s vezes chamado de estouro de cache, dogpiling ou efeito slashdot, esse problema ocorre quando inst\u00e2ncias concorrentes de um aplicativo tentam acessar dados simultaneamente.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Para essa discuss\u00e3o, nosso thundering herd \u00e9 em resposta a um cache miss, o que significa que os dados foram removidos ou nunca foram colocados no cache. Por exemplo, em opera\u00e7\u00e3o normal, <b>um aplicativo permanece responsivo sob carga pesada, desde que os dados permane\u00e7am em cache<\/b>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Quando o cache n\u00e3o tem os dados, esse thundering herd de trabalho concorrente pode sobrecarregar o sistema e resultar em congestionamento e poss\u00edvel colapso do sistema.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Para combater esse trabalho concorrente, voc\u00ea precisa de um sistema para sincronizar a busca ou renderiza\u00e7\u00e3o dos dados. Felizmente, <b>existe uma biblioteca em Golang chamada <\/b><a href=\"https:\/\/github.com\/mailgun\/groupcache\" target=\"_tabs\" rel=\"noopener noreferrer\"><b>GroupCache<\/b><\/a><b> que pode ser usada para resolver o problema do thundering herd<\/b> e melhorar as implica\u00e7\u00f5es do cache remoto que mencionamos.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">O que \u00e9 o GroupCache e como ele se compara a outras solu\u00e7\u00f5es de cache?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Existem muitas solu\u00e7\u00f5es de cache no mercado. O GroupCache do Golang \u00e9 uma solu\u00e7\u00e3o de c\u00f3digo aberto que difere de ferramentas populares como BigCache, Redis e Memcache, pois <b>se integra diretamente ao seu c\u00f3digo como um In Code Distributed Cache (ICDC)<\/b>. Isso significa que cada inst\u00e2ncia do <b>App<\/b> <i>\u00e9<\/i> um <b>Node<\/b> no cache distribu\u00eddo. A vantagem? Como membro integral do cache distribu\u00eddo, cada inst\u00e2ncia do aplicativo conhece as estruturas de dados, n\u00e3o apenas como armazenar dados para o n\u00f3, mas tamb\u00e9m como buscar ou renderizar os dados se eles estiverem faltando.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Para entender por que isso \u00e9 superior ao Redis ou Memcached, vamos analisar o fluxo de cache distribu\u00eddo ao usar o GroupCache. Ao ler o fluxo, lembre-se de que <b>o GroupCache \u00e9 uma biblioteca usada pelo aplicativo que tamb\u00e9m escuta as solicita\u00e7\u00f5es recebidas de outras inst\u00e2ncias do aplicativo<\/b> que est\u00e3o usando o GroupCache.<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>O <b>App<\/b> solicita ao <b>GroupCache<\/b> os dados por meio de uma chave.<\/li>\n\n\n\n<li>Em seguida, o <b>GroupCache<\/b> verifica o hot cache na mem\u00f3ria em busca dos dados; se n\u00e3o houver, ele continua.<\/li>\n\n\n\n<li>O <b>GroupCache<\/b> realiza um hash consistente na chave para determinar qual inst\u00e2ncia do <b>GroupCache<\/b> tem os dados.<\/li>\n\n\n\n<li>Ent\u00e3o, o <b>GroupCache<\/b> faz uma solicita\u00e7\u00e3o de rede \u00e0 <b>inst\u00e2ncia do GroupCache<\/b> que possui os dados.<\/li>\n\n\n\n<li>O <b>GroupCache<\/b> retorna os dados se eles existirem na mem\u00f3ria; caso contr\u00e1rio, solicita que o <b>App<\/b> renderize ou busque os dados.<\/li>\n\n\n\n<li>Finalmente, o <b>GroupCache<\/b> retorna os dados \u00e0 <b>inst\u00e2ncia do GroupCache<\/b> que iniciou a solicita\u00e7\u00e3o. <\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">A <b>Etapa 5<\/b> \u00e9 significativa no contexto de um evento de thundering herd, pois <b>apenas uma das inst\u00e2ncias do GroupCache<\/b> executar\u00e1 a renderiza\u00e7\u00e3o ou busca dos dados solicitados. Todas as outras inst\u00e2ncias do aplicativo \u2013 que tamb\u00e9m est\u00e3o solicitando os dados da inst\u00e2ncia do GroupCache \u2013 ser\u00e3o bloqueadas at\u00e9 que a inst\u00e2ncia propriet\u00e1ria do aplicativo renderize ou busque os dados com sucesso. <b>Isso cria um ponto de sincroniza\u00e7\u00e3o natural para acesso aos dados no sistema distribu\u00eddo<\/b> e anula o problema do thundering herd. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A <b>Etapa 2<\/b> tamb\u00e9m \u00e9 significativa, pois a capacidade de armazenar os dados localmente em cache na mem\u00f3ria evita o custo de uma ida e volta \u00e0 rede, proporcionando um enorme benef\u00edcio de desempenho e press\u00e3o de rede reduzida. Como o <b>GroupCache<\/b> faz parte do aplicativo, evitamos a possibilidade de o <b>GroupCache<\/b> excluir os dados sem o conhecimento do aplicativo, j\u00e1 que qualquer evento de exclus\u00e3o desse tipo \u00e9 compartilhado por todas as inst\u00e2ncias do aplicativo usando o <b>GroupCache<\/b>. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Um benef\u00edcio reconhecidamente menor \u2014 mas que aqueles de n\u00f3s que gostam de simplicidade podem apreciar \u2014 \u00e9 o da implanta\u00e7\u00e3o. Embora n\u00e3o seja muito dif\u00edcil implantar e proteger o Redis e o Memcached como entidades separadas do aplicativo, ter um \u00fanico aplicativo para implantar significa uma coisa a menos para um operador lidar e manter atualizado e seguro. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Vale a pena mencionar de novo, pois \u00e9 f\u00e1cil de deixar passar. A capacidade da implementa\u00e7\u00e3o do cache de renderizar ou buscar os dados em um banco de dados durante um cache miss, e a capacidade de depender de um hot cache na mem\u00f3ria local \u00e9 o que torna o GroupCache uma escolha superior entre os caches distribu\u00eddos. Nenhum cache distribu\u00eddo externo ao seu aplicativo pode fornecer esses benef\u00edcios.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">GroupCache como uma ferramenta de sincroniza\u00e7\u00e3o<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Como o GroupCache fornece \u00f3timas sem\u00e2nticas de sincroniza\u00e7\u00e3o, descobrimos que ele \u00e9 <b>uma alternativa superior a bloqueios distribu\u00eddos ou no n\u00edvel do banco de dados<\/b> ao criar e gerenciar recursos exclusivos.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Como exemplo, nosso mecanismo de an\u00e1lises interno l\u00ea milhares de eventos e adiciona tags de forma din\u00e2mica com estat\u00edsticas atribu\u00eddas. Como temos muitas inst\u00e2ncias do mecanismo em execu\u00e7\u00e3o, cada nova tag vista deve ser tratada como uma poss\u00edvel nova tag. Normalmente, isso geraria um fluxo constante de solicita\u00e7\u00f5es upsert para nosso banco de dados. Usando o GroupCache, cada inst\u00e2ncia pode consultar o cache com a chave <code>account:tag<\/code>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Se a tag j\u00e1 existe, ela \u00e9 retornada com os dados mais recentes dela. No entanto, se a tag n\u00e3o existir, o GroupCache retransmite a solicita\u00e7\u00e3o para a inst\u00e2ncia propriet\u00e1ria e cria a tag. Dessa forma, apenas um \u00fanico upsert \u00e9 enviado ao banco de dados quando o sistema encontra uma nova tag.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Da mesma forma, usamos o GroupCache para contar contadores exclusivos em que o sistema deve registrar apenas uma \u00fanica inst\u00e2ncia de um contador. Como estamos usando o <b>GroupCache, evitamos completamente usar bloqueios distribu\u00eddos e problemas de deadlock<\/b>. Isso \u00e9 especialmente \u00fatil ao usar um banco de dados nosql com pouca ou nenhuma sem\u00e2ntica de bloqueio ou sincroniza\u00e7\u00e3o pr\u00f3pria.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Usando o GroupCache<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">A Mailgun executa uma vers\u00e3o modificada do c\u00f3digo de <i>Brad Fitzpatrick (<\/i><a href=\"https:\/\/github.com\/patrickmn\/go-cache\" target=\"_tabs\" rel=\"noopener noreferrer\"><i>patrickmn<\/i><\/a><i>)<\/i> original da <a href=\"https:\/\/github.com\/mailgun\/groupcache\" target=\"_tabs\" rel=\"noopener noreferrer\">biblioteca do GroupCache no 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\"> Para ver a documenta\u00e7\u00e3o e exemplos da API, consulte <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\">Mudan\u00e7as not\u00e1veis na biblioteca s\u00e3o:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Suporte para remo\u00e7\u00e3o de chaves expl\u00edcitas de um grupo. <code>Remove()<\/code><\/li>\n\n\n\n<li>Suporte para valores expirados. <code>SetBytes()<\/code>, <code>SetProto()<\/code> e <code>SetString()<\/code> agora aceitam um <code>time.Time{}<\/code> opcional, que representa um momento no futuro quando o valor ir\u00e1 expirar<\/li>\n\n\n\n<li>Suporte para o padr\u00e3o Golang <code>context.Context<\/code><\/li>\n\n\n\n<li>Sempre preenche o hotcache<\/li>\n\n\n\n<li>Para usar o GroupCache, voc\u00ea cria um Pool de inst\u00e2ncias com as quais cada inst\u00e2ncia do GroupCache falar\u00e1 e, em seguida, cria v\u00e1rios Groups de cache independentes que usam o mesmo Pool de inst\u00e2ncias.<\/li>\n\n\n\n<li>Rastreie os peers em nosso cluster e adicione nossa inst\u00e2ncia ao pool `<code>http:\/\/localhost:8080` pool := groupcache.NewHTTPPoolOpts(\"http:\/\/localhost:8080\", &amp;groupcache.HTTPPoolOptions{}<\/code>)<\/li>\n\n\n\n<li>Adicione mais peers <code>pool.Set(\"http:\/\/peer1:8080\", \"http:\/\/peer2:8080\")<\/code><\/li>\n\n\n\n<li>Crie um novo group cache com um tamanho m\u00e1ximo de cache de 3 MB group: = <code>groupcache.NewGroup(\"users\", 3000000, groupcache.GetterFunc( func(ctx context.Context, id string, dest groupcache.Sink) error { \/\/ Retorna uma struct protobuf `User` if user, err := fetchUserFromMongo(ctx, id); err != nil { return err }<\/code><\/li>\n\n\n\n<li>Defina o usu\u00e1rio no groupcache para expirar ap\u00f3s 5 minutos <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>Busque a defini\u00e7\u00e3o no cache do grupo 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\">Como implementar com HTTP\/2 e TLS<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">O GroupCache usa HTTP para se comunicar entre as inst\u00e2ncias no cluster. Se o seu aplicativo tamb\u00e9m usa HTTP, o GroupCache pode usar a mesma porta HTTP do seu aplicativo. Basta adicionar o pool como um handler com seu pr\u00f3prio caminho.<\/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=\"Copiar para a \u00e1rea de transfer\u00eancia\" data-clipboard-success-label=\"Copiado!\" data-clipboard-error-label=\"N\u00e3o foi poss\u00edvel copiar\" data-tooltip=\"Copiar para a \u00e1rea de transfer\u00eancia\" data-tooltip-placement=\"left\" role=\"tooltip\" aria-label=\"Copiar para a \u00e1rea de transfer\u00eancia\">\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\">Se o seu aplicativo tiver o TLS configurado, o GroupCache se beneficiar\u00e1 da mesma configura\u00e7\u00e3o de TLS que o seu aplicativo usa, tendo tamb\u00e9m a op\u00e7\u00e3o de ativar o HTTP\/2, o que melhora ainda mais o desempenho das solicita\u00e7\u00f5es do GroupCache.\u202f<a href=\"https:\/\/www.mailgun.com\/blog\/dev-life\/http-2-cleartext-h2c-client-example-go\/\" target=\"_tabs\" rel=\"noopener noreferrer\">Voc\u00ea tamb\u00e9m pode usar HTTP\/2 sem TLS por meio do H2C<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Atualiza\u00e7\u00e3o de remo\u00e7\u00e3o de chaves da Mailgun<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"><b>Uma diferen\u00e7a not\u00e1vel na vers\u00e3o da Mailgun do GroupCache \u00e9 a capacidade de excluir as chaves de forma expl\u00edcita do cache.<\/b> Quando uma inst\u00e2ncia deseja remover uma chave, primeiro ela exclui a chave da inst\u00e2ncia propriet\u00e1ria e, em seguida, envia as solicita\u00e7\u00f5es de exclus\u00e3o para todas as outras inst\u00e2ncias no pool. Isso garante que quaisquer solicita\u00e7\u00f5es futuras de inst\u00e2ncias n\u00e3o propriet\u00e1rias no pool para a propriet\u00e1ria resultar\u00e3o em uma nova busca ou renderiza\u00e7\u00e3o dos dados (ou em um erro, se os dados n\u00e3o estiverem mais dispon\u00edveis).<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Como em qualquer sistema distribu\u00eddo, h\u00e1 a possibilidade de que uma inst\u00e2ncia n\u00e3o esteja dispon\u00edvel ou a conectividade tenha sido perdida quando a solicita\u00e7\u00e3o de remo\u00e7\u00e3o foi feita. Nesse cen\u00e1rio, <code>group.Remove()<\/code> retornar\u00e1 um erro indicando que algumas inst\u00e2ncias n\u00e3o foram contatadas e a natureza do erro. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Dependendo do caso de uso, o usu\u00e1rio ent\u00e3o tem a op\u00e7\u00e3o de tentar novamente a chamada de <code>group.Remove()<\/code> ou ignorar o erro. Para alguns sistemas, ignorar o erro pode ser aceit\u00e1vel, especialmente se voc\u00ea estiver usando o recurso de valores expirados. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">O recurso de valores expirados permite que voc\u00ea forne\u00e7a um tempo de expira\u00e7\u00e3o opcional, <code>time.Time<\/code>, que especifica um momento futuro em que os dados devem expirar.<\/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=\"Copiar para a \u00e1rea de transfer\u00eancia\" data-clipboard-success-label=\"Copiado!\" data-clipboard-error-label=\"N\u00e3o foi poss\u00edvel copiar\" data-tooltip=\"Copiar para a \u00e1rea de transfer\u00eancia\" data-tooltip-placement=\"left\" role=\"tooltip\" aria-label=\"Copiar para a \u00e1rea de transfer\u00eancia\">\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\">No cen\u00e1rio acima, no qual perdemos temporariamente a conectividade com uma inst\u00e2ncia, dizemos que o pool de inst\u00e2ncias est\u00e1 em um estado inconsistente. No entanto, quando usado em conjunto com o recurso de expira\u00e7\u00e3o de dados, sabemos que o sistema acabar\u00e1 se tornando consistente de novo quando os dados nas inst\u00e2ncias desconectadas expirarem. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Existem outras solu\u00e7\u00f5es muito mais complexas para resolver esse problema, mas descobrimos na pr\u00e1tica que as solu\u00e7\u00f5es eventualmente consistentes s\u00e3o <b>a maneira mais simples e menos propensa a erros<\/b> de lidar com interrup\u00e7\u00f5es de rede.<\/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\"> Uma nota r\u00e1pida sobre descoberta: embora o GroupCache n\u00e3o forne\u00e7a um m\u00e9todo de descoberta de inst\u00e2ncias, existem v\u00e1rios sistemas amplamente dispon\u00edveis para tornar a descoberta simples. Veja algumas op\u00e7\u00f5es para voc\u00ea come\u00e7ar:<\/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\">Melhorias de desempenho da Mailgun com o GroupCache<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Na Mailgun, nosso primeiro uso de produ\u00e7\u00e3o do GroupCache foi em nosso servi\u00e7o de limite de taxa (ratelimit). Como esse servi\u00e7o deve operar em um n\u00edvel muito alto de desempenho\/baixa lat\u00eancia, os sistemas de cache tradicionais eram uma preocupa\u00e7\u00e3o; quanto mais idas e voltas introduz\u00edamos no pipeline de solicita\u00e7\u00f5es, mais oportunidades t\u00ednhamos de introduzir lat\u00eancia adicional.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Os gr\u00e1ficos a seguir <b>mostram o n\u00famero total de cache hits e, desses hits, o n\u00famero total de hits que resultaram em uma ida e volta para outra inst\u00e2ncia do GroupCache<\/b>. Isso demonstra exatamente o quanto nos beneficiamos do hot cache na mem\u00f3ria local em compara\u00e7\u00e3o com uma chamada de ida e volta em cada solicita\u00e7\u00e3o.<\/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\">Voc\u00ea pode ver no pr\u00f3ximo gr\u00e1fico exatamente o quanto o MongoDB e nosso aplicativo se beneficiam de evitar o thundering herd \u00e0 medida que novas chaves s\u00e3o recuperadas do sistema.<\/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\">As chamadas reais para o MongoDB s\u00e3o uma pequena fra\u00e7\u00e3o do total de solicita\u00e7\u00f5es que foram realmente feitas ao servi\u00e7o. Isso, al\u00e9m da velocidade do Gubernator, \u00e9 o que permite que nosso servi\u00e7o de limite de taxa tenha um desempenho de baixa lat\u00eancia, mesmo durante uma alta carga.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Aqui voc\u00ea pode ver as m\u00e9tricas de tempo de resposta do servi\u00e7o de limite de taxa. Lembre-se de que, para cada solicita\u00e7\u00e3o, fazemos uma chamada ao Gubernator e uma solicita\u00e7\u00e3o ao GroupCache, o que pode ou n\u00e3o resultar em uma solicita\u00e7\u00e3o HTTP do GroupCache ou solicita\u00e7\u00e3o ao MongoDB.\u202f<i>(Este gr\u00e1fico mostra as respostas mais lentas, e n\u00e3o a m\u00e9dia)<\/i>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Conclus\u00e3o: cache distribu\u00eddo de forma f\u00e1cil<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">O GroupCache melhorou o desempenho de nossos servi\u00e7os na Mailgun. Ele torna <b>o cache distribu\u00eddo e a sincroniza\u00e7\u00e3o simples e f\u00e1ceis<\/b> de implantar. Minha esperan\u00e7a \u00e9 que outras pessoas descubram os mesmos benef\u00edcios que estamos aproveitando e inspirem outras implementa\u00e7\u00f5es ICDC em outras linguagens.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Isso foi \u00fatil? Na Mailgun, estamos sempre avaliando e implementando novas formas de ajudar a escalar nossos servi\u00e7os e melhorar nosso desempenho. Isso nem sempre \u00e9 f\u00e1cil. Adorar\u00edamos que voc\u00ea aprendesse com nossas experi\u00eancias. Assine nossa newsletter para ver mais conte\u00fados como este.<\/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                    Mantenha-me informado! Receba \u00f3timos recursos em sua caixa de entrada toda semana.                <\/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-3023\" class=\"form-check-input\"\r\n                                        type=\"checkbox\" name=\"terms\">\r\n                                    <label for=\"formSubscriptionAcceptance-terms-3023\" class=\"form-check-label text-body-color\">\r\n                                        I have read and agree to the Terms of Service.                                        <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-9128\" class=\"form-check-input\"\r\n                                        type=\"checkbox\" name=\"privacy\">\r\n                                    <label for=\"formSubscriptionAcceptance-privacy-9128\" class=\"form-check-label text-body-color\">\r\n                                        I have read and agree to the Privacy Policy.                                        <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                            Envie-me a newsletter da Mailjet. Eu concordo expressamente em receber a newsletter e sei que posso cancelar a inscri\u00e7\u00e3o facilmente a qualquer momento.                        <\/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                    Verifique sua caixa de entrada mensalmente para receber sua newsletter da Mailjet!                <\/p>\r\n            <\/div>\r\n        <\/div>\r\n        <\/div>\r\n    <\/div>\r\n","protected":false},"excerpt":{"rendered":"<p>O cache para Golang, tamb\u00e9m conhecido como GroupCache, foi uma adi\u00e7\u00e3o fant\u00e1stica ao nosso conjunto de ferramentas de servi\u00e7os distribu\u00eddos na Mailgun. Veja como voc\u00ea pode implement\u00e1-lo no seu.<\/p>\n","protected":false},"author":35,"featured_media":4843,"menu_order":0,"template":"","meta":{"_acf_changed":true,"footnotes":""},"blog_category":[23],"class_list":["post-24073","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>A solu\u00e7\u00e3o de cache superior do Golang em compara\u00e7\u00e3o ao Memcached e Redis - Transactional Email API Service For Developers | Mailgun<\/title>\n<meta name=\"description\" content=\"O GroupCache foi uma adi\u00e7\u00e3o fant\u00e1stica ao nosso conjunto de ferramentas de servi\u00e7os distribu\u00eddos na Mailgun. Veja como voc\u00ea pode implement\u00e1-lo no seu.\" \/>\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\/pt\/blog\/it-and-engineering\/golangs-superior-cache-solution-memcached-redis\/\" \/>\n<meta property=\"og:locale\" content=\"pt_BR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"A solu\u00e7\u00e3o de cache superior do Golang em compara\u00e7\u00e3o ao Memcached e Redis - Transactional Email API Service For Developers | Mailgun\" \/>\n<meta property=\"og:description\" content=\"O GroupCache foi uma adi\u00e7\u00e3o fant\u00e1stica ao nosso conjunto de ferramentas de servi\u00e7os distribu\u00eddos na Mailgun. Veja como voc\u00ea pode implement\u00e1-lo no seu.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.mailgun.com\/pt\/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-16T10:55:33+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 minutos\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.mailgun.com\\\/pt\\\/blog\\\/it-and-engineering\\\/golangs-superior-cache-solution-memcached-redis\\\/\",\"url\":\"https:\\\/\\\/www.mailgun.com\\\/pt\\\/blog\\\/it-and-engineering\\\/golangs-superior-cache-solution-memcached-redis\\\/\",\"name\":\"A solu\u00e7\u00e3o de cache superior do Golang em compara\u00e7\u00e3o ao Memcached e Redis - Transactional Email API Service For Developers | Mailgun\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.mailgun.com\\\/pt\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.mailgun.com\\\/pt\\\/blog\\\/it-and-engineering\\\/golangs-superior-cache-solution-memcached-redis\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.mailgun.com\\\/pt\\\/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-16T10:55:33+00:00\",\"description\":\"O GroupCache foi uma adi\u00e7\u00e3o fant\u00e1stica ao nosso conjunto de ferramentas de servi\u00e7os distribu\u00eddos na Mailgun. Veja como voc\u00ea pode implement\u00e1-lo no seu.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.mailgun.com\\\/pt\\\/blog\\\/it-and-engineering\\\/golangs-superior-cache-solution-memcached-redis\\\/#breadcrumb\"},\"inLanguage\":\"pt-BR\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.mailgun.com\\\/pt\\\/blog\\\/it-and-engineering\\\/golangs-superior-cache-solution-memcached-redis\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@id\":\"https:\\\/\\\/www.mailgun.com\\\/pt\\\/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\\\/pt\\\/blog\\\/it-and-engineering\\\/golangs-superior-cache-solution-memcached-redis\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.mailgun.com\\\/pt\\\/inicio\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Blog\",\"item\":\"https:\\\/\\\/www.mailgun.com\\\/pt\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"GroupCache: o cache superior para Golang\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.mailgun.com\\\/pt\\\/#website\",\"url\":\"https:\\\/\\\/www.mailgun.com\\\/pt\\\/\",\"name\":\"Transactional Email API Service For Developers | Mailgun\",\"description\":\"Poderosas APIs de e-mail transacional que permitem a voc\u00ea enviar, receber e rastrear e-mails, criadas com os desenvolvedores em mente. Saiba mais hoje mesmo!\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.mailgun.com\\\/pt\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.mailgun.com\\\/pt\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"pt-BR\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.mailgun.com\\\/pt\\\/#organization\",\"name\":\"Transactional Email API Service For Developers | Mailgun\",\"url\":\"https:\\\/\\\/www.mailgun.com\\\/pt\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@id\":\"https:\\\/\\\/www.mailgun.com\\\/pt\\\/#\\\/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\\\/pt\\\/#\\\/schema\\\/logo\\\/image\\\/\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"A solu\u00e7\u00e3o de cache superior do Golang em compara\u00e7\u00e3o ao Memcached e Redis - Transactional Email API Service For Developers | Mailgun","description":"O GroupCache foi uma adi\u00e7\u00e3o fant\u00e1stica ao nosso conjunto de ferramentas de servi\u00e7os distribu\u00eddos na Mailgun. Veja como voc\u00ea pode implement\u00e1-lo no seu.","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\/pt\/blog\/it-and-engineering\/golangs-superior-cache-solution-memcached-redis\/","og_locale":"pt_BR","og_type":"article","og_title":"A solu\u00e7\u00e3o de cache superior do Golang em compara\u00e7\u00e3o ao Memcached e Redis - Transactional Email API Service For Developers | Mailgun","og_description":"O GroupCache foi uma adi\u00e7\u00e3o fant\u00e1stica ao nosso conjunto de ferramentas de servi\u00e7os distribu\u00eddos na Mailgun. Veja como voc\u00ea pode implement\u00e1-lo no seu.","og_url":"https:\/\/www.mailgun.com\/pt\/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-16T10:55:33+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 minutos"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/www.mailgun.com\/pt\/blog\/it-and-engineering\/golangs-superior-cache-solution-memcached-redis\/","url":"https:\/\/www.mailgun.com\/pt\/blog\/it-and-engineering\/golangs-superior-cache-solution-memcached-redis\/","name":"A solu\u00e7\u00e3o de cache superior do Golang em compara\u00e7\u00e3o ao Memcached e Redis - Transactional Email API Service For Developers | Mailgun","isPartOf":{"@id":"https:\/\/www.mailgun.com\/pt\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.mailgun.com\/pt\/blog\/it-and-engineering\/golangs-superior-cache-solution-memcached-redis\/#primaryimage"},"image":{"@id":"https:\/\/www.mailgun.com\/pt\/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-16T10:55:33+00:00","description":"O GroupCache foi uma adi\u00e7\u00e3o fant\u00e1stica ao nosso conjunto de ferramentas de servi\u00e7os distribu\u00eddos na Mailgun. Veja como voc\u00ea pode implement\u00e1-lo no seu.","breadcrumb":{"@id":"https:\/\/www.mailgun.com\/pt\/blog\/it-and-engineering\/golangs-superior-cache-solution-memcached-redis\/#breadcrumb"},"inLanguage":"pt-BR","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.mailgun.com\/pt\/blog\/it-and-engineering\/golangs-superior-cache-solution-memcached-redis\/"]}]},{"@type":"ImageObject","inLanguage":"pt-BR","@id":"https:\/\/www.mailgun.com\/pt\/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\/pt\/blog\/it-and-engineering\/golangs-superior-cache-solution-memcached-redis\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.mailgun.com\/pt\/inicio\/"},{"@type":"ListItem","position":2,"name":"Blog","item":"https:\/\/www.mailgun.com\/pt\/blog\/"},{"@type":"ListItem","position":3,"name":"GroupCache: o cache superior para Golang"}]},{"@type":"WebSite","@id":"https:\/\/www.mailgun.com\/pt\/#website","url":"https:\/\/www.mailgun.com\/pt\/","name":"Transactional Email API Service For Developers | Mailgun","description":"Poderosas APIs de e-mail transacional que permitem a voc\u00ea enviar, receber e rastrear e-mails, criadas com os desenvolvedores em mente. Saiba mais hoje mesmo!","publisher":{"@id":"https:\/\/www.mailgun.com\/pt\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.mailgun.com\/pt\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"pt-BR"},{"@type":"Organization","@id":"https:\/\/www.mailgun.com\/pt\/#organization","name":"Transactional Email API Service For Developers | Mailgun","url":"https:\/\/www.mailgun.com\/pt\/","logo":{"@type":"ImageObject","inLanguage":"pt-BR","@id":"https:\/\/www.mailgun.com\/pt\/#\/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\/pt\/#\/schema\/logo\/image\/"}}]}},"_links":{"self":[{"href":"https:\/\/www.mailgun.com\/pt\/wp-json\/wp\/v2\/blog\/24073","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.mailgun.com\/pt\/wp-json\/wp\/v2\/blog"}],"about":[{"href":"https:\/\/www.mailgun.com\/pt\/wp-json\/wp\/v2\/types\/blog"}],"author":[{"embeddable":true,"href":"https:\/\/www.mailgun.com\/pt\/wp-json\/wp\/v2\/users\/35"}],"version-history":[{"count":1,"href":"https:\/\/www.mailgun.com\/pt\/wp-json\/wp\/v2\/blog\/24073\/revisions"}],"predecessor-version":[{"id":24075,"href":"https:\/\/www.mailgun.com\/pt\/wp-json\/wp\/v2\/blog\/24073\/revisions\/24075"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.mailgun.com\/pt\/wp-json\/wp\/v2\/media\/4843"}],"wp:attachment":[{"href":"https:\/\/www.mailgun.com\/pt\/wp-json\/wp\/v2\/media?parent=24073"}],"wp:term":[{"taxonomy":"blog_category","embeddable":true,"href":"https:\/\/www.mailgun.com\/pt\/wp-json\/wp\/v2\/blog_category?post=24073"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}