در حالت فشردهسازی و پاکسازی تاپیکها (cleanup.policy=compact)، Kafka نیاز دارد که حذف رکوردها را به شیوهای ویژه مدیریت کند.
🔹 اگر رکوردهایی که کلاً حذف شدهاند را بدون مکانیزم خاص پاک کنیم، کلاینتها ممکن است متوجه حذف آنها نشوند. مثلا یک مصرف کننده متوقف شده است و بعد از چند ساعت، مجددا اجرا میشود و در این میان ممکن است عملیات فشرده سازی تمام رکوردهای مرتبط با آن رکورد حذف شده را پاک کرده باشد و این مصرف کننده همان داده های قبلی خود را نگه دارد و به روز نشود. بنابراین ما به مکانیزمی به نام Tombstone نیاز داریم.
Tombstone یک پیام ویژه با کلید مشخص و مقدار null است.
این پیام به Kafka میگوید:
“این کلید حذف شده است – تمام رکوردهای قدیمیتر با همان کلید را در هنگام فشردهسازی حذف کن.”
مثال:
# تولید رکورد معمولی
producer.send("users", key=b"user123", value=b"Alice")
# حذف رکورد با tombstone
producer.send("users", key=b"user123", value=None)
حالا لاگ به شکل زیر است:
| Offset | Key | Value |
|---|---|---|
| ۰ | user123 | Alice |
| ۱ | user123 | null 🔥 |
null بلافاصله حذف نمیشود.log.cleaner.delete.retention.ms)تنظیمات:
log.cleaner.delete.retention.ms
پیشفرض: 86400000 ms = 24 ساعت
Tombstone تا ۲۴ ساعت نگه داشته میشود تا همه مصرفکنندهها زمان کافی برای پردازش حذف را داشته باشند.
رکورد معمولی:
producer.send("users", key=b"user123", value=b"Alice")
| Offset | Key | Value |
|---|---|---|
| ۰ | user123 | Alice |
حذف رکورد (Tombstone):
producer.send("users", key=b"user123", value=None)
| Offset | Key | Value |
|---|---|---|
| ۰ | user123 | Alice |
| ۱ | user123 | null 🔥 |
✅ Kafka tombstone را خودکار تولید نمیکند؛ تولیدکننده مسئول ارسال آن است.
| زمان | عملیات | محتوای لاگ Kafka |
|---|---|---|
| t=0 | (user1, Alice) | user1 -> Alice |
| t=1 | (user2, Bob) | user1 -> Alice, user2 -> Bob |
| t=2 | (user1, null) | user1 -> Alice, user2 -> Bob, user1 -> null |
پس از compaction:
| Key | Value |
|---|---|
| user1 | null (tombstone) |
| user2 | Bob |
log.cleaner.delete.retention.ms نگه داشته میشود| عملیات | چیزی که تولیدکننده میفرستد | رفتار Kafka |
|---|---|---|
| ایجاد / آپدیت | Key + Value | اضافه شدن رکورد به لاگ |
| حذف | Key + null | اضافه شدن tombstone و حذف نسخههای قدیمی هنگام compaction |
# ایجاد تاپیک compacted
kafka-topics.sh --create \
--bootstrap-server localhost:9092 \
--topic users-demo \
--config cleanup.policy=compact
# تولید رکوردها
kafka-console-producer.sh --broker-list localhost:9092 --topic users-demo \
--property parse.key=true --property key.separator=:
user1:Alice
user2:Bob
user1:null
مشاهده با consumer:
kafka-console-consumer.sh --bootstrap-server localhost:9092 \
--topic users-demo --from-beginning --property print.key=true --property print.value=true
خروجی اولیه:
user1 Alice
user2 Bob
user1 null
پس از compaction:
user2 Bob
| مفهوم | چه کسی تولید میکند | هدف |
|---|---|---|
| Tombstone (مقدار null) | Producer | نشاندهنده حذف یک کلید |
| Compaction | Kafka | حذف رکوردهای قدیمی و نگهداری آخرین یا tombstone |
log.cleaner.delete.retention.ms | تنظیمات Kafka | مدت زمان نگهداری tombstone قبل از حذف نهایی |