עם 10,000 חיבורי WebSocket, כל מופע שרת יודע רק על הלקוחות שלו. שידור התראה בזמן אמת (עדכון סטטוס הזמנה) לכולם דורש Broker אחיד לקנה מידה אופקי. אנו פותרים זאת עם Redis Pub/Sub: הודעה מתפרסמת לערוץ, וכל המנויים הפעילים מקבלים אותה. מנגנון fire-and-forget עם זמן השהיה של <1 ms. ה-Broker אינו מאחסן היסטוריה – מתאים להתראות קצרות, אי-תוקף מטמון, סנכרון מצב. ההתקנה שלנו להתראות בזמן אמת מנצלת Redis Pub/Sub לקנה מידה אופקי. להלן: תצורה, אינטגרציה עם Node.js ו-Laravel, ומלכודות.
כיצד לבחור בין Pub/Sub ל-Redis Streams?
Pub/Sub פותר את בעיית השידור: מפרסם אחד, מנויים מרובים, כולם מקבלים הודעות זהות בו-זמנית. אם אתה צריך אספקה מובטחת, היסטוריה או קבוצות צרכנים – השתמש ב-Redis Streams. Pub/Sub מהיר פי 2–3 מ-Redis Streams לשידור, אך אינו מבטיח אספקה. טבלת סיכום:
| מאפיין | Pub/Sub | Redis Streams |
|---|---|---|
| אספקה מובטחת | לא (fire-and-forget) | כן (קבוצות צרכנים) |
| אחסון היסטוריה | לא | כן (TTL ניתן להגדרה) |
| זמן השהיה | < 1 ms | 1–5 ms |
| תמיכה ב-Sharding | רק Pub/Sub מפוצל (Redis 7+) | כן (דרך קבוצת צרכנים) |
| מקרה שימוש | התראות שידור בזמן אמת | תורים, עיבוד מובטח |
כיצד למנוע אובדן הודעות בזמן ניתוק מנוי?
דרך פשוטה להגן מפני אובדן הודעות היא לשכפל אירועים אחרונים למפתח Redis נפרד עם TTL (לדוגמה, last_event:user:42). כאשר לקוח מתחבר, הוא תחילה מאחזר אירועים שהוחמצו דרך REST API, ואז עובר ל-Pub/Sub. לנתונים קריטיים (עסקאות פיננסיות), השתמש ב-Redis Streams עם קבוצות צרכנים. גישה זו מפחיתה אובדן לאפס וחוסכת עד 30% משאבים בעיבוד חוזר.
תצורת Redis בסיסית
Redis תומך ב-Pub/Sub כברירת מחדל. פרמטרים מומלצים של redis.conf:
# Лимит памяти
maxmemory 512mb
maxmemory-policy allkeys-lru
# Количество баз
databases 16
# Отключить persistence для чистого Pub/Sub
save ""
appendonly no
לסביבת ייצור, השתמש ב-Redis Sentinel או Cluster. Pub/Sub רגיל ב-Cluster מוגבל ל-shard – עם Redis 7+, השתמש ב-Pub/Sub מפוצל (# Лимит памяти maxmemory 512mb maxmemory-policy allkeys-lru # Количество баз databases 16 # Отключить persistence для чистого Pub/Sub save "" appendonly no /SPUBLISH).
אינטגרציה עם Node.js ו-Socket.io
השתמש בספריית ioredis לשתי חיבורים נפרדים (מפרסם ומנוי). דוגמה ב-TypeScript:
import Redis from 'ioredis';
const publisher = new Redis({ host: 'redis', port: 6379 });
const subscriber = new Redis({ host: 'redis', port: 6379 });
subscriber.subscribe('notifications:user:*', (err, count) => {
if (err) throw err;
console.log(`Subscribed to ${count} channels`);
});
subscriber.on('pmessage', (pattern, channel, message) => {
const userId = channel.split(':')[2];
const payload = JSON.parse(message);
broadcastToUser(userId, payload);
});
async function notifyUser(userId: string, event: object) {
const channel = `notifications:user:${userId}`;
const count = await publisher.publish(channel, JSON.stringify(event));
return count;
}ל-WebSocket, השתמש ב-Socket.io עם Redis Adapter:
import { createServer } from 'http';
import { Server } from 'socket.io';
import { createAdapter } from '@socket.io/redis-adapter';
import { createClient } from 'redis';
const httpServer = createServer();
const io = new Server(httpServer);
const pubClient = createClient({ url: 'redis://redis:6379' });
const subClient = pubClient.duplicate();
await Promise.all([pubClient.connect(), subClient.connect()]);
io.adapter(createAdapter(pubClient, subClient));
httpServer.listen(3000);Redis Adapter משתמש ב-Pub/Sub: כאשר SSUBSCRIBE נקרא, הפקודה מתפרסמת לערוץ Redis, וכל מופעי השרת משדרים אותה ללקוחות החדר.
אינטגרציה עם Laravel
ב-Laravel, שליחת הודעת Pub/Sub נראית כך:
use Illuminate\Support\Facades\Redis;
Redis::publish('notifications:user:'.$userId, json_encode([
'type' => 'order.status_changed',
'orderId' => $order->id,
'status' => $order->status,
'timestamp' => now()->toISOString(),
]));
לקבלת הודעות בצד הלקוח, השתמש ב-Laravel Echo Server או Soketi.
תהליך ההתקנה (שלב אחר שלב)
- עיצוב סכמת ערוצים: בדרך כלל השתמש בתבניות
import Redis from 'ioredis'; const publisher = new Redis({ host: 'redis', port: 6379 }); const subscriber = new Redis({ host: 'redis', port: 6379 }); subscriber.subscribe('notifications:user:*', (err, count) => { if (err) throw err; console.log(`Subscribed to ${count} channels`); }); subscriber.on('pmessage', (pattern, channel, message) => { const userId = channel.split(':')[2]; const payload = JSON.parse(message); broadcastToUser(userId, payload); }); async function notifyUser(userId: string, event: object) { const channel = `notifications:user:${userId}`; const count = await publisher.publish(channel, JSON.stringify(event)); return count; }. - הגדר Redis: הגדר maxmemory, השבת AOF ל-Pub/Sub טהור.
- יישם פרסום אירועים בקצה האחורי (Node.js, Laravel, Django).
- חבר שרת WebSocket (Socket.io, Soketi) עם Redis Adapter.
- פתח מנגנון גיבוי לאירועים שהוחמצו (דרך REST).
- בדיקת עומס: ודא ש-
import { createServer } from 'http'; import { Server } from 'socket.io'; import { createAdapter } from '@socket.io/redis-adapter'; import { createClient } from 'redis'; const httpServer = createServer(); const io = new Server(httpServer); const pubClient = createClient({ url: 'redis://redis:6379' }); const subClient = pubClient.duplicate(); await Promise.all([pubClient.connect(), subClient.connect()]); io.adapter(createAdapter(pubClient, subClient)); httpServer.listen(3000);אינו עולה על 5,000.
ניטור
השתמש בפקודות Redis CLI:
redis-cli PUBSUB CHANNELS "*" redis-cli PUBSUB NUMSUB notifications:user:42 redis-cli PUBSUB NUMPAT ב-Prometheus עם Redis Exporter, נטר io.to('room').emit(). גידול מעל 5,000 פעולות בשנייה תחת עומס Pub/Sub מצביע על צורך באופטימיזציה (הקטנת גודל הודעה, הגדלת מספר הערוצים).
רשימת בדיקות לייצור
- ודא ש-Redis פועל במצב Sentinel או Cluster.
- הגדר maxmemory ומדיניות פינוי.
- השתמש בחיבורים נפרדים ל-Pub/Sub (אל תערבב עם פעולות רגילות).
- יישם בקשות גיבוי להודעות שהוחמצו.
- הגבל קצב פרסום ל-5,000 פעולות בשנייה לכל מופע.
מגבלות וחלופות
אובדן הודעות בחיבור מחדש
מנוי שמתנתק זמנית יפספס הודעות שנשלחו בזמן זה. להתראות קריטיות – Redis Streams או אחסון אירועים אחרונים.
אין אישור אספקה
PUBLISH מחזיר את מספר המקלטים אך אינו מבטיח עיבוד. לאספקה של לפחות פעם אחת – השתמש בתור (RabbitMQ, Redis Streams).
עומס CPU עם תבניות רבות
PSUBSCRIBE מתאים כל הודעה לכל התבניות. עם 10,000+ תבניות, זמן ההשהיה גדל ב-30–50%.
מה כלול בעבודה
יישום Pub/Sub יכול להפחית עלויות תשתית WebSocket בעד 40%. עבור אפליקציה טיפוסית עם 10,000 משתמשים בו-זמנית, התקנה זו מפחיתה עלויות WebSocket חודשיות בכ-1,500 דולר. מופע Redis טיפוסי ל-Pub/Sub עולה כ-30–50 דולר לחודש בספקי ענן כמו AWS או DigitalOcean. ההתקנה שלנו להתראות בזמן אמת מנצלת Redis Pub/Sub, Node.js ioredis ו-Socket.io Redis adapter לקנה מידה אופקי חלק. עם ניסיון של למעלה מ-6 שנים ו-15+ פרויקטים מוצלחים, אנו מספקים ייעוץ Redis מקצועי.
- עיצוב סכמת ערוצים ותבניות ללוגיקה עסקית.
- הגדרת Redis (תצורה, Clustering, ניטור).
- אינטגרציה של Pub/Sub עם הקצה האחורי (Node.js, Laravel, Django – לפי המחסנית שלך).
- חיבור שרת WebSocket (Socket.io, Soketi, Laravel Echo).
- פיתוח מניעת אובדן הודעות (בקשות גיבוי).
- תיעוד פריסה ותפעול.
- העברת גישה למאגר ולתשתית.
- תמיכה למשך שבועיים לאחר המסירה.
| שלב | משך |
|---|---|
| ניתוח ועיצוב | 1–2 ימים |
| הגדרת Redis ו-Pub/Sub | יום אחד |
| אינטגרציה עם הקצה האחורי | 1–2 ימים |
| חיבור WebSocket | יום אחד |
| בדיקות וניפוי שגיאות | 1–2 ימים |
| סה"כ | 4 עד 6 ימים |
אנו עובדים עם Redis למעלה מ-6 שנים ויישמנו 15+ פרויקטי Pub/Sub ללקוחות מסחר אלקטרוני ופינטק. אנו משתמשים בתצורות ייצור עם Sentinel ו-Cluster, המבטיחות סובלנות לתקלות. צור קשר כדי להגדיר Redis Pub/Sub לפרויקט שלך – קבל ייעוץ תוך יום אחד. פנה אלינו ליישום וקנה מידה.







