Caching en Go: Redis, Memcached y soluciones integradas: de la A a la Z

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

Caching en Go: Redis, Memcached y soluciones integradas: de la A a la Z

\n\n

El caching es una de las herramientas clave para mejorar el rendimiento de aplicaciones web y microservicios. En Go (Golang) existen múltiples enfoques: desde simples mapas en memoria hasta potentes sistemas distribuidos como Redis y Memcached. En este artículo analizaremos todas las opciones populares de caching en Go con ejemplos de código, compararemos su rendimiento y mostraremos las mejores prácticas de implementación.

\n\n

¿Por qué es necesario el caching en Go?

\n

Sin caché, cada acceso a datos puede implicar operaciones costosas: consultas a bases de datos, llamadas a APIs externas o cálculos complejos. El caching permite guardar el resultado de la primera operación y entregarlo rápidamente en solicitudes posteriores. Esto reduce la carga en el backend, disminuye las latencias y mejora la experiencia del usuario. En Go, gracias a las gorutinas y su alta concurrencia, una implementación correcta del caché es especialmente importante.

\n\n

1. Soluciones integradas: sync.Map y bigcache

\n

Para proyectos pequeños o casos donde no se requiere distribución, Go ofrece mecanismos de caching integrados.

\n\n

1.1 sync.Map

\n

sync.Map es un mapa thread-safe de la biblioteca estándar de Go. Está optimizado para casos donde las claves se escriben una vez y se leen muchas veces. Es ideal para cachés con baja frecuencia de actualización.

\n
package main\n\nimport (\n    "fmt"\n    "sync"\n)\n\nfunc main() {\n    var cache sync.Map\n\n    // Escritura\n    cache.Store("user:1", "Alice")\n    cache.Store("user:2", "Bob")\n\n    // Lectura\n    if value, ok := cache.Load("user:1"); ok {\n        fmt.Println("Encontrado:", value)\n    }\n\n    // Eliminación\n    cache.Delete("user:2")\n\n    // Iteración (Range)\n    cache.Range(func(key, value interface{}) bool {\n        fmt.Printf("Clave: %v, Valor: %v\\n", key, value)\n        return true\n    })\n}
\n

Ventajas: sin dependencias externas, API simple, thread-safe.
\nDesventajas: sin TTL (tiempo de vida), sin límite de tamaño, el rendimiento disminuye con escrituras frecuentes.

\n\n

1.2 BigCache

\n

BigCache es una biblioteca de caching rápida en memoria, diseñada específicamente para Go. Minimiza las asignaciones de memoria y soporta TTL.

\n
package main\n\nimport (\n    "fmt"\n    "time"\n    "github.com/allegro/bigcache/v3"\n)\n\nfunc main() {\n    config := bigcache.Config{\n        Shards:             1024,\n        LifeWindow:         10 * time.Minute,\n        CleanWindow:        5 * time.Minute,\n        MaxEntriesInWindow: 1000,\n        MaxEntrySize:       500,\n        Verbose:            true,\n    }\n\n    cache, err := bigcache.NewBigCache(config)\n    if err != nil {\n        panic(err)\n    }\n\n    // Escritura\n    cache.Set("session:abc123", []byte("user_data"))\n\n    // Lectura\n    data, err := cache.Get("session:abc123")\n    if err == nil {\n        fmt.Println("Datos:", string(data))\n    }\n}
\n

Ventajas: alta velocidad, soporte TTL, baja carga en el GC (Garbage Collector).
\nDesventajas: solo para una instancia de la aplicación, sin replicación.

\n\n

2. Memcached en Go

\n

Memcached es un sistema de caching distribuido en memoria. Es simple pero muy rápido y soporta TTL. En Go, se utiliza el driver github.com/bradfitz/gomemcache/memcache para trabajar con Memcached.

\n
package main\n\nimport (\n    "fmt"\n    "github.com/bradfitz/gomemcache/memcache"\n)\n\nfunc main() {\n    mc := memcache.New("127.0.0.1:11211")\n\n    // Escritura\n    err := mc.Set(&memcache.Item{\n        Key:   "user:42",\n        Value: []byte("John Doe"),\n        Expiration: 300, // 5 minutos\n    })\n    if err != nil {\n        panic(err)\n    }\n\n    // Lectura\n    item, err := mc.Get("user:42")\n    if err == nil {\n        fmt.Println("Valor:", string(item.Value))\n    }\n\n    // Elim                

Blogs

Book Recommendations