Redis: Pub/Sub dan Real-time Features
Messaging real-time, streams, dan use cases advanced
Tujuan Pembelajaran
- Bisa menggunakan Redis Pub/Sub
- Mengerti Redis Streams
- Bisa implementasi real-time features
Analogi
Pub/Sub Flow:
Publisher → Redis Channel → [Subscriber 1, Subscriber 2, ...]
Streams Flow:
Producer → Redis Stream → Consumer Group → [Consumer 1, Consumer 2]
Pub/Sub untuk broadcast, Streams untuk persistent event log
Penjelasan Konsep
Selain caching, Redis punya fitur real-time yang powerful: Pub/Sub dan Streams.
Kedua fitur ini memungkinkan komunikasi real-time antar bagian aplikasi.
Pub/Sub: Publish dan Subscribe
Pub/Sub adalah pattern messaging di mana publisher mengirim pesan ke channel, dan subscriber yang subscribe ke channel tersebut menerima pesan.
Publisher: PUBLISH notifications:user:100 "Pesan baru!"
Subscriber (sebelumnya): SUBSCRIBE notifications:user:100
→ Menerima: "Pesan baru!"
Karakteristik Pub/Sub Redis:
- Fire and forget: Pesan tidak disimpan,
Kalau tidak ada subscriber pesan hilang
- One-to-many: Satu pesan bisa diterima banyak subscriber
- No persistence: Pesan hanya ada di memory
- Decoupled: Publisher tidak tahu siapa subscriber
Use cases:
- Chat application (broadcast message ke room)
- Real-time notifications
- Live updates (score, status)
- Cache invalidation broadcast
Redis Streams: Persistent Event Log
Streams adalah data structure yang lebih advanced daripada Pub/Sub.
Mirip seperti Apache Kafka tapi lebih sederhana:
- Persistent: Pesan disimpan (tidak hilang seperti Pub/Sub)
- Ordered: Pesan punya ID dan urutan
- Consumer groups: Multiple consumers bisa membagi workload
- Acknowledgment: Pesan harus di-ack setelah diproses
# Producer
XADD orders_stream * order_id 100 status pending
# Consumer (single)
XREAD BLOCK 5000 STREAMS orders_stream $ # Block 5 detik
# Consumer Group
XGROUP CREATE orders_stream processing_group $ MKSTREAM
XREADGROUP GROUP processing_group consumer_1 STREAMS orders_stream >
XACK orders_stream processing_group 1698765432100-0
Pub/Sub di Aplikasi
import { createClient } from 'redis';
const pub = createClient({ url: 'redis://localhost:6379' });
const sub = createClient({ url: 'redis://localhost:6379' });
await pub.connect();
await sub.connect();
// Subscribe
await sub.subscribe('notifications',
(message) => {
const data = JSON.parse(message);
console.log('Notifikasi:', data);
// Kirim ke WebSocket client
});
// Publish
await pub.publish('notifications', JSON.stringify({
type: 'new_message',
userId: 100,
content: 'Halo!'
}));
Membangun Chat dengan Redis Pub/Sub + WebSocket
Kombinasi Redis Pub/Sub dengan WebSocket memungkinkan chat multi-server.
Setiap server subscribe ke channel, dan broadcast ke semua WebSocket client yang terhubung.
Contoh Kode
// Real-time notification system
import { createClient } from 'redis';
const redis = {
pub: createClient({ url: 'redis://localhost:6379' }),
sub: createClient({ url: 'redis://localhost:6379' }),
};
await redis.pub.connect();
await redis.sub.connect();
// Notification service
class NotificationService {
async send(userId: number, notification: { type: string; message: string }) {
const channel = `notifications:user:${userId}`;
const payload = JSON.stringify({
...notification,
timestamp: new Date().toISOString(),
});
// Publish ke channel
await redis.pub.publish(channel, payload);
// Simpan ke inbox (untuk user yang offline)
await redis.lpush(`inbox:user:${userId}`, payload);
await redis.ltrim(`inbox:user:${userId}`, 0, 99); // Keep last 100
}
async subscribe(userId: number, onMessage: (msg: any) => void) {
const channel = `notifications:user:${userId}`;
await redis.sub.subscribe(channel, (message) => {
onMessage(JSON.parse(message));
});
// Kirim unread messages dari inbox
const inbox = await redis.lrange(`inbox:user:${userId}`, 0, -1);
inbox.reverse().forEach(msg => onMessage(JSON.parse(msg)));
await redis.del(`inbox:user:${userId}`); // Clear inbox setelah deliver
}
async unsubscribe(userId: number) {
await redis.sub.unsubscribe(`notifications:user:${userId}`);
}
}
// Usage with WebSocket
const notifService = new NotificationService();
// Saat user connect via WebSocket
ws.on('open', () => {
notifService.subscribe(userId, (notification) => {
ws.send(JSON.stringify(notification));
});
});Penjelasan Kode
Prompt AI
Bangun sistem chat sederhana dengan Redis Pub/Sub. Gunakan channel per room. Support join/leave room.
Pertanyaan Reflektif
Bandingkan Redis Streams dengan message queue seperti RabbitMQ atau Apache Kafka. Kapan pakai masing-masing?