NarvikHub Logo

NARVIKHUB

Tools

Redis Caching Strategies

Database

2024-08-28

Redis Caching Strategies: High-Performance In-Memory Data Store

Optimize application performance with Redis caching, data structures, pub/sub messaging, and advanced patterns.

RedisCachingPerformanceNoSQL

Redis is an in-memory data structure store used as a database, cache, and message broker. This guide covers Redis data types, caching strategies, performance patterns, and production deployment best practices.

Redis Data Structures

# Strings - Simple key-value

SET user:1000 "John Doe"

GET user:1000

INCR page_views

EXPIRE session:abc123 3600

# Lists - Ordered collections

LPUSH notifications:user:1000 "New message"

LRANGE notifications:user:1000 0 9

RPOP queue:emails

# Sets - Unique values

SADD tags:post:100 "redis" "caching" "database"

SINTER tags:post:100 tags:post:101

SCARD online_users

# Sorted Sets - Scored unique values

ZADD leaderboard 95 "Alice" 87 "Bob" 92 "Charlie"

ZREVRANGE leaderboard 0 9 WITHSCORES

ZRANK leaderboard "Alice"

# Hashes - Field-value pairs

HSET user:1000 name "John" email "john@example.com" age 30

HGETALL user:1000

HINCRBY user:1000 login_count 1

# Bitmaps - Bit operations

SETBIT user:login:2024-01 1000 1

BITCOUNT user:login:2024-01

# HyperLogLog - Cardinality estimation

PFADD unique_visitors "user123" "user456"

PFCOUNT unique_visitors

Caching Strategies

Cache-Aside (Lazy Loading)

async function getData(key) {

// Check cache first

let data = await redis.get(key);

if (!data) {

// Cache miss - fetch from database

data = await database.fetch(key);

// Store in cache with TTL

await redis.setex(key, 3600,

JSON.stringify(data));

} else {

data = JSON.parse(data);

}

return data;

}

Write-Through Cache

async function saveData(key, value) {

// Write to cache and database

const pipeline = redis.pipeline();

pipeline.setex(key, 3600,

JSON.stringify(value));

await Promise.all([

pipeline.exec(),

database.save(key, value)

]);

return value;

}

Common Patterns

Session Management

// Store session with automatic expiration

async function createSession(userId, sessionData) {

const sessionId = generateSessionId();

const key = `session:${sessionId}`;

await redis.hset(key, {

userId,

...sessionData,

createdAt: Date.now()

});

await redis.expire(key, 3600); // 1 hour TTL

return sessionId;

}

// Extend session on activity

async function touchSession(sessionId) {

const key = `session:${sessionId}`;

await redis.expire(key, 3600);

}

Rate Limiting

// Sliding window rate limiter

async function checkRateLimit(userId, limit = 100) {

const key = `rate_limit:${userId}`;

const now = Date.now();

const windowStart = now - 60000; // 1 minute window

// Remove old entries

await redis.zremrangebyscore(key, 0, windowStart);

// Count requests in window

const count = await redis.zcard(key);

if (count < limit) {

// Add current request

await redis.zadd(key, now, `${now}-${Math.random()}`);

await redis.expire(key, 60);

return { allowed: true, remaining: limit - count - 1 };

}

return { allowed: false, remaining: 0 };

}

Distributed Locking

// Acquire lock with timeout

async function acquireLock(resource, ttl = 5000) {

const lockId = generateId();

const key = `lock:${resource}`;

const acquired = await redis.set(

key, lockId, 'PX', ttl, 'NX'

);

return acquired ? lockId : null;

}

// Release lock safely

async function releaseLock(resource, lockId) {

const key = `lock:${resource}`;

// Lua script for atomic check and delete

const script = `

if redis.call("get", KEYS[1]) == ARGV[1] then

return redis.call("del", KEYS[1])

else

return 0

end`;

return await redis.eval(script, 1, key, lockId);

}

Pub/Sub Messaging

// Publisher

const publisher = redis.duplicate();

async function publishEvent(channel, data) {

await publisher.publish(channel, JSON.stringify(data));

}

// Subscriber

const subscriber = redis.duplicate();

subscriber.on('message', (channel, message) => {

const data = JSON.parse(message);

console.log(`Received on ${channel}:`, data);

// Process message based on channel

switch(channel) {

case 'orders:new':

processNewOrder(data);

break;

case 'users:updated':

invalidateUserCache(data.userId);

break;

}

});

// Subscribe to channels

subscriber.subscribe('orders:new', 'users:updated');

Performance Optimization

Pipeline Commands

Batch multiple commands together to reduce network round trips and improve throughput.

Memory Optimization

Use appropriate data structures, enable compression, and set proper eviction policies (LRU, LFU).

Persistence Strategy

Choose between RDB snapshots for backups and AOF for durability based on your needs.

Connection Pooling

Reuse connections with proper pool configuration to avoid connection overhead.

Published on 2024-08-28 • Category: Database

← Back to Blog

NarvikHub

Free online developer tools and utilities for encoding, formatting, generating, and analyzing data. No registration required - all tools work directly in your browser.

Built for developers, by developers. Privacy-focused and open source.

Popular Tools

Base64 Encoder/DecoderJSON FormatterURL Encoder/DecoderHTML FormatterHash GeneratorUUID Generator

Blog Articles

Base64 Encoding GuideURL Encoding Deep DiveUnderstanding JWT TokensRegular Expressions GuideView All Articles →

Developer Tools & Utilities

Base64 Encoder/DecoderJSON FormatterURL Encoder/DecoderHTML FormatterHash GeneratorUUID GeneratorQR Code GeneratorJWT DecoderTimestamp ConverterRegex TesterText Diff CheckerHex ConverterImage Base64 ConverterASN.1 DecoderCharles Keygen

Free online tools for Base64 encoding, JSON formatting, URL encoding, hash generation, UUID creation, QR codes, JWT decoding, timestamp conversion, regex testing, and more.

Privacy PolicyTerms of ServiceContact

© 2024 NarvikHub. All rights reserved.