بخش اول: مفاهیم پایه، معماری و Kafka Core
بخش دوم : سایر بازیگران اکوسیستم کافکا
بخش سوم ابزارهای جانبی کافکا : کانکت و رجیستری
بخش چهارم : پردازش جریان در عمل
بخش پنجم :‌ مباحث مدیریتی و تکمیلی

ساختار فیزیکی ذخیره‌سازی: فایل‌های لاگ، سگمنت‌ها و ایندکس‌ها

در این بخش یاد می‌گیریم پیام‌هایی که تولید می‌کنیم دقیقاً کجا و چگونه روی دیسک ذخیره می‌شوند، ساختار فایل‌های لاگ در هر پارتیشن چگونه است و چطور می‌توانیم محتوای آن‌ها را مشاهده کنیم.


⚙️ ۱. آماده‌سازی محیط عملیاتی

برای بررسی نحوه‌ی ذخیره‌سازی داده‌ها، ابتدا از یک اسکریپت پایتون ساده برای تولید داده‌های تست استفاده کردیم. این اسکریپت با کمک کتابخانه‌های kafka-python و faker داده‌های ساختگی کاربران را به‌صورت مداوم در تاپیک users ارسال می‌کند.

# requirements: kafka-python, faker

from datetime import datetime
import json, random, time, uuid
from kafka import KafkaProducer
from faker import Faker

producer = KafkaProducer(
    value_serializer=lambda msg: json.dumps(msg).encode('utf-8'),
    key_serializer=str.encode,
    bootstrap_servers=['localhost:9092']
)

TOPIC_NAME = 'users'
fake = Faker('en_US')

def generate_user():
    return {
        'user_id': str(uuid.uuid4()),
        'name': fake.name(),
        'gender': random.choice(['male', 'female']),
        'email': fake.email(),
        'location': f"{fake.city()}, {fake.country()}",
        'fetched_at': datetime.now().strftime('%Y-%m-%d-%H-%M-%S')
    }

while True:
    user = generate_user()
    producer.send(TOPIC_NAME, value=user, key=user['user_id'])
    producer.flush()
    print(f"Sent → {user['user_id']}")
    time.sleep(0.1)

🔹 نکته: هر پیام دارای key=user_id است، بنابراین Kafka همه‌ی پیام‌های دارای یک کلید را به یک پارتیشن ثابت می‌فرستد.


🧱 ۲. تنظیم سگمنت‌ها در Kafka

در فایل Docker Compose، برای کنترل اندازه‌ی فایل‌های لاگ از تنظیم زیر استفاده کردیم تا هر ۱ مگابایت داده، یک فایل سگمنت جدید بسازد:

KAFKA_LOG_SEGMENT_BYTES: 1048576

همچنین مسیر ذخیره‌سازی داده‌ها را روی یک دایرکتوری لوکال mount کردیم تا بتوانیم به‌سادگی محتوای فایل‌ها را ببینیم:

KAFKA_LOG_DIRS: /var/lib/kafka/data
volumes:
  - ./kafka-data:/var/lib/kafka/data

در نتیجه، تمام داده‌ها در مسیر زیر روی سیستم شما ذخیره می‌شوند (در پوشه‌ای که فایل داکر کامپوز قرار گرفته است):

./kafka-data/

📁 ۳. ساختار دایرکتوری‌ها در Kafka

وقتی تاپیک users با ۴ پارتیشن ساخته شد، Kafka به‌صورت خودکار چهار پوشه جدا برای هر پارتیشن ایجاد کرد:

kafka-data/
├── users-0/
├── users-1/
├── users-2/
└── users-3/

هر پوشه، مربوط به یک پارتیشن است و شامل چند فایل کلیدی می‌شود:

فایلتوضیح
.logداده‌های واقعی (پیام‌ها)
.indexنگاشت آفست منطقی به موقعیت بایت در فایل .log
.timeindexنگاشت زمان تولید پیام به آفست برای جست‌وجوی زمانی
leader-epoch-checkpointذخیره تاریخچه تغییر لیدر برای هماهنگی کنترلرها

نمونه:

users-0/
├── ۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰.log
├── ۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰.index
├── ۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰.timeindex
└── leader-epoch-checkpoint

📦 ۴. سگمنت‌ها – بلوک‌های اصلی ذخیره‌سازی

