در نسخههای جدید Apache Kafka (از نسخه ۳ به بعد)، دیگر از ZooKeeper برای مدیریت و هماهنگی نودهای کلاستر استفاده نمیشود.
علت این تغییر، پیچیدگی، وابستگی زیاد و مشکلات هماهنگی بین Kafka و ZooKeeper بود.
به جای آن، Kafka حالا دارای یک لایهی داخلی هماهنگی به نام KRaft (Kafka Raft Metadata Mode) است که خودش تمام کارهای مربوط به مدیریت متادیتا، هماهنگی نودها و انتخاب رهبر را انجام میدهد.
به عبارت سادهتر:
KRaft همان کاری را میکند که قبلاً ZooKeeper انجام میداد، اما حالا بهصورت درونساخت خود Kafka و بسیار بهینهتر.
در معماری جدید KRaft، هر نود Kafka میتواند یکی از این سه نقش را داشته باشد:
فرض کن چند نود (سرور) داریم و باید یکی از آنها نقش رهبر را بر عهده گیرد. اگر دو سرور همزمان فکر کنند رهبر هستند، دادهها ناهماهنگ میشود و سیستم دچار خطا خواهد شد.
برای جلوگیری از این مشکل، ما نیاز به یک الگوریتم اجماع (Consensus Algorithm) داریم تا همه نودها بتوانند با هم توافق کنند که:
Kafka برای این کار از الگوریتم Raft استفاده میکند — و در واقع نام KRaft از ترکیب Kafka + Raft گرفته شده است.
الگوریتم Raft بهصورت خلاصه تضمین میکند که همهی نودها در مورد وضعیت متادیتا و رهبر، به توافق برسند.
در هر لحظه:
این فرآیند بسیار سریع است و باعث میشود کلاستر حتی در زمان خرابی یک سرور هم پایدار بماند.
بیایید ارتباطها را مرحلهبهمرحله مرور کنیم 👇
در کلاستر، کنترلرها با هم یک Quorum تشکیل میدهند — یعنی گروهی از نودها که با هم در مورد متادیتا تصمیم میگیرند.
نکته مهم: در KRaft برخلاف تصور عمومی، رهبر اطلاعات را “push” نمیکند، بلکه نودهای دیگر اطلاعات را “pull” میکنند.
هر بروکر فقط با رهبر کنترلر ارتباط دارد. این ارتباط شامل چند بخش است:
| مورد | توضیح |
|---|---|
| 🔹 ساختار Pull-driven | پیروها دادهها و متادیتا را از رهبر Pull میکنند |
| 🔹 استقلال از ZooKeeper | تمام مدیریت متادیتا درون Kafka انجام میشود |
| 🔹 Quorum Controller | برای اطمینان از صحت و پایداری تصمیمات |
| 🔹 Heartbeat | کنترل سلامت و وضعیت نودها |
| 🔹 Metadata Log | تمام اطلاعات مدیریتی بهصورت لاگ مشابه دادهها ذخیره میشود |
فرض کنید ما سه سرور داریم که هر سه نقش Controller را در یک کلاستر Kafka ایفا میکنند:
Controller-1 Controller-2 Controller-3
همهی این سرورها اطلاعات متادیتا (مثل لیست تاپیکها و پارتیشنها) را در خود نگه میدارند، اما فقط یکی از آنها باید رهبر (Leader) باشد — چون وجود چند رهبر باعث میشود دادهها ناسازگار شوند.
اینجاست که الگوریتم Raft وارد عمل میشود.
وقتی کلاستر برای اولین بار بالا میآید، همهی کنترلرها در حالت Follower (دنبالکننده) هستند.
هیچکدام نمیداند رهبر کیست، و منتظرند از جایی پیامی دریافت کنند که بگوید “رهبر من هستم”.
اما چون هنوز هیچ رهبری وجود ندارد، بعد از مدتزمانی که به آن Election Timeout میگویند (مثلاً ۳۰۰ تا ۵۰۰ میلیثانیه)، یکی از آنها تصمیم میگیرد خودش کاندید (Candidate) شود.
فرض کنیم Controller-2 زودتر از بقیه تایماوتش تمام شده است.
او تصمیم میگیرد برای رهبر شدن کاندید شود.
در این حالت:
هر کدام از کنترلرهای دیگر (۱ و ۳) بررسی میکنند:
اگر پاسخ مثبت باشد و شرایط درست باشد، آنها به Controller-2 رأی میدهند.
✅ در الگوریتم Raft، برای برنده شدن، کاندید باید اکثریت آرا (majority) را بهدست آورد.
مثلاً در ۳ نود، باید حداقل ۲ رأی داشته باشد.
وقتی Controller-2 دو رأی (از خودش و یکی از بقیه) میگیرد، اعلام میکند:
«من رهبر جدید هستم.»
از این لحظه به بعد:
رهبر (Controller-2) حالا لاگ متادیتا را مدیریت میکند.
وقتی یک تغییر رخ میدهد — مثلاً ساخت یک Topic جدید — ابتدا رهبر آن را در لاگ خود مینویسد، سپس بقیه کنترلرها آن تغییر را از او pull میکنند تا لاگشان هم همگام شود.
وقتی اکثریت کنترلرها تأیید کردند که این تغییر را ثبت کردهاند، رهبر میگوید:
«تغییر قطعی (Committed) شد.»
اگر Controller-2 (رهبر فعلی) از کار بیفتد یا پاسخ ندهد:
به این ترتیب، سیستم همیشه یک رهبر فعال دارد و هیچوقت بیرهبر نمیماند.
| مرحله | وضعیت |
|---|---|
| ۱️⃣ همه Follower هستند | در انتظار پیام رهبر |
| ۲️⃣ یک نفر Candidate میشود | درخواست رأی میدهد |
| ۳️⃣ اکثریت رأی میدهند | رهبر جدید انتخاب میشود |
| ۴️⃣ رهبر با heartbeat بقیه را هماهنگ نگه میدارد | پایداری برقرار میشود |
| ۵️⃣ اگر رهبر از کار افتاد | انتخابات جدید برگزار میشود |
تصور کن سه نفر در یک گروه کاری هستند:
هرکدام منتظرند یکی مسئول شود. اگر کسی داوطلب شد و بقیه هم قبول کردند، او مدیر میشود.
مدیر مرتب به بقیه پیام میدهد (heartbeat) که “من هنوز اینجام و مدیریت را بر عهده دارم”.
اگر مدتی از او خبری نشود، دوباره رأیگیری میکنند تا مدیر جدید انتخاب شود.
Kafka هم دقیقاً با همین منطق کنترلر رهبر خود را انتخاب میکند.
در معماری KRaft:
اگر بخواهیم این ساختار را با مثالی انسانی توضیح دهیم:
کنترلر رهبر مثل مدیر اصلی شرکت است، کنترلرهای پیرو مثل معاونان او هستند که اطلاعات را مرتب از مدیر میگیرند، و بروکرها مثل شعبههای شرکتاند که مستقیم با مشتریان (Producer و Consumer) در ارتباطاند.