__
🚀 How to Integrate Redis Caching in Golang
In this post, I'll walk you through how to set up and use Redis caching in a Golang project. This setup helps in reducing database queries and improving performance by caching frequently requested data.
🔹 Why Use Redis for Caching?
✅ Reduces database load
✅ Improves response time
✅ Easy key-value storage
✅ Supports expiration & invalidation
📌 Step 1: Install Redis Package
We use the go-redis/v9 package to interact with Redis. Install it using:
go get github.com/redis/go-redis/v9
📌 Step 2: Initialize Redis Client
Create a file utils/redis.go
and add the following:
package utils
import (
"context"
"crypto/tls"
"log"
"github.com/redis/go-redis/v9"
)
var (
RedisClient *redis.Client
Ctx = context.Background()
)
// Initialize Redis Connection
func InitRedis() {
RedisClient = redis.NewClient(&redis.Options{
Addr: "127.0.0.1:6379", // Replace with Redis host
Password: "", // Replace with Redis password
DB: 0,
_, err := RedisClient.Ping(Ctx).Result()
if err != nil {
log.Fatalf("❌ Failed to connect to Redis: %v", err)
}
log.Println("✅ Redis connection established")
}
🔹 If using a local Redis instance, set Addr: "127.0.0.1:6379"
and remove TLSConfig
.
🔹 For cloud Redis providers (like Aiven, AWS, etc.), use the TLS setup.
📌 Step 3: Implement Caching Functions
Add the following caching functions to manage data in Redis:
package utils
import (
"encoding/json"
"errors"
"log"
"time"
)
// CacheGet: Fetch data from Redis
func CacheGet(key string, result interface{}) (bool, error) {
log.Printf("🔍 Checking cache for key: %s", key)
val, err := RedisClient.Get(Ctx, key).Result()
if err == redis.Nil {
return false, errors.New("key does not exist") // Cache miss
} else if err != nil {
return false, errors.New("internal server error")
}
// Unmarshal JSON into result
err = json.Unmarshal([]byte(val), result)
if err != nil {
return false, err
}
log.Printf("✅ Cache hit for key: %s", key)
return true, nil
}
// CacheSet: Store data in Redis
func CacheSet(key string, value interface{}, expiration time.Duration) error {
jsonData, err := json.Marshal(value)
if err != nil {
return err
}
return RedisClient.Set(Ctx, key, jsonData, expiration).Err()
}
// InvalidateCache: Delete a cached key (for updates)
func InvalidateCache(key string) error {
err := RedisClient.Del(Ctx, key).Err()
if err != nil {
log.Printf("❌ Error invalidating cache for key: %s", key)
return err
}
log.Printf("🗑️ Cache invalidated for key: %s", key)
return nil
}
🔹 CacheGet()
→ Checks if the key exists, retrieves & unmarshals data.
🔹 CacheSet()
→ Stores JSON-encoded data with an expiration time.
🔹 InvalidateCache()
→ Deletes a cache entry (useful when data updates).
📌 Step 4: Use Redis Cache in Database Queries
Modify your database query functions to first check Redis before querying the database:
package services
import (
"errors"
"log"
"time"
"your_project/utils" // Import utils package
)
var cacheExpiration = 10 * time.Minute // Set cache expiration time
type Category struct {
ID int `json:"id"`
Name string `json:"name"`
}
func GetAllCategories() ([]Category, error) {
var categories []Category
cacheKey := "categories_cache"
// 1️⃣ Check Redis cache first
cached, err := utils.CacheGet(cacheKey, &categories)
if err != nil {
log.Printf("Redis CacheGet error: %v", err)
}
if cached {
log.Println("✅ Categories fetched from Redis cache")
return categories, nil
}
// 2️⃣ Cache miss → Fetch data from DB
log.Println("⚠️ Cache miss: Fetching categories from DB")
query := `SELECT id, name FROM categories`
rows, err := utils.DB.Query(query)
if err != nil {
return nil, errors.New("database error")
}
defer rows.Close()
for rows.Next() {
var category Category
if err := rows.Scan(&category.ID, &category.Name); err != nil {
return nil, errors.New("data scan error")
}
categories = append(categories, category)
}
// 3️⃣ Store fetched data in Redis
if err := utils.CacheSet(cacheKey, categories, cacheExpiration); err != nil {
log.Printf("Redis CacheSet error: %v", err)
}
log.Println("✅ Categories cached in Redis")
return categories, nil
}
🔹 First, check Redis cache using CacheGet()
.
🔹 If cache miss, query the database.
🔹 Store result in Redis for future use with CacheSet()
.
📌 Step 5: Invalidate Cache When Data Changes
Whenever new categories are added, remove the outdated cache:
err := utils.InvalidateCache("categories_cache")
if err != nil {
log.Printf("Error invalidating cache: %v", err)
}
🔹 Use this after adding/updating/deleting data to keep cache fresh.
If you want to test Redis caching locally on Windows, follow these steps:
✅ Step 1: Install & Run Redis Locally
-
Download Redis for Windows:
- (Redis is not natively supported on Windows)
- Install and run the Redis server.
Start Redis Server:
If you installed Redis using WSL or a Redis-compatible version, start it using:
redis-server
- Check if Redis is Running: Open Command Prompt (cmd) and run:
redis-cli ping
If Redis is running, it should return:
PONG
✅ Step 2: Set & Get Keys in Redis (Local Testing)
To manually check your cache for the key categories_cache
, use the following commands in Command Prompt:
- Open Redis CLI:
redis-cli
-
Check if
categories_cache
exists:
EXISTS categories_cache
If it returns 1
, the key exists. If 0
, it's missing.
- Get Cached Data:
GET categories_cache
This should return the cached JSON data.
Top comments (0)