Introdução: por que o cache é necessário em C++ e como ele acelera aplicações
\n\nNo desenvolvimento moderno em C++, o desempenho é um fator crítico. Cada consulta extra ao banco de dados, cada recálculo de uma função complexa ou leitura do disco é uma perda de milissegundos que, na escala de um serviço de alta carga, se transformam em segundos de inatividade. O cache resolve esse problema, armazenando os resultados de operações caras em memória de acesso rápido.
\n\nNeste artigo, abordaremos três principais abordagens para cache em C++: sistemas externos (Redis, Memcached) e soluções embutidas (std::unordered_map, LRU-cache). Você aprenderá quando escolher cada ferramenta, como configurar o cache corretamente e quais armadilhas esperam por você.
\n\n1. Sistemas de cache externos: Redis e Memcached
\n\n1.1 Redis: poderoso armazenamento in-memory com suporte a estruturas de dados
\n\nRedis não é apenas um cache, mas um servidor completo de estruturas de dados que opera na memória RAM. Ele suporta strings, listas, conjuntos, tabelas hash e até filas. Para C++, existem várias bibliotecas cliente, sendo as mais populares hiredis (em C) e redis-plus-plus (em C++).
Exemplo de conexão e uso do Redis via redis-plus-plus:
#include <sw/redis++/redis++.h>\n#include <iostream>\n\nint main() {\n // Conectando ao Redis no host local\n sw::redis::Redis redis("tcp://127.0.0.1:6379");\n\n // Gravando um valor no cache\n redis.set("user:1001", "{\\"name\\":\\"Alice\\",\\"age\\":30}");\n\n // Lendo o valor\n auto val = redis.get("user:1001");\n if (val) {\n std::cout << "Dados em cache: " << *val << std::endl;\n }\n\n // Definindo TTL (tempo de vida) — 60 segundos\n redis.expire("user:1001", 60);\n\n return 0;\n}\n\n\nVantagens do Redis:
\n- \n
- Suporte a estruturas de dados complexas (listas, hashes, conjuntos) \n
- Mecanismos embutidos de replicação e persistência \n
- Suporte a transações e scripts Lua \n
- Possibilidade de uso como broker de mensagens pub/sub \n
Desvantagens do Redis:
\n- \n
- Requer um servidor separado (infraestrutura adicional) \n
- Consome mais memória que o Memcached devido aos metadados das estruturas \n
- Não é adequado para volumes muito grandes de dados (limitação de RAM) \n
1.2 Memcached: cache distribuído leve e rápido
\n\nMemcached é um sistema mais simples, projetado exclusivamente para cache de pares chave-valor. É ideal para armazenar objetos pequenos (até 1 MB). Para C++, utiliza-se a biblioteca libmemcached.
Exemplo de trabalho com Memcached em C++:
\n\n#include <libmemcached/memcached.h>\n#include <iostream>\n#include <cstring>\n\nint main() {\n memcached_server_st *servers;\n memcached_st *memc;\n memcached_return rc;\n\n memc = memcached_create(nullptr);\n servers = memcached_server_list_append(nullptr, "127.0.0.1", 11211, &rc);\n rc = memcached_server_push(memc, servers);\n\n // Gravando no cache com TTL de 300 segundos\n const char *key = "session_token_abc123";\n const char *value = "valid";\n rc = memcached_set(memc, key, strlen(key), value, strlen(value), 300, 0);\n\n // Lendo do cache\n size_t value_length;\n uint32_t flags;\n char *result = memcached_get(memc, key, strlen(key), &value_length, &flags, &rc);\n if (result) {\n std::cout << "Valor em cache: " << result << std::endl;\n free(result);\n }\n\n memcached_free(memc);\n return 0;\n}\n\n\nVantagens do Memcached:
\n- \n
- Máximo desempenho em operações simples get/set \n
- Consumo mínimo de memória para metadados \n <