Caché en Go: 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

Almacenamiento en caché en Go: Redis, Memcached y soluciones integradas



El almacenamiento en caché es una de las herramientas clave para mejorar el rendimiento de aplicaciones web y microservicios. En Go (Golang) existen varios enfoques: desde estructuras de datos integradas simples hasta potentes sistemas distribuidos como Redis y Memcached. En este artículo analizaremos las principales opciones de almacenamiento en caché, sus ventajas, desventajas y proporcionaremos ejemplos prácticos de código.



¿Por qué es necesario el almacenamiento en caché en Go?

Go es conocido por su velocidad y eficiencia, pero incluso en él suelen encontrarse cuellos de botella: consultas lentas a la base de datos, APIs externas o cálculos pesados. El almacenamiento en caché permite:

  • Reducir la carga en la base de datos y servicios externos.
  • Disminuir el tiempo de respuesta de la API (latencia).
  • Ahorrar recursos del servidor (CPU, memoria).
  • Aumentar la tolerancia a fallos durante interrupciones temporales.

La elección de la solución específica depende de la arquitectura de la aplicación: monolito o microservicios, requisitos de consistencia de datos, volumen de caché y presupuesto.



Almacenamiento en caché integrado en Go

Para escenarios simples (por ejemplo, almacenar datos en caché dentro de un solo proceso), son adecuadas las herramientas integradas de Go. No requieren instalación de servicios externos y son ideales para aplicaciones pequeñas.



1. sync.Map

sync.Map es un map thread-safe de la biblioteca estándar de Go. Es adecuado para almacenamiento en caché que se actualiza raramente y se lee con frecuencia. Ejemplo:

package main

import ( "fmt" "sync")

func main() { var cache sync.Map

// Guardamos datos cache.Store("user_1", "Alice") cache.Store("user_2", "Bob")

// Leemos datos if val, ok := cache.Load("user_1"); ok { fmt.Println("Found:", val) }

// Eliminamos cache.Delete("user_2")}

Ventajas: simplicidad, sin dependencias externas, thread-safe. Desventajas: no tiene TTL (tiempo de vida), no tiene limpieza automática, limitado a un solo proceso.



2. Paquete go-cache

La popular biblioteca github.com/patrickmn/go-cache añade soporte para TTL y limpieza automática. Ejemplo:

package main

import ( "fmt" "time" "github.com/patrickmn/go-cache")

func main() { // Creamos un caché con tiempo de vida de 5 minutos y limpieza cada 10 minutos c := cache.New(5*time.Minute, 10*time.Minute)

// Guardamos con TTL c.Set("session_token", "abc123", cache.DefaultExpiration)

// Obtenemos token, found := c.Get("session_token") if found { fmt.Println("Token:", token) }

// Eliminamos c.Delete("session_token")}

Ventajas: TTL, simplicidad de integración, limpieza automática. Desventajas: los datos se almacenan en la memoria de un solo proceso, no es adecuado para sistemas distribuidos.



Redis: almacenamiento en caché distribuido para Go

Redis es la solución más popular para almacenamiento en caché en Go. Funciona como un servidor independiente, soporta estructuras de datos complejas (strings, hashes, listas, conjuntos) y tiene un excelente soporte en Go a través del driver go-redis.



Conexión y operaciones básicas

package main

import ( "context" "fmt" "github.com/redis/go-redis/v9")

func main() { ctx := context.Background()

// Conexión a Redis rdb := redis.NewClient(&redis.Options{ Addr: "localhost:6379", Password: "", // sin contraseña DB: 0, })

// Guardamos un string con TTL (1 hora) err := rdb.Set(ctx, "key", "value", 3600*time.Second).Err() if err != nil { panic(err) }

// Leemos val, err := rdb.Get(ctx, "key").Result() if err != nil { fmt.Println("Key not found") } else { fmt.Println("Value:", val) }

// Eliminamos rdb.Del(ctx, "key")}

Blogs

Book Recommendations