Caché en C++: Redis, Memcached y soluciones integradas

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Introducción: ¿Por qué es necesario el almacenamiento en caché en C++?



En el desarrollo moderno con C++, la velocidad de la aplicación suele ser un factor crítico. El almacenamiento en caché permite reducir significativamente el tiempo de acceso a los datos, disminuir la carga en las bases de datos y acelerar la ejecución de operaciones computacionales repetitivas. En este artículo, analizaremos en detalle tres enfoques principales para el almacenamiento en caché en C++: el uso de sistemas externos (Redis y Memcached) y soluciones integradas disponibles "de fábrica".



Independientemente de si estás desarrollando un servidor web de alta carga, un motor de juegos o un sistema financiero, la elección correcta de una estrategia de almacenamiento en caché puede aumentar el rendimiento decenas de veces. Analizaremos los pros y los contras de cada enfoque, y también proporcionaremos ejemplos de código listos para una integración rápida.



1. Soluciones integradas para almacenamiento en caché en C++



Antes de conectar servicios externos, vale la pena considerar las capacidades que ofrece el propio lenguaje C++ y su biblioteca estándar. Las soluciones integradas son ideales para aplicaciones de un solo hilo o para casos en los que los datos no necesitan compartirse entre varios procesos.



1.1. Caché LRU simple basado en std::unordered_map



El algoritmo LRU (Least Recently Used) es uno de los más populares para el almacenamiento en caché integrado. Elimina automáticamente los elementos menos utilizados cuando la caché alcanza el límite de memoria.



#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; // Movemos la clave al inicio de la lista items_.splice(items_.begin(), items_, it->second.second); return it->second.first; }};


Ventajas: gastos generales mínimos, sin latencia de red, control total sobre los datos.

Desventajas: los datos no se comparten entre hilos (se requiere sincronización manual), limitados por la memoria de un solo proceso.



1.2. Uso de std::shared_mutex para subprocesamiento múltiple



Para aplicaciones de subprocesamiento múltiple, se puede mejorar el rendimiento utilizando shared_mutex, que permite la lectura simultánea por parte de varios hilos:



#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. Almacenamiento en caché con Memcached en C++



Memcached es un sistema de almacenamiento en caché distribuido en memoria RAM, ideal para almacenar pequeños fragmentos

Blogs

Book Recommendations