Redis Cache untuk Meningkatkan Performa Aplikasi


Redis adalah in-memory data store yang sangat cepat dan sering digunakan sebagai cache, message broker, dan session storage. Dengan Redis, kamu bisa meningkatkan performa aplikasi secara signifikan.

Apa Itu Redis?

Redis (Remote Dictionary Server) adalah database NoSQL yang menyimpan data di memory (RAM), sehingga operasi baca/tulis sangat cepat. Redis mendukung berbagai struktur data seperti strings, hashes, lists, sets, dan sorted sets.

Kapan Menggunakan Redis?

  • Caching: Menyimpan hasil query database yang sering diakses
  • Session Storage: Menyimpan session user
  • Rate Limiting: Membatasi request per user
  • Real-time Analytics: Leaderboard, counter
  • Message Queue: Pub/Sub messaging

Instalasi Redis

Windows (WSL atau Docker)

# Menggunakan Docker
docker run -d --name redis -p 6379:6379 redis:alpine

macOS

brew install redis
brew services start redis

Linux (Ubuntu/Debian)

sudo apt update
sudo apt install redis-server
sudo systemctl start redis-server
sudo systemctl enable redis-server

Verifikasi Instalasi

redis-cli ping
# Output: PONG

Perintah Dasar Redis

Strings

# Set value
SET nama "Baris Kode"

# Get value
GET nama

# Set dengan expiration (dalam detik)
SETEX token 3600 "abc123"

# Set jika belum ada
SETNX key "value"

# Increment/Decrement
SET counter 10
INCR counter    # 11
DECR counter    # 10
INCRBY counter 5  # 15

Hashes

# Set hash field
HSET user:1 name "John" email "john@example.com" age 25

# Get single field
HGET user:1 name

# Get all fields
HGETALL user:1

# Check field exists
HEXISTS user:1 email

# Delete field
HDEL user:1 age

Lists

# Push ke list
LPUSH notifications "Pesan baru"
RPUSH notifications "Notifikasi lain"

# Get range
LRANGE notifications 0 -1

# Pop dari list
LPOP notifications
RPOP notifications

# Get length
LLEN notifications

Sets

# Add members
SADD tags "javascript" "nodejs" "redis"

# Get all members
SMEMBERS tags

# Check membership
SISMEMBER tags "redis"

# Remove member
SREM tags "nodejs"

# Set operations
SADD tags2 "python" "redis"
SINTER tags tags2    # Intersection
SUNION tags tags2    # Union

Sorted Sets

# Add dengan score
ZADD leaderboard 100 "player1" 85 "player2" 92 "player3"

# Get by rank (ascending)
ZRANGE leaderboard 0 -1 WITHSCORES

# Get by rank (descending)
ZREVRANGE leaderboard 0 2 WITHSCORES

# Get rank of member
ZRANK leaderboard "player1"

# Increment score
ZINCRBY leaderboard 10 "player2"

Key Management

# List keys
KEYS *
KEYS user:*

# Check key exists
EXISTS nama

# Delete key
DEL nama

# Set expiration
EXPIRE nama 3600

# Check TTL
TTL nama

# Remove expiration
PERSIST nama

Implementasi Caching

Pattern: Cache-Aside

// Node.js dengan ioredis
const Redis = require('ioredis');
const redis = new Redis();

async function getUser(userId) {
  const cacheKey = `user:${userId}`;

  // 1. Cek cache dulu
  const cached = await redis.get(cacheKey);
  if (cached) {
    console.log('Cache HIT');
    return JSON.parse(cached);
  }

  // 2. Jika tidak ada, query database
  console.log('Cache MISS');
  const user = await db.query('SELECT * FROM users WHERE id = ?', [userId]);

  // 3. Simpan ke cache (expire 1 jam)
  await redis.setex(cacheKey, 3600, JSON.stringify(user));

  return user;
}

// Invalidate cache saat update
async function updateUser(userId, data) {
  await db.query('UPDATE users SET ? WHERE id = ?', [data, userId]);
  await redis.del(`user:${userId}`);
}

Pattern: Write-Through

async function createOrder(orderData) {
  // 1. Simpan ke database
  const order = await db.query('INSERT INTO orders SET ?', orderData);

  // 2. Langsung simpan ke cache
  await redis.setex(`order:${order.id}`, 3600, JSON.stringify(order));

  return order;
}

Use Case: Rate Limiting

async function rateLimiter(userId, limit = 10, window = 60) {
  const key = `ratelimit:${userId}`;

  const current = await redis.incr(key);

  if (current === 1) {
    await redis.expire(key, window);
  }

  if (current > limit) {
    const ttl = await redis.ttl(key);
    throw new Error(`Rate limit exceeded. Try again in ${ttl} seconds`);
  }

  return { remaining: limit - current };
}

Use Case: Session Storage

const session = require('express-session');
const RedisStore = require('connect-redis').default;

app.use(
  session({
    store: new RedisStore({ client: redis }),
    secret: 'your-secret-key',
    resave: false,
    saveUninitialized: false,
    cookie: {
      secure: process.env.NODE_ENV === 'production',
      maxAge: 24 * 60 * 60 * 1000, // 24 jam
    },
  })
);

Use Case: Real-time Leaderboard

// Tambah/update score
async function updateScore(playerId, score) {
  await redis.zadd('game:leaderboard', score, playerId);
}

// Get top 10
async function getTopPlayers() {
  return await redis.zrevrange('game:leaderboard', 0, 9, 'WITHSCORES');
}

// Get player rank
async function getPlayerRank(playerId) {
  const rank = await redis.zrevrank('game:leaderboard', playerId);
  const score = await redis.zscore('game:leaderboard', playerId);
  return { rank: rank + 1, score };
}

Pub/Sub Messaging

// Publisher
const publisher = new Redis();

async function publishNotification(channel, message) {
  await publisher.publish(channel, JSON.stringify(message));
}

// Subscriber
const subscriber = new Redis();

subscriber.subscribe('notifications', (err, count) => {
  console.log(`Subscribed to ${count} channels`);
});

subscriber.on('message', (channel, message) => {
  console.log(`Received from ${channel}:`, JSON.parse(message));
});

Best Practices

1. Gunakan Naming Convention yang Konsisten

# Format: object-type:id:field
user:1234:profile
order:5678:items
session:abc123

2. Set Expiration untuk Cache

// Selalu set TTL untuk cache
await redis.setex(key, 3600, value); // 1 jam

3. Gunakan Pipeline untuk Multiple Commands

const pipeline = redis.pipeline();
pipeline.set('key1', 'value1');
pipeline.set('key2', 'value2');
pipeline.get('key1');
await pipeline.exec();

4. Monitor Memory Usage

redis-cli INFO memory

5. Konfigurasi Maxmemory Policy

# Di redis.conf
maxmemory 256mb
maxmemory-policy allkeys-lru

Kesimpulan

Redis adalah tool yang sangat powerful untuk:

  • Meningkatkan performa dengan caching
  • Menyimpan session dengan cepat
  • Implementasi rate limiting
  • Real-time features seperti leaderboard

Mulai dengan use case sederhana seperti caching, lalu eksplorasi fitur lainnya sesuai kebutuhan.


Referensi:

Komentar

Real-time

Memuat komentar...

Tulis Komentar

Email tidak akan ditampilkan

0/2000 karakter

Catatan: Komentar akan dimoderasi sebelum ditampilkan. Mohon bersikap sopan dan konstruktif.