هر فایل .log در واقع یک سگمنت از لاگ پارتیشن است.
Kafka پیام‌ها را فقط به انتهای لاگ اضافه می‌کند (append-only) و هرگز رکوردی را بازنویسی نمی‌کند.

وقتی اندازه‌ی یک سگمنت از مقدار تعیین‌شده (log.segment.bytes) فراتر رفت، Kafka فایل جدیدی می‌سازد که نام آن بر اساس base offset رکورد اول در آن سگمنت است:

users-0/
├── ۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰.log   → offsets [0 … ۹۹۹]
├── ۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۱۰۰۰.log   → offsets [1000 … ۱۹۹۹]
├── ۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۲۰۰۰.log   → offsets [2000 … ۲۹۹۹]

به این ترتیب Kafka داده‌ها را به‌صورت ترتیبی، ماژولار و بسیار سریع روی دیسک نگه می‌دارد.


🔍 ۵. بررسی فایل‌ها در عمل

برای مشاهده‌ی فایل‌ها کافی است از سیستم‌عامل میزبان، محتوای دایرکتوری‌ها را بررسی کنید:

ls -lh ./kafka-data/users-0

و خواهید دید:

۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰.log
۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰.index
۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰.timeindex
leader-epoch-checkpoint

اگر مدتی پیام تولید کنید، فایل‌های .log بیشتری ظاهر می‌شوند (هر ۱ مگابایت یک فایل جدید).


🧰 ۶. مشاهده محتوای سگمنت‌ها

برای مشاهده‌ی جزئیات داخل یک فایل .log می‌توانید از ابزار داخلی Kafka استفاده کنید:

docker exec -it kafka-1 \
  kafka-run-class.sh kafka.tools.DumpLogSegments \
  --files /var/lib/kafka/data/users-0/00000000000000000000.log \
  --print-data-log

این دستور محتوای فایل را همراه با اطلاعات زیر نمایش می‌دهد:

  • offset (آفست هر پیام)
  • CreateTime (زمان تولید)
  • key/value size
  • CRC و وضعیت صحت داده

نمونه خروجی:

offset: 0 position: 0 CreateTime: 1760242021480 keysize: 36 valuesize: 219
key: 2a74853c-319a-4fb0-8da2-4250cb0f71d9
payload: {"user_id": "...", "name": "...", ...}

به این ترتیب می‌توانید دقیقاً ببینید که Kafka پیام‌ها را چگونه در فایل‌ها ذخیره کرده است.


⚠️ نکته مهم پیش از اجرای دستورات Kafka

برای اجرای ابزارها و دستورات خط فرمان Kafka (مثل kafka-topics.sh, kafka-console-producer.sh, kafka-run-class.sh و غیره)، لازم است ابتدا وارد نود Kafka در محیط Docker شوید و سپس به پوشه‌ی bin بروید.

اگر از Docker Desktop یا خط فرمان استفاده می‌کنید، مراحل زیر را انجام دهید:

# مشاهده لیست کانتینرها
docker ps

# ورود به کانتینر Kafka (مثلاً kafka-node یا kafka-1)
docker exec -it kafka-node /bin/bash

# رفتن به پوشه ابزارها
cd /opt/kafka/bin

حالا تمام دستورات Kafka را باید با پیشوند ./ اجرا کنید، مثلاً:

./kafka-topics.sh --list --bootstrap-server localhost:9092
./kafka-console-consumer.sh --topic users --from-beginning --bootstrap-server localhost:9092

🔹 یادتان باشد:
اگر ./ را در ابتدای دستور نیاورید، سیستم آن فایل اجرایی را پیدا نمی‌کند و با خطای
command not found
روبه‌رو می‌شوید.


📊 ۷. جمع‌بندی بخش

مفهومتوضیح
Partitionفایل لاگ ترتیبی برای ذخیره پیام‌ها
Segmentبخش فیزیکی از لاگ که داده‌ها در آن نوشته می‌شوند
Index / Timeindexنگاشت آفست‌ها و زمان‌ها برای دسترسی سریع
Retention & Rotationتعیین طول عمر و اندازه سگمنت‌ها
DumpLogSegmentsابزار بررسی درونی ساختار فایل‌های لاگ
Mount Volumeروشی ساده برای مشاهده فایل‌ها از میزبان

فروشگاه
جستجو
دوره ها

لطفا کلمات کلیدی را وارد کنید