Cache em C++: Redis, Memcached e soluções embutidas — nível avançado

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Introdução: por que o cache é crítico para o desempenho em C++

No desenvolvimento moderno de alta carga em C++, o cache deixou de ser uma opção — é um elemento obrigatório da arquitetura. Sem ele, qualquer sistema CRUD ou microsserviço rapidamente encontra os limites do banco de dados, e a latência das requisições cresce exponencialmente. Em nível avançado, enfrentamos o dilema: usar sistemas externos (Redis, Memcached) ou implementar nossa própria solução in-memory em C++? Neste artigo, analisaremos os prós, contras e implementações específicas de cada abordagem, com base na prática de trabalhar com filas de rede, bloqueios e serialização.



1. Redis: flexibilidade e estruturas de dados

Redis não é apenas um key-value store. Sua principal vantagem é o rico conjunto de tipos de dados: strings, hashes, listas, conjuntos, sorted sets. Para C++, existem vários clientes: redis-plus-plus (recomendado) e hiredis (baixo nível).

Exemplo de conexão e operações básicas com redis-plus-plus

#include <sw/redis++/redis++.h>#include <iostream>

int main() { // Conexão ao Redis (padrão localhost:6379) sw::redis::Redis redis("tcp://127.0.0.1:6379");

// Definir valor com TTL de 60 segundos redis.set("user:1001", "John Doe", std::chrono::seconds(60));

// Leitura auto val = redis.get("user:1001"); if (val) { std::cout << "User: " << *val << std::endl; }

// Trabalhando com hashes redis.hset("session:abc", "token", "xyz123"); redis.hset("session:abc", "expires", "3600"); auto token = redis.hget("session:abc", "token"); std::cout << "Token: " << *token << std::endl;

return 0;}

Recursos avançados: uso de transações via redis.multi() e redis.exec(), além de Pub/Sub para notificações de invalidação de cache. Redis é ideal quando é necessário armazenar estruturas complexas com operações atômicas (por exemplo, incremento de contador).



2. Memcached: velocidade e simplicidade

Memcached é um cache distribuído leve, otimizado para armazenar dados planos (strings e blobs binários). Ele não suporta transações ou estruturas complexas, mas ganha em velocidade e consumo mínimo de memória. Para C++, usamos a biblioteca libmemcached.

Exemplo de trabalho com Memcached via libmemcached

#include <libmemcached/memcached.h>#include <iostream>#include <cstring>

int main() { memcached_st *memc = memcached_create(nullptr); memcached_server_st *servers = nullptr; memcached_return_t rc;

// Adicionar servidor servers = memcached_server_list_append(servers, "127.0.0.1", 11211, &rc); rc = memcached_server_push(memc, servers); if (rc != MEMCACHED_SUCCESS) { std::cerr << "Error: " << memcached_strerror(memc, rc) << std::endl; return 1; }

// Escrita com TTL de 30 segundos const char *key = "config:db_host"; const char *value = "10.0.0.1"; rc = memcached_set(memc, key, strlen(key), value, strlen(value), std::time(0) + 30, (uint32_t)0); if (rc != MEMCACHED_SUCCESS) { std::cerr << "Set failed: " << memcached_strerror(memc, rc) << std::endl; }

// Leitura size_t val_len; uint32_t flags; char *retrieved = memcached_get(memc, key, strlen(key), &val_len, &flags, &rc); if (rc == MEMCACHED_SUCCESS) { std::cout << "DB Host: " << retrieved << std::endl; free(retrieved); }

memcached_free(memc); return 0;}

Quando escolher Memcached? Se você precisa de um cache simples para objetos serializados, sem a necessidade de armazenar estruturas complexas. Memcached é ideal para cachear resultados de consultas SQL ou fragmentos HTML.

Blogs

Book Recommendations