Cache em C++: Redis, Memcached e soluções embutidas

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
```html

Introdução: Por que usar cache em C++?

No desenvolvimento moderno em C++, a velocidade da aplicação é frequentemente um fator crítico. O cache permite reduzir significativamente o tempo de acesso aos dados, diminuir a carga nos bancos de dados e acelerar a execução de operações computacionais repetitivas. Neste artigo, vamos explorar detalhadamente três abordagens principais para cache em C++: uso de sistemas externos (Redis e Memcached) e soluções integradas disponíveis "prontas para uso".

Independentemente de você estar desenvolvendo um servidor web de alta carga, um motor de jogos ou um sistema financeiro, a escolha correta da estratégia de cache pode aumentar o desempenho dezenas de vezes. Analisaremos os prós e contras de cada abordagem, além de fornecer exemplos de código prontos para integração rápida.

1. Soluções integradas para cache em C++

Antes de conectar serviços externos, vale a pena considerar as capacidades que a própria linguagem C++ e sua biblioteca padrão oferecem. As soluções integradas são ideais para aplicações single-thread ou para casos em que os dados não precisam ser compartilhados entre vários processos.

1.1. Cache LRU simples baseado em std::unordered_map

O algoritmo LRU (Least Recently Used) é um dos mais populares para cache integrado. Ele remove automaticamente os elementos menos usados quando o cache atinge o limite de memória.

#include <unordered_map>
#include <list>
#include <mutex>

template <typename Key, typename Value>
class LRUCache {
private:
    size_t capacity_;
    std::list<Key> items_;
    std::unordered_map<Key, std::pair<Value, typename std::list<Key>::iterator>> cache_;
    std::mutex mutex_;

public:
    LRUCache(size_t capacity) : capacity_(capacity) {}

    void put(const Key& key, const Value& value) {
        std::lock_guard<std::mutex> lock(mutex_);
        auto it = cache_.find(key);
        if (it != cache_.end()) {
            items_.erase(it->second.second);
            cache_.erase(it);
        }
        items_.push_front(key);
        cache_[key] = {value, items_.begin()};
        
        if (cache_.size() > capacity_) {
            auto last = items_.back();
            items_.pop_back();
            cache_.erase(last);
        }
    }

    std::optional<Value> get(const Key& key) {
        std::lock_guard<std::mutex> lock(mutex_);
        auto it = cache_.find(key);
        if (it == cache_.end()) return std::nullopt;
        
        // Move a chave para o início da lista
        items_.splice(items_.begin(), items_, it->second.second);
        return it->second.first;
    }
};

Vantagens: sobrecarga mínima, sem latência de rede, controle total sobre os dados.

Desvantagens: os dados não são compartilhados entre threads (requer sincronização manual), limitados pela memória de um único processo.

1.2. Uso de std::shared_mutex para multithreading

Para aplicações multithread, é possível melhorar o desempenho usando shared_mutex, que permite leitura simultânea por várias threads:

#include <shared_mutex>

class ThreadSafeCache {
    std::map<std::string, std::string> data_;
    mutable std::shared_mutex mutex_;
    
public:
    std::string read(const std::string& key) {
        std::shared_lock lock(mutex_);
        auto it = data_.find(key);
        return (it != data_.end()) ? it->second : "";
    }
    
    void write(const std::string& key, const std::string& value) {
        std::unique_lock lock(mutex_);
        data_[key] = value;
    }
};

2. Cache com Memcached em C++

Memcached é um sistema de cache distribuído em memória RAM, ideal para armazenar pequenos fragmentos

```

Blogs

Book Recommendations