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
Memuat komentar...
Tulis Komentar