کافکا و رؤیای پارتیشنبندی کشسان
خلاصهٔ کاملتر
تو این مقاله اومده که چند تا درد همیشگی کافکا از یک ریشه میان: پارتیشنبندی ثابت. عوض کردن تعداد پارتیشنها تضمین ترتیب رو خراب میکنه، پس یا زیادی پارتیشن میسازی و کارایی batch رو از دست میدی، یا کم میسازی و به سقف موازیسازی میخوری. کلیدهای داغ بار رو نامتوازن میکنن و چون تعداد پارتیشن هم مرز تولیدکنندهست هم مرز مصرفکننده، این دو تا به هم چسبیدن. نویسنده میگه توی ۲۰۲۶ این محدودیت عجیبه، چون خیلی از دیتابیسها خودشون بر اساس بار پارتیشن رو تنظیم میکنن.
پیشنهاد اینه که تضمین از «ترتیب داخل پارتیشن» به «ترتیب داخل هر کلید» تغییر کنه. اونوقت بروکرها میتونن با اجماع (کافکا از Raft استفاده میکنه) محدودهٔ hash کلیدها رو بین خودشون جابهجا کنن و بار رو حتی در حد تککلید پخش کنن. پارتیشنهای split و mergeشده یک رابطهٔ پدر و فرزند میسازن و مصرفکننده باید اول رکوردهای پدر رو تموم کنه تا ترتیب نشکنه.
سختترین بخش، state محلی مصرفکنندهست: کلیدها که جابهجا بشن، حالت مربوط به اونها هم باید بره روی نود جدید. Kafka Streams این مشکل رو با یک changelog فشرده و standby replica حل کرده، ولی اگه چیدمان مدام عوض شه، نود جدید باید تاریخچهٔ چند پارتیشن قبلی رو بخونه و از لای کلی دادهٔ بیربط سهم خودش رو دربیاره.
چیز دیگهای که زیر فشاره، batching سرتاسری کافکاست. کلاینت خودش رکوردها رو به پارتیشن نسبت میده و بروکر اصلاً داخل batch رو باز نمیکنه؛ همین باعث فشردهسازی سرتاسری و zero-copy با فراخوانی sendfile میشه، یعنی داده مستقیم از دیسک به بافر شبکه میره. به گفتهٔ نویسنده این دو تا ذاتاً ناسازگار نیستن، ولی هر بار تغییر چیدمان، تولیدکننده باید مکث کنه و دادهٔ در حال پرواز رو دوباره پارتیشن کنه.
برای جدا کردن تولیدکننده و مصرفکننده هم یک لایهٔ سرویسدهی وسط پیشنهاد میشه که لاگ اصلی رو میخونه و به «پارتیشن مجازی» تقسیمش میکنه. نمونهٔ عملی این ایدهها هست: Kinesis بر اساس بار split و merge میکنه، Flink هم state رو توی key group نگه میداره (پیشفرض ۱۲۸ تا)، و لینکدین با Northguard رفته سراغ شاردینگ بازهای که واحد replicationش segmentه نه پارتیشن. Pulsar هم با scalable topics همین مسیر رو میره.
نکات کلیدی:
- تضمین پیشنهادی: ترتیب کامل به ازای هر کلید، بهجای ترتیب به ازای هر پارتیشن
- پارتیشنهای split و mergeشده یک DAG پدر و فرزند میسازن و پدر باید اول پردازش شه
- حذف کامل پارتیشن یعنی نگهداشتن یک offset برای هر کلید، گاهی میلیاردها مقدار
- Flink پیشفرض ۱۲۸ key group داره و state رو مستقل از پارتیشن منبع نگه میداره
- Northguard لینکدین واحد replication رو segment گذاشته، نه پارتیشن
- scalable topics در Pulsar قراره اواخر ۲۰۲۶ منتشر شه




