Kafka ו-Event Streaming בקנה מידה: מעבר לתור הודעות רגיל
מאת צוות מדיה דיל · 02.09.2026 · טכנולוגיה · 6 דק׳
Topics, Partitions ו-Consumer Groups, Exactly-Once Semantics במדויק, Schema Registry, והקשר בין Kafka ל-Outbox Pattern ולארכיטקטורה מונעת אירועים.
תור הודעות רגיל (כמו RabbitMQ) מוחק הודעה אחרי שהיא נצרכה — מצוין למשימות עבודה, גרוע כשצריך שכמה צרכנים שונים יקראו את אותו סטרים אירועים, כל אחד בקצב שלו, ואולי גם יחזרו אחורה בזמן. Kafka נבנה סביב מודל שונה מהיסוד: לוג מתמשך ומסודר של אירועים, לא תור שמתרוקן.
Topic, Partition, Offset: המודל הבסיסי
Kafka מארגן נתונים ב-Topics, וכל Topic מחולק ל-Partitions — לוגים עצמאיים שכל אחד שומר סדר פנימי מוחלט משלו. כל הודעה מקבלת Offset עולה בתוך ה-Partition שלה, וצרכנים עוקבים אחרי המיקום שלהם בעצמם — Kafka לא מוחק הודעות אחרי קריאה, אלא שומר אותן לפי מדיניות שמירה (Retention) שמוגדרת בזמן או בנפח, לא לפי מי כבר קרא.
Consumer Groups: איך מפזרים עומס קריאה בלי לאבד סדר
כמה Consumers שמשתייכים לאותה Consumer Group מתחלקים ביניהם ב-Partitions של Topic — כל Partition נצרך על ידי Consumer יחיד בקבוצה בכל רגע, כך שאין כפילות בתוך הקבוצה, אבל יש מקביליות בין Partitions שונים. שתי קבוצות שונות יכולות לקרוא את אותו Topic במקביל לגמרי, כל אחת בקצב ובשלב שלה — זה ההבדל המהותי מתור רגיל שבו הודעה נעלמת אחרי שהיא נצרכת פעם אחת.
Partition Key: מי קובע מה הולך לאיפה
כשמפיקים הודעה עם מפתח (למשל user_id), Kafka שולח את כל ההודעות עם אותו מפתח לאותו Partition תמיד — זו הדרך היחידה להבטיח סדר יחסי בין הודעות של אותה ישות. הודעות בלי מפתח מתפזרות (Round-Robin) בין Partitions, מה שנותן איזון עומס טוב יותר אבל מוותר על ערבות סדר בין הודעות שונות.
Replication ו-ISR: איך Kafka שורד נפילת Broker
כל Partition משוכפל למספר Brokers (Replication Factor), כאשר אחד מהם Leader וכל השאר Followers. In-Sync Replicas (ISR) היא קבוצת ה-Replicas שבאמת עדכניים מספיק כדי להיחשב "בטוחים" — כתיבה עם acks=all ממתינה לאישור מכל ה-ISR, לא רק מה-Leader, כדי להבטיח שהודעה לא תיאבד גם אם ה-Leader נופל מיד אחרי הכתיבה.
Exactly-Once: יומרה גדולה עם תנאים מדויקים
"Exactly-Once Semantics" ב-Kafka לא אומר שההודעה נשלחת פעם אחת פיזית — היא אומרת שגם אם המפיק שולח שוב עקב Retry (למשל אחרי Timeout ברשת), Kafka מזהה את הכפילות ומונע רישום כפול, בעזרת Idempotent Producer עם מזהה ורצף פנימיים. זה עובד מלא רק בתוך Kafka עצמו (Producer עד Consumer בתוך Kafka); ברגע שהאירוע יוצא לצריכה בצד עסקי חיצוני, עדיין נדרשת התנהגות Idempotent בצד הצורך.
Schema Registry: המשמעת שמונעת אנדרלמוסיה
כשעשרות שירותים מפיקים וצורכים מאותם Topics, שינוי לא מתואם במבנה ההודעה שובר צרכנים בשקט. Schema Registry (בדרך כלל עם Avro או Protobuf) אוכף תאימות גרסאות — צרכן ישן חייב להצליח לקרוא הודעה חדשה, ולהפך, לפי מדיניות תאימות שנבדקת בזמן רישום סכימה, לפני שהיא בכלל מגיעה לפרודקשן.
Kafka כעמוד השדרה של Event-Driven Architecture
Kafka הוא הבחירה הנפוצה ביותר למימוש ארכיטקטורה מונעת אירועים בקנה מידה גדול, בדיוק כי הוא שומר את האירועים כלוג בר-חזרה במקום תור שמתרוקן — שירות חדש שמצטרף מאוחר יכול לקרוא היסטוריה שלמה, לא רק אירועים מרגע ההצטרפות. השילוב עם Outbox Pattern נפוץ במיוחד: כתיבה למסד נתונים ופרסום ל-Kafka חייבים להיות אטומיים, וה-Outbox מבטיח את זה בלי טרנזקציה מבוזרת אמיתית.
Rebalancing: כשהוספת Consumer גורמת להשהיה זמנית
כשConsumer מצטרף או עוזב קבוצה, Kafka מפעיל Rebalance — הקצאה מחדש של Partitions בין כל ה-Consumers הפעילים, שבמהלכה הצריכה נעצרת זמנית. Rebalancing תכוף מדי (למשל עקב Consumers שנופלים ועולים בלולאה) הופך לצוואר בקבוק תפעולי אמיתי — כיוונון נכון של Session Timeout וזיהוי מוקדם של Consumers איטיים מונע את התופעה הזו.
בונים תשתית Event Streaming בקנה מידה ורוצים ליווי בעיצוב Partitions וקונפיגורציה נכונה? דברו איתנו בוואטסאפ.
תגיות: Kafka · Event Streaming · Consumer Groups · Distributed Systems