مسئله: خود Kafka را طراحی کن — سیستمی که روزانه تریلیونها پیام را با دوام، ترتیب و تأخیر میلیثانیهای جابهجا میکند. حالا که درس ۴۲ مصرفش را میدانی، وقت ساختنش است.
۱-۲) نیازمندی و تخمین
- FR: producer بنویسد، consumer با ترتیب بخواند، چند مصرفکننده مستقل از یک داده (fan-out)، نگهداشت روزها.
- NFR: throughput میلیون پیام/ثانیه، دوام در برابر مرگ دیسک/گره، تأخیر انتهابهانتها <100ms.
- تخمین: 1M msg/s × 1KB ≈ 1GB/s نوشتن و چند برابرش خواندن — دیسک sequential تنها راه زندهماندن است.
۳) طراحی — همهچیز log است
بینش مرکزی: پیام را مثل صف «بخوان و حذف کن» نگهدار، مثل log فقط-الحاقی (درس ۱۲، همان WAL!) بنویس و به هر مصرفکننده اجازه بده با offset خودش بخواند. نوشتن = الحاق انتهای فایل (سریعترین I/O دیسک)؛ خواندن = خواندن ترتیبی. حذف نه بر اساس مصرف که بر اساس زمان/حجم (retention) — همین یک تصمیم، fan-out نامحدود و replay را مجانی میکند.
- پارتیشن واحد مقیاس است: هر پارتیشن یک log مستقل روی یک گره؛ ترتیب فقط درون پارتیشن تضمان است — کلید پیام تعیینکننده پارتیشن (هش) پس کلید را بر اساس نیاز ترتیب انتخاب کن (user_id ،order_id).
- دوام: هر پارتیشن r نسخه روی گرههای مختلف؛ leader مینویسد، follower ها دنبال میکنند؛ acks=all یعنی فقط وقتی ack که ISR (نسخههای همگام) نوشته باشند — درس ۱۴ در عمل.
- Consumer group: پارتیشنها بین اعضای گروه تقسیم میشوند؛ offset مشترک در Kafka خودش ذخیره است — افزودن مصرفکننده = مقیاس خواندن، و rebalance هزینهاش است (درس ۴۲).
- صفحهکش سیستمعامل: Kafka خودش کش نمیکند؛ page cache لینوکس + zero-copy (sendfile) خواندن را تقریباً رایگان میکند.
۴) عمق و گلوگاه
- چرا نه RabbitMQ برای این حجم؟ مدل «تحویل هوشمند بروکر» (ردیابی هر پیام/مصرفکننده) در مقیاس تریلیونی نمیچرخد؛ Kafka بروکر را احمق و مصرفکننده را هوشمند کرد — دقیقاً معکوس.
- ترتیب سراسری بین پارتیشنها نداری — اگر لازم است (نادر)، یا یک پارتیشن (سقف throughput یک گره) یا ترتیبدهی در لایه کاربرد با sequence number.
- KRaft جای ZooKeeper: متادیتای کلاستر خودش یک log داخلی با Raft (درس ۹) است — یک وابستگی کمتر، failover سریعتر.
به زبان ساده
Kafka خودش یک فایل بزرگ فقط-الحاقی است: نوشتن همیشه به ته فایل (سریعترین کار دیسک)، خواندن با offset هر مصرفکننده، و مقیاس با تقسیم به پارتیشن.
مثال واقعی
مثل نوار کاغذی تلگراف قدیم: خبرها پشت سر هم به ته نوار اضافه میشوند؛ هر خواننده قلمی روی شمارهای که رسیده نگه میدارد و هر وقت خواست ادامه میدهد.